diff --git a/src/components/OptionRow.js b/src/components/OptionRow.js index 47ab4fe45db1..85d3e83c1360 100644 --- a/src/components/OptionRow.js +++ b/src/components/OptionRow.js @@ -70,6 +70,9 @@ const propTypes = { /** Whether to remove the lateral padding and align the content with the margins */ shouldDisableRowInnerPadding: PropTypes.bool, + /** Whether to prevent default focusing on select */ + shouldPreventDefaultFocusOnSelectRow: PropTypes.bool, + /** Whether to wrap large text up to 2 lines */ isMultilineSupported: PropTypes.bool, @@ -95,6 +98,7 @@ const defaultProps = { style: null, shouldHaveOptionSeparator: false, shouldDisableRowInnerPadding: false, + shouldPreventDefaultFocusOnSelectRow: false, }; class OptionRow extends Component { @@ -213,6 +217,7 @@ class OptionRow extends Component { hoverDimmingValue={1} hoverStyle={this.props.hoverStyle} needsOffscreenAlphaCompositing={lodashGet(this.props.option, 'icons.length', 0) >= 2} + onMouseDown={this.props.shouldPreventDefaultFocusOnSelectRow ? (e) => e.preventDefault() : undefined} > diff --git a/src/components/OptionsList/BaseOptionsList.js b/src/components/OptionsList/BaseOptionsList.js index 5a40c28a86c9..23049b65f198 100644 --- a/src/components/OptionsList/BaseOptionsList.js +++ b/src/components/OptionsList/BaseOptionsList.js @@ -54,6 +54,7 @@ function BaseOptionsList({ showScrollIndicator, listContainerStyles, shouldDisableRowInnerPadding, + shouldPreventDefaultFocusOnSelectRow, disableFocusOptions, canSelectMultipleOptions, shouldShowMultipleOptionSelectorAsButton, @@ -206,6 +207,7 @@ function BaseOptionsList({ isDisabled={isItemDisabled} shouldHaveOptionSeparator={index > 0 && shouldHaveOptionSeparator} shouldDisableRowInnerPadding={shouldDisableRowInnerPadding} + shouldPreventDefaultFocusOnSelectRow={shouldPreventDefaultFocusOnSelectRow} isMultilineSupported={isRowMultilineSupported} /> ); diff --git a/src/components/OptionsList/optionsListPropTypes.js b/src/components/OptionsList/optionsListPropTypes.js index a2479c878041..165cec699b80 100644 --- a/src/components/OptionsList/optionsListPropTypes.js +++ b/src/components/OptionsList/optionsListPropTypes.js @@ -79,6 +79,9 @@ const propTypes = { /** Whether to disable the inner padding in rows */ shouldDisableRowInnerPadding: PropTypes.bool, + /** Whether to prevent default focusing when selecting a row */ + shouldPreventDefaultFocusOnSelectRow: PropTypes.bool, + /** Whether to show the scroll bar */ showScrollIndicator: PropTypes.bool, @@ -107,6 +110,7 @@ const defaultProps = { onLayout: undefined, shouldHaveOptionSeparator: false, shouldDisableRowInnerPadding: false, + shouldPreventDefaultFocusOnSelectRow: false, showScrollIndicator: false, isRowMultilineSupported: false, }; diff --git a/src/components/OptionsSelector/BaseOptionsSelector.js b/src/components/OptionsSelector/BaseOptionsSelector.js index 1d0105394042..183ddb20c87b 100755 --- a/src/components/OptionsSelector/BaseOptionsSelector.js +++ b/src/components/OptionsSelector/BaseOptionsSelector.js @@ -316,7 +316,7 @@ class BaseOptionsSelector extends Component { */ selectRow(option, ref) { return new Promise((resolve) => { - if (this.props.shouldShowTextInput && this.props.shouldFocusOnSelectRow) { + if (this.props.shouldShowTextInput && this.props.shouldPreventDefaultFocusOnSelectRow) { if (this.relatedTarget && ref === this.relatedTarget) { this.textInput.focus(); this.relatedTarget = null; @@ -344,7 +344,7 @@ class BaseOptionsSelector extends Component { * @param {Object} option */ addToSelection(option) { - if (this.props.shouldShowTextInput && this.props.shouldFocusOnSelectRow) { + if (this.props.shouldShowTextInput && this.props.shouldPreventDefaultFocusOnSelectRow) { this.textInput.focus(); if (this.textInput.isFocused()) { setSelection(this.textInput, 0, this.props.value.length); @@ -372,7 +372,7 @@ class BaseOptionsSelector extends Component { maxLength={this.props.maxLength} keyboardType={this.props.keyboardType} onBlur={(e) => { - if (!this.props.shouldFocusOnSelectRow) { + if (!this.props.shouldPreventDefaultFocusOnSelectRow) { return; } this.relatedTarget = e.relatedTarget; @@ -417,6 +417,7 @@ class BaseOptionsSelector extends Component { isLoading={!this.props.shouldShowOptions} showScrollIndicator={this.props.showScrollIndicator} isRowMultilineSupported={this.props.isRowMultilineSupported} + shouldPreventDefaultFocusOnSelectRow={this.props.shouldPreventDefaultFocusOnSelectRow} /> ); return ( diff --git a/src/components/OptionsSelector/optionsSelectorPropTypes.js b/src/components/OptionsSelector/optionsSelectorPropTypes.js index 8a7158092967..2eaa727b0f25 100644 --- a/src/components/OptionsSelector/optionsSelectorPropTypes.js +++ b/src/components/OptionsSelector/optionsSelectorPropTypes.js @@ -80,8 +80,8 @@ const propTypes = { /** Whether to show the title tooltip */ showTitleTooltip: PropTypes.bool, - /** Whether to focus the textinput after an option is selected */ - shouldFocusOnSelectRow: PropTypes.bool, + /** Whether to prevent default focusing of options and focus the textinput when selecting an option */ + shouldPreventDefaultFocusOnSelectRow: PropTypes.bool, /** Whether to autofocus the search input on mount */ autoFocus: PropTypes.bool, @@ -144,7 +144,7 @@ const defaultProps = { hideSectionHeaders: false, boldStyle: false, showTitleTooltip: false, - shouldFocusOnSelectRow: false, + shouldPreventDefaultFocusOnSelectRow: false, autoFocus: true, shouldShowConfirmButton: false, confirmButtonText: undefined, diff --git a/src/components/SelectionList/BaseListItem.js b/src/components/SelectionList/BaseListItem.js index 8a42c84ffc67..171a58ee9fa9 100644 --- a/src/components/SelectionList/BaseListItem.js +++ b/src/components/SelectionList/BaseListItem.js @@ -13,7 +13,16 @@ import RadioListItem from './RadioListItem'; import OfflineWithFeedback from '../OfflineWithFeedback'; import CONST from '../../CONST'; -function BaseListItem({item, isFocused = false, isDisabled = false, showTooltip, canSelectMultiple = false, onSelectRow, onDismissError = () => {}}) { +function BaseListItem({ + item, + isFocused = false, + isDisabled = false, + showTooltip, + shouldPreventDefaultFocusOnSelectRow = false, + canSelectMultiple = false, + onSelectRow, + onDismissError = () => {}, +}) { const isUserItem = lodashGet(item, 'icons.length', 0) > 0; const ListItem = isUserItem ? UserListItem : RadioListItem; @@ -32,6 +41,7 @@ function BaseListItem({item, isFocused = false, isDisabled = false, showTooltip, hoverDimmingValue={1} hoverStyle={styles.hoveredComponentBG} dataSet={{[CONST.SELECTION_SCRAPER_HIDDEN_ELEMENT]: true}} + onMouseDown={shouldPreventDefaultFocusOnSelectRow ? (e) => e.preventDefault() : undefined} > { onSelectAll(); - if (shouldShowTextInput && shouldFocusOnSelectRow && textInputRef.current) { + if (shouldShowTextInput && shouldPreventDefaultFocusOnSelectRow && textInputRef.current) { textInputRef.current.focus(); } }; @@ -299,6 +299,7 @@ function BaseSelectionList({ canSelectMultiple={canSelectMultiple} onSelectRow={() => selectRow(item, true)} onDismissError={onDismissError} + shouldPreventDefaultFocusOnSelectRow={shouldPreventDefaultFocusOnSelectRow} /> ); }; @@ -401,6 +402,7 @@ function BaseSelectionList({ accessibilityState={{checked: flattenedSections.allSelected}} disabled={flattenedSections.allOptions.length === flattenedSections.disabledOptionsIndexes.length} dataSet={{[CONST.SELECTION_SCRAPER_HIDDEN_ELEMENT]: true}} + onMouseDown={shouldPreventDefaultFocusOnSelectRow ? (e) => e.preventDefault() : undefined} > 1 ? translate('newChatPage.createGroup') : translate('newChatPage.createChat')} diff --git a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js index e3dc7407e99b..bedca1a10c35 100755 --- a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js +++ b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js @@ -263,7 +263,7 @@ function MoneyRequestParticipantsSelector({ textInputLabel={translate('optionsSelector.nameEmailOrPhoneNumber')} safeAreaPaddingBottomStyle={safeAreaPaddingBottomStyle} shouldShowOptions={isOptionsDataReady} - shouldFocusOnSelectRow={!Browser.isMobile()} + shouldPreventDefaultFocusOnSelectRow={!Browser.isMobile()} shouldDelayFocus /> diff --git a/src/pages/workspace/WorkspaceInvitePage.js b/src/pages/workspace/WorkspaceInvitePage.js index 39495911b8dc..e7bbd9657e8b 100644 --- a/src/pages/workspace/WorkspaceInvitePage.js +++ b/src/pages/workspace/WorkspaceInvitePage.js @@ -18,6 +18,7 @@ import withPolicy, {policyDefaultProps, policyPropTypes} from './withPolicy'; import FullPageNotFoundView from '../../components/BlockingViews/FullPageNotFoundView'; import ROUTES from '../../ROUTES'; import * as PolicyUtils from '../../libs/PolicyUtils'; +import * as Browser from '../../libs/Browser'; import useNetwork from '../../hooks/useNetwork'; import useLocalize from '../../hooks/useLocalize'; import SelectionList from '../../components/SelectionList'; @@ -231,6 +232,7 @@ function WorkspaceInvitePage(props) { onConfirm={inviteUser} showScrollIndicator showLoadingPlaceholder={!didScreenTransitionEnd || !OptionsListUtils.isPersonalDetailsReady(props.personalDetails)} + shouldPreventDefaultFocusOnSelectRow={!Browser.isMobile()} />