diff --git a/.storybook/preview.js b/.storybook/preview.js index 835171bd408d..9ddb43d6f3e7 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -23,7 +23,15 @@ const decorators = [ ), ]; +const parameters = { + controls: { + matchers: { + color: /(background|color)$/i, + }, + }, +}; + export { - // eslint-disable-next-line import/prefer-default-export decorators, + parameters, }; diff --git a/src/components/IOUConfirmationList.js b/src/components/IOUConfirmationList.js index c9e8d8ce435d..a02a75595805 100755 --- a/src/components/IOUConfirmationList.js +++ b/src/components/IOUConfirmationList.js @@ -364,7 +364,7 @@ class IOUConfirmationList extends Component { canSelectMultipleOptions={this.props.hasMultipleParticipants} selectedOptions={this.getSelectedOptions()} onSelectRow={toggleOption} - disableRowInteractivity={!this.props.isGroupSplit} + isDisabled={!this.props.isGroupSplit} optionHoveredStyle={hoverStyle} /> diff --git a/src/pages/home/sidebar/OptionRow.js b/src/components/OptionRow.js similarity index 91% rename from src/pages/home/sidebar/OptionRow.js rename to src/components/OptionRow.js index eaa6b7c1d9fe..9610d5a9200b 100644 --- a/src/pages/home/sidebar/OptionRow.js +++ b/src/components/OptionRow.js @@ -8,21 +8,21 @@ import { StyleSheet, } from 'react-native'; import Str from 'expensify-common/lib/str'; -import styles from '../../../styles/styles'; -import * as StyleUtils from '../../../styles/StyleUtils'; -import {optionPropTypes} from './optionPropTypes'; -import Icon from '../../../components/Icon'; -import * as Expensicons from '../../../components/Icon/Expensicons'; -import MultipleAvatars from '../../../components/MultipleAvatars'; -import Hoverable from '../../../components/Hoverable'; -import DisplayNames from '../../../components/DisplayNames'; -import IOUBadge from '../../../components/IOUBadge'; -import colors from '../../../styles/colors'; -import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize'; -import Text from '../../../components/Text'; -import SelectCircle from '../../../components/SelectCircle'; -import SubscriptAvatar from '../../../components/SubscriptAvatar'; -import CONST from '../../../CONST'; +import styles from '../styles/styles'; +import * as StyleUtils from '../styles/StyleUtils'; +import optionPropTypes from './optionPropTypes'; +import Icon from './Icon'; +import * as Expensicons from './Icon/Expensicons'; +import MultipleAvatars from './MultipleAvatars'; +import Hoverable from './Hoverable'; +import DisplayNames from './DisplayNames'; +import IOUBadge from './IOUBadge'; +import colors from '../styles/colors'; +import withLocalize, {withLocalizePropTypes} from './withLocalize'; +import Text from './Text'; +import SelectCircle from './SelectCircle'; +import SubscriptAvatar from './SubscriptAvatar'; +import CONST from '../CONST'; const propTypes = { /** Background Color of the Option Row */ @@ -62,9 +62,6 @@ const propTypes = { /** Whether this option should be disabled */ isDisabled: PropTypes.bool, - /** Whether to disable the interactivity of this row */ - disableRowInteractivity: PropTypes.bool, - ...withLocalizePropTypes, }; @@ -77,10 +74,9 @@ const defaultProps = { forceTextUnreadStyle: false, showTitleTooltip: false, mode: 'default', - onSelectRow: null, + onSelectRow: () => {}, isDisabled: false, optionIsFocused: false, - disableRowInteractivity: false, }; const OptionRow = (props) => { @@ -143,7 +139,7 @@ const OptionRow = (props) => { e.preventDefault(); props.onSelectRow(props.option, touchableRef); }} - disabled={props.disableRowInteractivity} + disabled={props.isDisabled} activeOpacity={0.8} style={[ styles.flexRow, @@ -295,5 +291,21 @@ export default withLocalize(memo(OptionRow, (prevProps, nextProps) => { return false; } + if (prevProps.showSelectedState !== nextProps.showSelectedState) { + return false; + } + + if (prevProps.isDisabled !== nextProps.isDisabled) { + return false; + } + + if (prevProps.showTitleTooltip !== nextProps.showTitleTooltip) { + return false; + } + + if (prevProps.backgroundColor !== nextProps.backgroundColor) { + return false; + } + return true; })); diff --git a/src/components/OptionsList/BaseOptionsList.js b/src/components/OptionsList/BaseOptionsList.js index e65b0034035a..f6049a886c5a 100644 --- a/src/components/OptionsList/BaseOptionsList.js +++ b/src/components/OptionsList/BaseOptionsList.js @@ -4,7 +4,7 @@ import {View} from 'react-native'; import PropTypes from 'prop-types'; import Log from '../../libs/Log'; import styles from '../../styles/styles'; -import OptionRow from '../../pages/home/sidebar/OptionRow'; +import OptionRow from '../OptionRow'; import SectionList from '../SectionList'; import Text from '../Text'; import {propTypes as optionsListPropTypes, defaultProps as optionsListDefaultProps} from './optionsListPropTypes'; @@ -111,7 +111,7 @@ class BaseOptionsList extends Component { showSelectedState={this.props.canSelectMultipleOptions} hideAdditionalOptionStates={this.props.hideAdditionalOptionStates} forceTextUnreadStyle={this.props.forceTextUnreadStyle} - disableRowInteractivity={this.props.disableRowInteractivity} + isDisabled={this.props.isDisabled} /> ); } diff --git a/src/components/OptionsList/optionsListPropTypes.js b/src/components/OptionsList/optionsListPropTypes.js index 7b2e20c8828c..b51fc14d64d7 100644 --- a/src/components/OptionsList/optionsListPropTypes.js +++ b/src/components/OptionsList/optionsListPropTypes.js @@ -74,7 +74,7 @@ const propTypes = { optionMode: PropTypes.oneOf(_.values(CONST.OPTION_MODE)), /** Whether to disable the interactivity of the list's option row(s) */ - disableRowInteractivity: PropTypes.bool, + isDisabled: PropTypes.bool, /** Callback to execute when the SectionList lays out */ onLayout: PropTypes.func, @@ -98,7 +98,7 @@ const defaultProps = { innerRef: null, showTitleTooltip: false, optionMode: undefined, - disableRowInteractivity: false, + isDisabled: false, onLayout: undefined, }; diff --git a/src/components/optionPropTypes.js b/src/components/optionPropTypes.js index 1e5440ddf4a9..47af58d240cb 100644 --- a/src/components/optionPropTypes.js +++ b/src/components/optionPropTypes.js @@ -1,4 +1,5 @@ import PropTypes from 'prop-types'; +import participantPropTypes from './participantPropTypes'; export default PropTypes.shape({ // Text to display @@ -33,4 +34,19 @@ export default PropTypes.shape({ // Whether the report corresponds to a chat room isChatRoom: PropTypes.bool, + + // Whether the option has an outstanding IOU + hasOutstandingIOU: PropTypes.bool, + + // List of participants of the report + participantsList: PropTypes.arrayOf(participantPropTypes), + + // Descriptive text to be displayed besides selection element + descriptiveText: PropTypes.string, + + // The type of option we have e.g. user or report + type: PropTypes.string, + + // Text to show for tooltip + tooltipText: PropTypes.string, }); diff --git a/src/components/participantPropTypes.js b/src/components/participantPropTypes.js new file mode 100644 index 000000000000..3f965be445c1 --- /dev/null +++ b/src/components/participantPropTypes.js @@ -0,0 +1,15 @@ +import PropTypes from 'prop-types'; + +export default PropTypes.shape({ + // Primary login of participant + login: PropTypes.string, + + // Display Name of participant + displayName: PropTypes.string, + + // Avatar url of participant + avatar: PropTypes.string, + + /** First Name of the participant */ + firstName: PropTypes.string, +}); diff --git a/src/pages/ReportDetailsPage.js b/src/pages/ReportDetailsPage.js index 70323fe03b04..10dc4ea4f738 100644 --- a/src/pages/ReportDetailsPage.js +++ b/src/pages/ReportDetailsPage.js @@ -16,7 +16,7 @@ import styles from '../styles/styles'; import DisplayNames from '../components/DisplayNames'; import * as OptionsListUtils from '../libs/OptionsListUtils'; import * as ReportUtils from '../libs/reportUtils'; -import {participantPropTypes} from './home/sidebar/optionPropTypes'; +import participantPropTypes from '../components/participantPropTypes'; import * as Expensicons from '../components/Icon/Expensicons'; import ROUTES from '../ROUTES'; import MenuItem from '../components/MenuItem'; diff --git a/src/pages/home/HeaderView.js b/src/pages/home/HeaderView.js index 4b3969903c44..fb47e0506904 100644 --- a/src/pages/home/HeaderView.js +++ b/src/pages/home/HeaderView.js @@ -19,7 +19,7 @@ import Navigation from '../../libs/Navigation/Navigation'; import ROUTES from '../../ROUTES'; import DisplayNames from '../../components/DisplayNames'; import * as OptionsListUtils from '../../libs/OptionsListUtils'; -import {participantPropTypes} from './sidebar/optionPropTypes'; +import participantPropTypes from '../../components/participantPropTypes'; import VideoChatButtonAndMenu from '../../components/VideoChatButtonAndMenu'; import IOUBadge from '../../components/IOUBadge'; import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize'; diff --git a/src/pages/home/report/ParticipantLocalTime.js b/src/pages/home/report/ParticipantLocalTime.js index dcb48b101b06..25a14689bf9a 100644 --- a/src/pages/home/report/ParticipantLocalTime.js +++ b/src/pages/home/report/ParticipantLocalTime.js @@ -6,7 +6,7 @@ import lodashGet from 'lodash/get'; import Str from 'expensify-common/lib/str'; import styles from '../../../styles/styles'; import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize'; -import {participantPropTypes} from '../sidebar/optionPropTypes'; +import participantPropTypes from '../../../components/participantPropTypes'; import Text from '../../../components/Text'; import Timers from '../../../libs/Timers'; import CONST from '../../../CONST'; diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index b14bb03fab5b..cafee70c3b85 100755 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -35,7 +35,7 @@ import reportActionPropTypes from './reportActionPropTypes'; import * as ReportUtils from '../../../libs/reportUtils'; import ReportActionComposeFocusManager from '../../../libs/ReportActionComposeFocusManager'; import Text from '../../../components/Text'; -import {participantPropTypes} from '../sidebar/optionPropTypes'; +import participantPropTypes from '../../../components/participantPropTypes'; import ParticipantLocalTime from './ParticipantLocalTime'; import {withNetwork, withPersonalDetails} from '../../../components/OnyxProvider'; import DateUtils from '../../../libs/DateUtils'; diff --git a/src/pages/home/report/ReportActionsView.js b/src/pages/home/report/ReportActionsView.js index 592c279c8ec2..a92e335a1838 100755 --- a/src/pages/home/report/ReportActionsView.js +++ b/src/pages/home/report/ReportActionsView.js @@ -36,7 +36,7 @@ import Performance from '../../../libs/Performance'; import * as ReportUtils from '../../../libs/reportUtils'; import ONYXKEYS from '../../../ONYXKEYS'; import {withPersonalDetails} from '../../../components/OnyxProvider'; -import {participantPropTypes} from '../sidebar/optionPropTypes'; +import participantPropTypes from '../../../components/participantPropTypes'; import EmojiPicker from '../../../components/EmojiPicker'; import * as EmojiPickerAction from '../../../libs/actions/EmojiPickerAction'; diff --git a/src/pages/home/sidebar/SidebarLinks.js b/src/pages/home/sidebar/SidebarLinks.js index 0532ccf3fc11..509927586bbc 100644 --- a/src/pages/home/sidebar/SidebarLinks.js +++ b/src/pages/home/sidebar/SidebarLinks.js @@ -20,7 +20,7 @@ import * as OptionsListUtils from '../../../libs/OptionsListUtils'; import KeyboardSpacer from '../../../components/KeyboardSpacer'; import Tooltip from '../../../components/Tooltip'; import CONST from '../../../CONST'; -import {participantPropTypes} from './optionPropTypes'; +import participantPropTypes from '../../../components/participantPropTypes'; import themeColors from '../../../styles/themes/default'; import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize'; import * as App from '../../../libs/actions/App'; diff --git a/src/pages/home/sidebar/optionPropTypes.js b/src/pages/home/sidebar/optionPropTypes.js deleted file mode 100644 index f49f2c85cb8d..000000000000 --- a/src/pages/home/sidebar/optionPropTypes.js +++ /dev/null @@ -1,46 +0,0 @@ -import PropTypes from 'prop-types'; - -const participantPropTypes = PropTypes.shape({ - // Primary login of participant - login: PropTypes.string, - - // Display Name of participant - displayName: PropTypes.string, - - // Avatar url of participant - avatar: PropTypes.string, - - /** First Name of the participant */ - firstName: PropTypes.string, -}); - -const optionPropTypes = PropTypes.shape({ - // The full name of the user if available, otherwise the login (email/phone number) of the user - text: PropTypes.string.isRequired, - - // Subtitle to show under report displayName, mostly lastMessageText of the report - alternateText: PropTypes.string, - - // List of participants of the report - participantsList: PropTypes.arrayOf(participantPropTypes), - - // The array URLs or icons of the person's avatar - icons: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.func])), - - // Descriptive text to be displayed besides selection element - descriptiveText: PropTypes.string, - - // The type of option we have e.g. user or report - type: PropTypes.string, - - // The option key provided to FlatList keyExtractor - keyForList: PropTypes.string, - - // Text to show for tooltip - tooltipText: PropTypes.string, -}); - -export { - participantPropTypes, - optionPropTypes, -}; diff --git a/src/pages/iou/IOUCurrencySelection.js b/src/pages/iou/IOUCurrencySelection.js index 933583d1210c..3121ecae1545 100644 --- a/src/pages/iou/IOUCurrencySelection.js +++ b/src/pages/iou/IOUCurrencySelection.js @@ -8,7 +8,7 @@ import * as PersonalDetails from '../../libs/actions/PersonalDetails'; import ONYXKEYS from '../../ONYXKEYS'; import * as OptionsListUtils from '../../libs/OptionsListUtils'; import Text from '../../components/Text'; -import OptionRow from '../home/sidebar/OptionRow'; +import OptionRow from '../../components/OptionRow'; import TextInput from '../../components/TextInput'; import Navigation from '../../libs/Navigation/Navigation'; import ScreenWrapper from '../../components/ScreenWrapper'; diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js index c9f97aeb58d7..cb916ad25b4f 100644 --- a/src/pages/workspace/WorkspaceMembersPage.js +++ b/src/pages/workspace/WorkspaceMembersPage.js @@ -24,7 +24,7 @@ import ConfirmModal from '../../components/ConfirmModal'; import personalDetailsPropType from '../personalDetailsPropType'; import Permissions from '../../libs/Permissions'; import withWindowDimensions, {windowDimensionsPropTypes} from '../../components/withWindowDimensions'; -import OptionRow from '../home/sidebar/OptionRow'; +import OptionRow from '../../components/OptionRow'; import CheckboxWithTooltip from '../../components/CheckboxWithTooltip'; import Hoverable from '../../components/Hoverable'; import withFullPolicy, {fullPolicyPropTypes, fullPolicyDefaultProps} from './withFullPolicy'; @@ -215,7 +215,7 @@ class WorkspaceMembersPage extends React.Component { ; + +// Arguments can be passed to the component by binding +// See: https://storybook.js.org/docs/react/writing-stories/introduction#using-args +const Default = Template.bind({}); + +export { + Default, +};