-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
Disables the Button during onPress call in PressableWithFeedback #18122
Changes from all commits
4471e8b
90d9b72
0c045be
fcee719
76500fc
cb06109
11a0929
ee9e4d2
ec2b5c2
e1640db
2d14e33
1bca5e6
690cf59
738cf17
bba4458
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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; | ||
} | ||
|
@@ -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; | ||
} | ||
|
@@ -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) { | ||
|
@@ -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), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why this change is required? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is required to apply styles based on the component states like isHovered, isDisabled, etc just like the lines below it. @robertKozik told me to add it so maybe he can add more context here if needed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The idea inside style={({isHovered, isPressed}) => ({
isHovered && <<hoverStyle>>,
isPressed && <<pressStyle>>
})} We would get: pressedStyle={<<pressStyle>>}
hoverStyle={<<hoverStyle>>} But as During our convo with @priyeshshah11 I came up with this change because I thought It could be used there. |
||
isScreenReaderActive && StyleUtils.parseStyleFromFunction(props.screenReaderActiveStyle, state), | ||
state.focused && StyleUtils.parseStyleFromFunction(props.focusStyle, state), | ||
state.hovered && StyleUtils.parseStyleFromFunction(props.hoverStyle, state), | ||
|
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'; | ||
|
@@ -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)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nab, but if onPress is not an instance of Promise, does it still have to be inside could you elaborate difference between the above code and the following:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes I would prefer for it to be inside There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I am not sure about this when we have sync calls, but it's okay to keep what it is right now. |
||
setDisabled(props.disabled); | ||
Comment on lines
+44
to
+46
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The To better explain, here is an example:
This logic is copied from OptionRow but we missed that case in both PRs which lead to a regression #20983. |
||
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), | ||
]} | ||
> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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(); | ||
|
@@ -1078,7 +1079,7 @@ function createWorkspace(ownerEmail = '', makeMeAdmin = false, policyName = '', | |
}, | ||
); | ||
|
||
Navigation.isNavigationReady().then(() => { | ||
return Navigation.isNavigationReady().then(() => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Coming from #17452 (comment), this return promise is not used anywhere. So this change is unnecessary. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oops we were actually supposed to return a value on @priyeshshah11 Can you please raise a quick follow up PR? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But I couldn't reproduce the original issue with this PR. Still need promise though? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like we don't need it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @s77rt what's the conclusion here? do you still want me to raise another PR? to remove the promise part or instead return it from the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @priyeshshah11 Raise a PR that simply return the onPress on Button. (promise may be removed on the other PR) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
if (transitionFromOldDot) { | ||
Navigation.dismissModal(); // Dismiss /transition route for OldDot to NewDot transitions | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be required
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does that mean all Buttons will need an accessibility label? & should adding all of them be in scope of this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well since
accessibilityLabel
is required onGenericPressable
it would make sense to have this required onButton
too. I think it would be better to split this to two PRs:cc @roryabraham thoughts on this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or given that I have already done the majority of the work for both the things above, I would prefer to move updating all usages of
Button
to add accessibilityLabels to a seperate PR.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that
accessibilityLabel
should be required. I also agree that we should start by disablingPressableWithFeedback
on press in this PR, then create a separate PR to migrate fromPressable
toPressableWithFeedback
forButton
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@roryabraham I have already done the migration part in this PR as we didn't get a reply for ~2 weeks, so what's the plan of action here?