Skip to content

Conversation

@BohdanKhv
Copy link

@BohdanKhv BohdanKhv commented Nov 2, 2025

  • Add optional debounce prop to prevent rapid successive presses
  • Implement debounce logic in both web and native TouchableRipple components
  • Add comprehensive test interface in TouchableRipple example
  • Update documentation with usage examples
  • Maintain backward compatibility with existing code

Motivation

Had to write extra code just to implement this in my apps


Note

Add optional debounce to TouchableRipple (web/native), wire it to onPress, and update examples and tests.

  • Components:
    • Add optional debounce prop to TouchableRipple (web: src/components/TouchableRipple/TouchableRipple.tsx, native: src/components/TouchableRipple/TouchableRipple.native.tsx).
    • Implement debouncedOnPress using Date.now() + ref; hook into Pressable via onPress={debouncedOnPress}.
    • Minor typing adjustments for PressableStateCallbackType on web.
  • Examples:
    • Revamp example/src/Examples/TouchableRippleExample.tsx with a scrollable demo showcasing basic ripple and a debounce test (normal vs debounced buttons, counters, reset).
  • Tests:
    • Extend src/components/__tests__/TouchableRipple.test.tsx to cover debounced vs non-debounced presses and existing behaviors.

Written by Cursor Bugbot for commit c77ad85. This will update automatically on new commits. Configure here.

- Add optional debounce prop to prevent rapid successive presses
- Implement debounce logic in both web and native TouchableRipple components
- Add comprehensive test interface in TouchableRipple example
- Update documentation with usage examples
- Maintain backward compatibility with existing code
Copilot AI review requested due to automatic review settings November 2, 2025 02:11
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is being reviewed by Cursor Bugbot

Details

Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

expect(onPress).toHaveBeenCalledTimes(2);

jest.useRealTimers();
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Unmocked Time Improves Debounce Testing Reliability

The debounce test uses jest.useFakeTimers() and jest.advanceTimersByTime(), but the debounce implementation relies on Date.now(). Since Date.now() isn't mocked by Jest's fake timers by default, advanceTimersByTime() doesn't affect the debounce logic's internal clock. This makes the test unreliable and unable to accurately verify the debounce behavior.

Fix in Cursor Fix in Web

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds a debounce feature to the TouchableRipple component to prevent rapid successive presses. The debounce functionality uses a time-based approach that ignores press events occurring within a specified time window after the first press.

  • Adds optional debounce prop (in milliseconds) to TouchableRipple component
  • Implements debouncing logic using Date.now() and a ref to track last press time
  • Includes comprehensive test coverage for debounced and non-debounced behavior

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
src/components/TouchableRipple/TouchableRipple.tsx Added debounce prop, implementation logic, and type annotations for PressableStateCallbackType
src/components/TouchableRipple/TouchableRipple.native.tsx Added debounce prop and implementation logic for native platform
src/components/tests/TouchableRipple.test.tsx Added tests for debounce functionality with fake timers
example/src/Examples/TouchableRippleExample.tsx Enhanced example with interactive debounce demonstration

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

expect(onPress).toHaveBeenCalledTimes(1);

// Fast forward time past debounce window
jest.advanceTimersByTime(400);
Copy link

Copilot AI Nov 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test advances timers by 400ms, but the debounce implementation uses Date.now() which is not affected by jest.advanceTimersByTime(). This test will likely fail because Date.now() returns real time, not fake timer time. Mock Date.now() using jest.spyOn(Date, 'now') and control its return value, or use jest.setSystemTime() if using modern fake timers.

Copilot uses AI. Check for mistakes.
onPressOut={handlePressOut}
disabled={disabled}
style={(state) => [
style={(state: PressableStateCallbackType) => [
Copy link

Copilot AI Nov 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Adding explicit type annotation here is unnecessary since TypeScript can infer the type from the Pressable component's props. This change adds no value and increases verbosity. Consider removing the type annotation unless there's a specific type inference issue.

Copilot uses AI. Check for mistakes.
]}
>
{(state) =>
{(state: PressableStateCallbackType) =>
Copy link

Copilot AI Nov 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Adding explicit type annotation here is unnecessary since TypeScript can infer the type from the Pressable component's children render prop. This change adds no value and increases verbosity. Consider removing the type annotation unless there's a specific type inference issue.

Suggested change
{(state: PressableStateCallbackType) =>
{state =>

Copilot uses AI. Check for mistakes.
onPress={debouncedOnPress}
>
{({ pressed }) => (
{({ pressed }: { pressed: boolean }) => (
Copy link

Copilot AI Nov 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Adding inline type annotation for a destructured parameter is unnecessarily verbose. TypeScript can infer this type from the Pressable component's children render prop. Consider removing the type annotation unless there's a specific type inference issue.

Suggested change
{({ pressed }: { pressed: boolean }) => (
{({ pressed }) => (

Copilot uses AI. Check for mistakes.
@callstack-bot
Copy link

Hey @BohdanKhv, thank you for your pull request 🤗. The documentation from this branch can be viewed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants