diff --git a/src/components/Hoverable/HoverablePropTypes.js b/src/components/Hoverable/HoverablePropTypes.js index c6adb8616fef..2d2842be19c5 100644 --- a/src/components/Hoverable/HoverablePropTypes.js +++ b/src/components/Hoverable/HoverablePropTypes.js @@ -2,7 +2,10 @@ import PropTypes from 'prop-types'; const propTypes = { // Children to wrap with Hoverable. - children: PropTypes.node.isRequired, + children: PropTypes.oneOfType([ + PropTypes.node, + PropTypes.func, + ]).isRequired, // Function that executes when the mouse moves over the children. onHoverIn: PropTypes.func, diff --git a/src/components/OptionsList.js b/src/components/OptionsList.js index 0067ab108313..efdfd83bbfcf 100644 --- a/src/components/OptionsList.js +++ b/src/components/OptionsList.js @@ -7,6 +7,10 @@ import OptionRow from '../pages/home/sidebar/OptionRow'; import optionPropTypes from './optionPropTypes'; const propTypes = { + // Style for hovered state + // eslint-disable-next-line react/forbid-prop-types + optionHoveredStyle: PropTypes.object, + // Extra styles for the section list container contentContainerStyles: PropTypes.arrayOf(PropTypes.object), @@ -63,6 +67,7 @@ const propTypes = { }; const defaultProps = { + optionHoveredStyle: undefined, contentContainerStyles: [], sections: [], focusedIndex: 0, @@ -145,6 +150,7 @@ class OptionsList extends Component { return ( this.list = el} + optionHoveredStyle={styles.hoveredComponentBG} onSelectRow={this.props.onSelectRow} sections={this.props.sections} focusedIndex={this.state.focusedIndex} diff --git a/src/pages/home/sidebar/OptionRow.js b/src/pages/home/sidebar/OptionRow.js index d971c2d1fb58..a8000b471f24 100644 --- a/src/pages/home/sidebar/OptionRow.js +++ b/src/pages/home/sidebar/OptionRow.js @@ -13,8 +13,13 @@ import Icon from '../../../components/Icon'; import {Pencil, PinCircle, Checkmark} from '../../../components/Icon/Expensicons'; import MultipleAvatars from '../../../components/MultipleAvatars'; import themeColors from '../../../styles/themes/default'; +import Hoverable from '../../../components/Hoverable'; const propTypes = { + // Style for hovered state + // eslint-disable-next-line react/forbid-prop-types + hoverStyle: PropTypes.object, + // Option to allow the user to choose from can be type 'report' or 'user' option: optionPropTypes.isRequired, @@ -38,6 +43,7 @@ const propTypes = { }; const defaultProps = { + hoverStyle: styles.sidebarLinkHover, hideAdditionalOptionStates: false, showSelectedState: false, isSelected: false, @@ -45,6 +51,7 @@ const defaultProps = { }; const OptionRow = ({ + hoverStyle, option, optionIsFocused, onSelectRow, @@ -59,77 +66,82 @@ const OptionRow = ({ const textUnreadStyle = (option.isUnread || forceTextUnreadStyle) ? [textStyle, styles.sidebarLinkTextUnread] : [textStyle]; return ( - - onSelectRow(option)} - activeOpacity={0.8} - style={StyleSheet.flatten([ - styles.chatLinkRowPressable, - styles.flexGrow1, - styles.optionItemAvatarNameWrapper, - ])} - > + + {hovered => ( - { - !_.isEmpty(option.icons) - && ( - - ) - } - - - {option.text} - - {option.alternateText ? ( - - {option.alternateText} - - ) : null} - - {showSelectedState && ( - - {isSelected && ( - + onSelectRow(option)} + activeOpacity={0.8} + style={StyleSheet.flatten([ + styles.chatLinkRowPressable, + styles.flexGrow1, + styles.optionItemAvatarNameWrapper, + ])} + > + + { + !_.isEmpty(option.icons) + && ( + + ) + } + + + {option.text} + + {option.alternateText ? ( + + {option.alternateText} + + ) : null} + + {showSelectedState && ( + + {isSelected && ( + + )} + )} - )} - - - {!hideAdditionalOptionStates && ( - - {option.hasDraftComment && ( - - - - )} - {option.isPinned && ( - - + + {!hideAdditionalOptionStates && ( + + {option.hasDraftComment && ( + + + + )} + {option.isPinned && ( + + + + )} )} )} - + ); }; diff --git a/src/styles/styles.js b/src/styles/styles.js index 643432de07b4..232aaea2c3ee 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -157,6 +157,10 @@ const styles = { color: themeColors.textReversed, }, + hoveredComponentBG: { + backgroundColor: themeColors.componentBGHover, + }, + touchableButtonImage: { alignItems: 'center', height: variables.componentSizeNormal, @@ -457,6 +461,10 @@ const styles = { overflow: 'hidden', }, + sidebarLinkHover: { + backgroundColor: themeColors.sidebarHover, + }, + sidebarLinkActive: { backgroundColor: themeColors.border, textDecorationLine: 'none', diff --git a/src/styles/themes/default.js b/src/styles/themes/default.js index 74067a3fe8c5..2f57fb5b72cc 100644 --- a/src/styles/themes/default.js +++ b/src/styles/themes/default.js @@ -4,9 +4,11 @@ export default { shadow: colors.black, link: colors.blue, componentBG: colors.white, + componentBGHover: colors.gray1, appBG: colors.white, heading: colors.charcoal, sidebar: colors.gray1, + sidebarHover: colors.white, border: colors.gray2, borderFocus: colors.blue, icon: colors.gray3,