Skip to content

refactor: inline the Touchable press state machine - #3012

Merged
jakex7 merged 1 commit into
software-mansion:mainfrom
zoontek:remove-touchable-usage
Aug 18, 2026
Merged

jakex7 merged 1 commit into
software-mansion:mainfrom
zoontek:remove-touchable-usage

Conversation

@zoontek

@zoontek zoontek commented Aug 13, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Shape handles presses by mixing in Touchable.Mixin, a private and deprecated API of react-native. react-native cannot delete Touchable while this library uses it.

From packages/react-native/index.js at v0.87.0:

// `Touchable` has been removed from the public API types, but remains
// re-exported at runtime here because of a hanging `react-native-svg` call
// site (fbsource).
// TODO(huntie): Remove this re-export once `react-native-svg` is updated.

How it is implemented

src/lib/SvgTouchableMixin.ts now holds its own copy of the press state machine, ported from Touchable.Mixin. Same states, same signals, same transition table, same method names, so the callers are unchanged. It only depends on the gesture responder system, which is public API.

Two differences with the original implementation:

  • No Android tap sound on press. SoundManager has no public export.
  • Measurement calls measure() on the granted responder node, falling back to the instance root ref, instead of UIManager.measure.

The mixin is also fully typed now, so the // @ts-expect-error: Mixin is not typed is gone.

Areas impacted

Press props on every shape element: onPress, onPressIn, onPressOut, onLongPress, delayPressIn, delayPressOut, delayLongPress, pressRetentionOffset, hitSlop, disabled, and the user supplied onResponder* overrides.

Plus the config needed to type check the new test file:

  • tsconfig.json includes __tests__ and e2e, and lists types explicitly
  • new tsconfig.build.json, narrowed back to src, used by the bob typescript target so test globals never reach the published types
  • devDependency bumps: @types/jest, new @types/react-test-renderer, react-native-builder-bob

Test Plan

What's required for testing (prerequisites)?

yarn install at the repo root, then yarn install in the example app.

What are the steps to reproduce (after prerequisites)?

__tests__/touchable.test.tsx is new. Its 19 cases cover handler attachment, press order, delayPressIn / delayPressOut / delayLongPress, the 500ms long press threshold, long press cancelling onPress, the 10px movement cancel, leaving and re-entering the press rect, the default retention offset, hitSlop, disabled, user supplied responder handlers, termination, and timer cleanup on unmount.

yarn jest __tests__/touchable.test.tsx
yarn lint
yarn tsc

Then check the TouchEvents example screen, which covers onPress on Circle, onLongPress on Rect, onPressIn / onPressOut with delayPressIn={0}, and onPress on G and Text:

cd apps/fabric-example && yarn ios # or yarn android

Compatibility

OS Implemented
iOS ✅
MacOS ✅
Android ✅

The change is JavaScript only and shared by every platform. No native code is touched.

Checklist

  • I have tested this on a device and a simulator
  • I added documentation in README.md
  • I updated the typed files (typescript)
  • I added a test for the API in the __tests__ folder

Demos

demo.ios.mov
demo.android.mov

@jakex7
jakex7 force-pushed the remove-touchable-usage branch from a04b8c4 to c830730 Compare August 14, 2026 15:13

@jakex7 jakex7 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks good to me, thank you! I'll re-introduce Android tap sound on press in a followup PR

@jakex7
jakex7 merged commit 9ff124c into software-mansion:main Aug 18, 2026
2 of 7 checks passed
@jakex7 jakex7 mentioned this pull request Aug 18, 2026
2 tasks done
jakex7 added a commit that referenced this pull request Aug 18, 2026
# Summary

#3012 removed
the tap sound, this PR restores previous behavior by adding
`SvgSoundModule` on Android.
 
## Test Plan

Run TouchEvents test on Android.

## Compatibility

| OS      | Implemented |
| ------- | :---------: |
| Android |    ✅      |

## Checklist

- [x] I have tested this on a device and a simulator
- [x] I updated the typed files (typescript)
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