Repository navigation
fix(button): prevent false ripples during scroll deceleration (#4911) #5133
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
base: main
Are you sure you want to change the base?
Changes from all commits
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 |
|---|---|---|
|
|
@@ -110,6 +110,10 @@ export type Props = Omit<ViewProps, 'style'> & { | |
| * The number of milliseconds a user must touch the element before executing `onLongPress`. | ||
| */ | ||
| delayLongPress?: number; | ||
| /** | ||
| * Delay in ms, from the start of the touch, before the press is engaged and ripple is triggered. | ||
| */ | ||
| unstable_pressDelay?: number; | ||
|
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. could we check how this lands against #5097 ? that PR is actively rewriting this file & already covers all 3 places this PR edits, so it'll definitely conflict. 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. [blocker] another thing to flag: API leak guard in |
||
| /** | ||
| * Style of button's inner content. | ||
| * Use this prop to apply custom height and width, to set a custom padding or to set the icon on the right with `flexDirection: 'row-reverse'`. | ||
|
|
@@ -179,6 +183,7 @@ const Button = ({ | |
| onPressOut, | ||
| onLongPress, | ||
| delayLongPress, | ||
| unstable_pressDelay, | ||
| style, | ||
| theme: themeOverrides, | ||
| uppercase: uppercaseProp, | ||
|
|
@@ -327,6 +332,7 @@ const Button = ({ | |
| onPressIn={hasPassedTouchHandler ? handlePressIn : undefined} | ||
| onPressOut={hasPassedTouchHandler ? handlePressOut : undefined} | ||
| delayLongPress={delayLongPress} | ||
| unstable_pressDelay={unstable_pressDelay} | ||
|
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. what do you think about fast-tap case? |
||
| aria-label={ariaLabel} | ||
| accessibilityHint={accessibilityHint} | ||
| role={role} | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -98,6 +98,19 @@ it('renders active button if only onLongPress handler is passed', async () => { | |
| expect(screen.getByTestId('active-button')).toBeEnabled(); | ||
| }); | ||
|
|
||
| it('renders button with unstable_pressDelay and triggers onPress', async () => { | ||
|
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. [blocker] could we strengthen these? I tried running this test after reverting changes in so wdyt about driving RN's responder state machine with fake timers asserting |
||
| const onPress = jest.fn(); | ||
|
|
||
| await render( | ||
| <Button testID="delay-button" unstable_pressDelay={100} onPress={onPress}> | ||
| Delay Button | ||
| </Button> | ||
| ); | ||
|
|
||
| await userEvent.press(screen.getByTestId('delay-button')); | ||
| expect(onPress).toHaveBeenCalledTimes(1); | ||
| }); | ||
|
|
||
| it('renders button with color', async () => { | ||
| const tree = ( | ||
| await render(<Button textColor={pink500}>Custom Button</Button>) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,6 +12,7 @@ export type Settings = { | |
| testID, | ||
| }: IconProps) => React.ReactNode; | ||
| rippleEffectEnabled?: boolean; | ||
| ripplePressDelay?: number; | ||
|
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. could we keep this PR to per-component #4911 is about a button inside scrolling list, but this setting changes every for what it's worth, #3806 (same problem) was solved at the call site rather than with library-wide default. the wiring itself looks fine & consistent with |
||
| }; | ||
|
|
||
| export const SettingsContext = React.createContext<Settings>({ | ||
|
|
||
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.
[nit] I tested it out & seems like press still fires - only feedback is delayed
so maybe we could reword it to smth like "...before the press feedback (ripple) is shown"?