Skip to content

Commit

Permalink
Merge pull request #18122 from priyeshshah11/priyeshshah11-disable-bu…
Browse files Browse the repository at this point in the history
…ttons

Disables the Button during onPress call in PressableWithFeedback
  • Loading branch information
roryabraham authored May 12, 2023
2 parents 3fba7dc + bba4458 commit 756e9d8
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 62 deletions.
71 changes: 35 additions & 36 deletions src/components/Button/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import React, {Component} from 'react';
import {Pressable, ActivityIndicator, View} from 'react-native';
import {ActivityIndicator, View} from 'react-native';
import PropTypes from 'prop-types';
import styles from '../../styles/styles';
import themeColors from '../../styles/themes/default';
import OpacityView from '../OpacityView';
import Text from '../Text';
import KeyboardShortcut from '../../libs/KeyboardShortcut';
import Icon from '../Icon';
Expand All @@ -15,6 +14,7 @@ import compose from '../../libs/compose';
import * as Expensicons from '../Icon/Expensicons';
import withNavigationFocus from '../withNavigationFocus';
import validateSubmitShortcut from './validateSubmitShortcut';
import PressableWithFeedback from '../Pressable/PressableWithFeedback';

const propTypes = {
/** The text for the button label */
Expand Down Expand Up @@ -106,6 +106,9 @@ const propTypes = {

/** Id to use for this button */
nativeID: PropTypes.string,

/** Accessibility label for the component */
accessibilityLabel: PropTypes.string,
};

const defaultProps = {
Expand Down Expand Up @@ -137,6 +140,7 @@ const defaultProps = {
shouldRemoveLeftBorderRadius: false,
shouldEnableHapticFeedback: false,
nativeID: '',
accessibilityLabel: '',
};

class Button extends Component {
Expand Down Expand Up @@ -235,7 +239,7 @@ class Button extends Component {

render() {
return (
<Pressable
<PressableWithFeedback
onPress={(e) => {
if (e && e.type === 'click') {
e.currentTarget.blur();
Expand All @@ -256,47 +260,42 @@ class Button extends Component {
onPressOut={this.props.onPressOut}
onMouseDown={this.props.onMouseDown}
disabled={this.props.isLoading || this.props.isDisabled}
style={[
wrapperStyle={[
this.props.isDisabled ? {...styles.cursorDisabled, ...styles.noSelect} : {},
styles.buttonContainer,
this.props.shouldRemoveRightBorderRadius ? styles.noRightBorderRadius : undefined,
this.props.shouldRemoveLeftBorderRadius ? styles.noLeftBorderRadius : undefined,
...StyleUtils.parseStyleAsArray(this.props.style),
]}
style={[
styles.button,
this.props.small ? styles.buttonSmall : undefined,
this.props.medium ? styles.buttonMedium : undefined,
this.props.large ? styles.buttonLarge : undefined,
this.props.success ? styles.buttonSuccess : undefined,
this.props.danger ? styles.buttonDanger : undefined,
this.props.isDisabled && (this.props.success || this.props.danger) ? styles.buttonOpacityDisabled : undefined,
this.props.isDisabled && !this.props.danger && !this.props.success ? styles.buttonDisabled : undefined,
this.props.shouldRemoveRightBorderRadius ? styles.noRightBorderRadius : undefined,
this.props.shouldRemoveLeftBorderRadius ? styles.noLeftBorderRadius : undefined,
...this.props.innerStyles,
]}
hoverStyle={[
this.props.success && !this.props.isDisabled ? styles.buttonSuccessHovered : undefined,
this.props.danger && !this.props.isDisabled ? styles.buttonDangerHovered : undefined,
]}
nativeID={this.props.nativeID}
accessibilityLabel={this.props.accessibilityLabel}
hoverDimmingValue={1}
>
{({pressed, hovered}) => {
const activeAndHovered = !this.props.isDisabled && hovered;
return (
<OpacityView
shouldDim={pressed}
style={[
styles.button,
this.props.small ? styles.buttonSmall : undefined,
this.props.medium ? styles.buttonMedium : undefined,
this.props.large ? styles.buttonLarge : undefined,
this.props.success ? styles.buttonSuccess : undefined,
this.props.danger ? styles.buttonDanger : undefined,
this.props.isDisabled && (this.props.success || this.props.danger) ? styles.buttonOpacityDisabled : undefined,
this.props.isDisabled && !this.props.danger && !this.props.success ? styles.buttonDisabled : undefined,
this.props.success && activeAndHovered ? styles.buttonSuccessHovered : undefined,
this.props.danger && activeAndHovered ? styles.buttonDangerHovered : undefined,
this.props.shouldRemoveRightBorderRadius ? styles.noRightBorderRadius : undefined,
this.props.shouldRemoveLeftBorderRadius ? styles.noLeftBorderRadius : undefined,
...this.props.innerStyles,
]}
>
{this.renderContent()}
{this.props.isLoading && (
<ActivityIndicator
color={this.props.success || this.props.danger ? themeColors.textLight : themeColors.text}
style={[styles.pAbsolute, styles.l0, styles.r0]}
/>
)}
</OpacityView>
);
}}
</Pressable>
{this.renderContent()}
{this.props.isLoading && (
<ActivityIndicator
color={this.props.success || this.props.danger ? themeColors.textLight : themeColors.text}
style={[styles.pAbsolute, styles.l0, styles.r0]}
/>
)}
</PressableWithFeedback>
);
}
}
Expand Down
35 changes: 16 additions & 19 deletions src/components/Pressable/GenericPressable/BaseGenericPressable.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ const GenericPressable = forwardRef((props, ref) => {
return props.disabled || shouldBeDisabledByScreenReader;
}, [isScreenReaderActive, enableInScreenReaderStates, props.disabled]);

const onLongPressHandler = useCallback(() => {
const onLongPressHandler = useCallback((event) => {
if (isDisabled) {
return;
}
Expand All @@ -76,12 +76,12 @@ const GenericPressable = forwardRef((props, ref) => {
if (ref && ref.current) {
ref.current.blur();
}
onLongPress();
onLongPress(event);

Accessibility.moveAccessibilityFocus(nextFocusRef);
}, [shouldUseHapticsOnLongPress, onLongPress, nextFocusRef, ref, isDisabled]);

const onPressHandler = useCallback(() => {
const onPressHandler = useCallback((event) => {
if (isDisabled) {
return;
}
Expand All @@ -91,20 +91,17 @@ const GenericPressable = forwardRef((props, ref) => {
if (ref && ref.current) {
ref.current.blur();
}
onPress();
onPress(event);

Accessibility.moveAccessibilityFocus(nextFocusRef);
}, [shouldUseHapticsOnPress, onPress, nextFocusRef, ref, isDisabled]);

const onKeyPressHandler = useCallback(
(event) => {
if (event.key !== 'Enter') {
return;
}
onPressHandler();
},
[onPressHandler],
);
const onKeyPressHandler = useCallback((event) => {
if (event.key !== 'Enter') {
return;
}
onPressHandler(event);
}, [onPressHandler]);

useEffect(() => {
if (!keyboardShortcut) {
Expand All @@ -119,14 +116,14 @@ const GenericPressable = forwardRef((props, ref) => {
hitSlop={shouldUseAutoHitSlop && hitSlop}
onLayout={onLayout}
ref={ref}
onPress={!isDisabled && onPressHandler}
onLongPress={!isDisabled && onLongPressHandler}
onKeyPress={!isDisabled && onKeyPressHandler}
onPressIn={!isDisabled && onPressIn}
onPressOut={!isDisabled && onPressOut}
onPress={!isDisabled ? onPressHandler : undefined}
onLongPress={!isDisabled ? onLongPressHandler : undefined}
onKeyPress={!isDisabled ? onKeyPressHandler : undefined}
onPressIn={!isDisabled ? onPressIn : undefined}
onPressOut={!isDisabled ? onPressOut : undefined}
style={(state) => [
getCursorStyle(isDisabled, [props.accessibilityRole, props.role].includes('text')),
props.style,
StyleUtils.parseStyleFromFunction(props.style, state),
isScreenReaderActive && StyleUtils.parseStyleFromFunction(props.screenReaderActiveStyle, state),
state.focused && StyleUtils.parseStyleFromFunction(props.focusStyle, state),
state.hovered && StyleUtils.parseStyleFromFunction(props.hoverStyle, state),
Expand Down
29 changes: 25 additions & 4 deletions src/components/Pressable/PressableWithFeedback.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, {forwardRef} from 'react';
import React, {forwardRef, useEffect, useState} from 'react';
import _ from 'underscore';
import propTypes from 'prop-types';
import {InteractionManager} from 'react-native';
import GenericPressable from './GenericPressable';
import GenericPressablePropTypes from './GenericPressable/PropTypes';
import OpacityView from '../OpacityView';
Expand All @@ -24,21 +25,41 @@ const PressableWithFeedbackDefaultProps = {

const PressableWithFeedback = forwardRef((props, ref) => {
const propsWithoutStyling = _.omit(props, omittedProps);
const [disabled, setDisabled] = useState(props.disabled);

useEffect(() => {
setDisabled(props.disabled);
}, [props.disabled]);

return (
<GenericPressable
ref={ref}
style={props.wrapperStyle}
// eslint-disable-next-line react/jsx-props-no-spreading
{...propsWithoutStyling}
disabled={disabled}
onPress={(e) => {
setDisabled(true);
const onPress = props.onPress(e);
InteractionManager.runAfterInteractions(() => {
if (!(onPress instanceof Promise)) {
setDisabled(props.disabled);
return;
}
onPress.then(() => {
setDisabled(props.disabled);
});
});
}}
>
{(state) => (
<OpacityView
shouldDim={state.pressed || state.hovered}
shouldDim={!disabled && (state.pressed || state.hovered)}
dimmingValue={state.pressed ? props.pressDimmingValue : props.hoverDimmingValue}
style={[
StyleUtils.parseStyleFromFunction(props.style, state),
state.pressed && StyleUtils.parseStyleFromFunction(props.pressStyle, state),
state.hovered && StyleUtils.parseStyleAsArray(props.hoverStyle, state),
!disabled && state.pressed && StyleUtils.parseStyleFromFunction(props.pressStyle, state),
!disabled && state.hovered && StyleUtils.parseStyleAsArray(props.hoverStyle, state),
state.focused && StyleUtils.parseStyleAsArray(props.focusStyle, state),
]}
>
Expand Down
2 changes: 1 addition & 1 deletion src/libs/Accessibility/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const useScreenReaderStatus = () => {
useEffect(() => {
const subscription = AccessibilityInfo.addEventListener('screenReaderChanged', setIsScreenReaderEnabled);

return subscription.remove;
return subscription && subscription.remove;
}, []);

return isScreenReaderEnabled;
Expand Down
3 changes: 2 additions & 1 deletion src/libs/actions/Policy.js
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,7 @@ function generatePolicyID() {
* @param {Boolean} [makeMeAdmin] Optional, leave the calling account as an admin on the policy
* @param {String} [policyName] Optional, custom policy name we will use for created workspace
* @param {Boolean} [transitionFromOldDot] Optional, if the user is transitioning from old dot
* @returns {Promise}
*/
function createWorkspace(ownerEmail = '', makeMeAdmin = false, policyName = '', transitionFromOldDot = false) {
const policyID = generatePolicyID();
Expand Down Expand Up @@ -1078,7 +1079,7 @@ function createWorkspace(ownerEmail = '', makeMeAdmin = false, policyName = '',
},
);

Navigation.isNavigationReady().then(() => {
return Navigation.isNavigationReady().then(() => {
if (transitionFromOldDot) {
Navigation.dismissModal(); // Dismiss /transition route for OldDot to NewDot transitions
}
Expand Down
1 change: 1 addition & 0 deletions src/pages/workspace/WorkspacesListPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ class WorkspacesListPage extends Component {
)}
<FixedFooter style={[styles.flexGrow0]}>
<Button
accessibilityLabel={this.props.translate('workspace.new.newWorkspace')}
success
text={this.props.translate('workspace.new.newWorkspace')}
onPress={() => Policy.createWorkspace()}
Expand Down
2 changes: 1 addition & 1 deletion src/styles/variables.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,5 +135,5 @@ export default {
// This is calculated based on the values specified in the 'getGoogleListViewStyle' function of the 'StyleUtils' utility
googleEmptyListViewHeight: 14,
hoverDimValue: 0.5,
pressDimValue: 0.2,
pressDimValue: 0.8,
};

0 comments on commit 756e9d8

Please sign in to comment.