Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow bubbling Enter key press event on Button #28374

Merged
6 changes: 5 additions & 1 deletion src/components/Button/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ import PressableWithFeedback from '../Pressable/PressableWithFeedback';
import refPropTypes from '../refPropTypes';

const propTypes = {
/** Should the press event bubble across multiple instances when Enter key triggers it. */
allowBubble: PropTypes.bool,

/** The text for the button label */
text: PropTypes.string,

Expand Down Expand Up @@ -123,6 +126,7 @@ const propTypes = {
};

const defaultProps = {
allowBubble: false,
text: '',
shouldShowRightIcon: false,
icon: null,
Expand Down Expand Up @@ -183,7 +187,7 @@ class Button extends Component {
shortcutConfig.descriptionKey,
shortcutConfig.modifiers,
true,
false,
this.props.allowBubble,
this.props.enterKeyEventListenerPriority,
false,
);
Expand Down
6 changes: 6 additions & 0 deletions src/components/ButtonWithDropdownMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ const propTypes = {
/** Callback to execute when the main button is pressed */
onPress: PropTypes.func.isRequired,

/** Call the onPress function on main button when Enter key is pressed */
pressOnEnter: PropTypes.bool,

/** Whether we should show a loading state for the main button */
isLoading: PropTypes.bool,

Expand Down Expand Up @@ -57,6 +60,7 @@ const propTypes = {
const defaultProps = {
isLoading: false,
isDisabled: false,
pressOnEnter: false,
menuHeaderText: '',
style: [],
buttonSize: CONST.DROPDOWN_BUTTON_SIZE.MEDIUM,
Expand Down Expand Up @@ -101,6 +105,7 @@ function ButtonWithDropdownMenu(props) {
<View style={[styles.flexRow, styles.justifyContentBetween, styles.alignItemsCenter, ...props.style]}>
<Button
success
pressOnEnter={props.pressOnEnter}
ref={props.buttonRef}
onPress={(event) => props.onPress(event, selectedItem.value)}
text={selectedItem.text}
Expand Down Expand Up @@ -138,6 +143,7 @@ function ButtonWithDropdownMenu(props) {
) : (
<Button
success
pressOnEnter={props.pressOnEnter}
isDisabled={props.isDisabled}
style={[styles.w100, ...props.style]}
isLoading={props.isLoading}
Expand Down
2 changes: 2 additions & 0 deletions src/components/DistanceRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,8 @@ function DistanceRequest({transactionID, report, transaction, mapboxAccessToken,
</View>
<Button
success
allowBubble
pressOnEnter
style={[styles.w100, styles.mb4, styles.ph4, styles.flexShrink0]}
onPress={() => onSubmit(waypoints)}
isDisabled={_.size(validatedWaypoints) < 2 || (!isOffline && (hasRouteError || isLoadingRoute || isLoading))}
Expand Down
1 change: 1 addition & 0 deletions src/components/MoneyRequestConfirmationList.js
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@ function MoneyRequestConfirmationList(props) {
/>
) : (
<ButtonWithDropdownMenu
pressOnEnter
isDisabled={shouldDisableButton}
onPress={(_event, value) => confirm(value)}
options={splitOrRequestOptions}
Expand Down
3 changes: 2 additions & 1 deletion src/pages/iou/steps/MoneyRequestAmountForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -266,10 +266,11 @@ function MoneyRequestAmountForm({amount, currency, isEditing, forwardedRef, onCu
) : null}
<Button
success
allowBubble
pressOnEnter
medium={isExtraSmallScreenHeight}
style={[styles.w100, styles.mt5]}
onPress={submitAndNavigateToNextPage}
pressOnEnter
text={buttonText}
/>
</View>
Expand Down
31 changes: 29 additions & 2 deletions src/stories/Button.stories.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
/* eslint-disable react/jsx-props-no-spreading */
import React, {useCallback, useState} from 'react';
import {View} from 'react-native';
import Button from '../components/Button';
import Text from '../components/Text';

/**
* We use the Component Story Format for writing stories. Follow the docs here:
Expand Down Expand Up @@ -28,7 +31,6 @@ function PressOnEnter(props) {
}, []);
return (
<Button
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
// eslint-disable-next-line react/prop-types
text={text || props.text}
Expand All @@ -37,6 +39,24 @@ function PressOnEnter(props) {
);
}

function PressOnEnterWithBubbling(props) {
return (
<>
<Text>Both buttons will trigger on press of Enter as the Enter event will bubble across all instances of button.</Text>
<View style={{flexDirection: 'row', padding: 10}}>
<PressOnEnter
{...props}
text="Button A"
/>
<PressOnEnter
{...props}
text="Button B"
/>
</View>
</>
);
}

Default.args = {
text: 'Save & Continue',
success: true,
Expand All @@ -53,5 +73,12 @@ PressOnEnter.args = {
success: true,
};

PressOnEnterWithBubbling.args = {
pressOnEnter: true,
success: true,
medium: true,
allowBubble: true,
};

export default story;
export {Default, Loading, PressOnEnter};
export {Default, Loading, PressOnEnter, PressOnEnterWithBubbling};
8 changes: 6 additions & 2 deletions src/stories/ButtonWithDropdownMenu.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,13 @@ function Template(args) {
const Default = Template.bind({});
Default.args = {
buttonText: 'Pay using Expensify',
onPress: (e, item) => {
alert(`Button ${item} is pressed.`);
},
pressOnEnter: true,
options: [
{value: 1, text: 'One'},
{value: 2, text: 'Two'},
{value: 'One', text: 'One'},
{value: 'Two', text: 'Two'},
],
};

Expand Down
Loading