Skip to content

feat: deliver batched CSS events to JS - #10107

Merged
MatiPl01 merged 4 commits into
mainfrom
@matipl01/css-events-js
Aug 12, 2026
Merged

MatiPl01 merged 4 commits into
mainfrom
@matipl01/css-events-js

Conversation

@MatiPl01

@MatiPl01 MatiPl01 commented Jul 30, 2026 •

Copy link
Copy Markdown
Contributor

The JS half of the CSS events channel: a registry that receives batched events from native and hands each one to the subscribers listening for that view tag, plus the module plumbing that installs the handler.

Subscription is keyed by view tag rather than by object identity, since nested animated components can share a tag. An event can outlive the view it was emitted for, so an event for a tag nobody listens to is dropped.

A batch carries events for unrelated views, so a throwing subscriber is reported through ErrorUtils.reportFatalError rather than left to unwind. The error stays fatal, as an uncaught one would be, without starving the views queued behind it in the same batch.

@coderabbitai

coderabbitai Bot commented Jul 30, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added support for receiving and dispatching CSS animation and transition events.
    • Added event subscription management by view, including registration, removal, and cleanup.
    • Added native event handling integration for supported runtime environments.
  • Bug Fixes

    • Unknown event targets are safely ignored.
    • Errors in event callbacks are reported while allowing other callbacks to continue.

Walkthrough

The PR adds typed CSS animation and transition events, a per-view callback registry, and setCSSEventHandler plumbing through the native Reanimated module. Native initialization dispatches event batches to registered subscribers.

Changes

CSS native event handling

Layer / File(s) Summary
Event contracts and callback registry
packages/react-native-reanimated/src/css/native/events/*, packages/react-native-reanimated/src/css/native/index.ts
Defines CSS event payloads and subscriber contracts. The registry routes events by view tag, handles subscriber errors, and supports cleanup. Tests cover registration, dispatch, errors, mutation during dispatch, and clearing.
Module handler API
packages/react-native-reanimated/src/ReanimatedModule/*, packages/react-native-reanimated/src/css/native/proxy.ts
Adds setCSSEventHandler to the native module, module proxy, CSS proxy, dummy proxy, and JS implementation.
Native event initialization
packages/react-native-reanimated/src/initializers.native.ts
Registers the CSS event handler during native initialization and forwards event batches to cssCallbacksRegistry.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested labels: lib: Reanimated

Suggested reviewers: tjzel

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The description accurately explains the CSS event registry, batched event delivery, subscription behavior, error propagation, and module plumbing.
Title check ✅ Passed The title clearly summarizes the main change: delivering batched CSS events from native code to JavaScript.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch @matipl01/css-events-js

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@MatiPl01 MatiPl01 self-assigned this Jul 30, 2026
@MatiPl01
MatiPl01 force-pushed the @matipl01/css-events-js branch from 75e2154 to e62aee0 Compare July 30, 2026 22:57
@MatiPl01
MatiPl01 force-pushed the @matipl01/css-events-js branch from e62aee0 to 3c2af90 Compare July 31, 2026 06:31
@MatiPl01
MatiPl01 force-pushed the @matipl01/css-events-js branch from 3c2af90 to 97019f6 Compare July 31, 2026 07:07
@MatiPl01
MatiPl01 force-pushed the @matipl01/css-events-js branch from 97019f6 to f5db016 Compare July 31, 2026 07:34
@MatiPl01
MatiPl01 force-pushed the @matipl01/css-events-js branch from f5db016 to 14928e0 Compare July 31, 2026 08:26
@MatiPl01
MatiPl01 force-pushed the @matipl01/css-events-js branch from 14928e0 to 7c24779 Compare July 31, 2026 08:44
@MatiPl01
MatiPl01 force-pushed the @matipl01/css-events-js branch from 7c24779 to 6168b15 Compare July 31, 2026 09:13
@MatiPl01
MatiPl01 force-pushed the @matipl01/css-events-js branch from 6168b15 to 1e77a4b Compare July 31, 2026 09:26
@MatiPl01
MatiPl01 force-pushed the @matipl01/css-events-js branch from 1e77a4b to e0a45db Compare July 31, 2026 09:38
@MatiPl01
MatiPl01 force-pushed the @matipl01/css-events-js branch 5 times, most recently from 017938d to c3f7688 Compare July 31, 2026 12:48
@MatiPl01
MatiPl01 marked this pull request as ready for review July 31, 2026 13:22

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@packages/react-native-reanimated/src/css/native/events/CSSCallbacksRegistry.ts`:
- Around line 46-48: The subscriber callback delivery in the nested event and
subscriber loops exits prematurely when handleCSSEvent throws, preventing later
subscribers and later events from receiving delivery. Wrap the
subscriber.handleCSSEvent(event) call in a try-catch block to capture errors
without exiting the loops. Store only the first caught error in a variable and
continue iterating through all subscribers and events. After both loops
complete, rethrow the captured error if one was encountered. Update the error
test to verify that a later subscriber in the same batch still receives its
event even when an earlier subscriber's handleCSSEvent throws.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 8faeb439-6ff8-4591-b3cd-940826c58af9

📥 Commits

Reviewing files that changed from the base of the PR and between cab405c and 801a7e4.

📒 Files selected for processing (10)
  • packages/react-native-reanimated/src/ReanimatedModule/NativeReanimated.ts
  • packages/react-native-reanimated/src/ReanimatedModule/js-reanimated/JSReanimated.ts
  • packages/react-native-reanimated/src/ReanimatedModule/reanimatedModuleProxy.ts
  • packages/react-native-reanimated/src/css/native/events/CSSCallbacksRegistry.ts
  • packages/react-native-reanimated/src/css/native/events/__tests__/CSSCallbacksRegistry.test.ts
  • packages/react-native-reanimated/src/css/native/events/index.ts
  • packages/react-native-reanimated/src/css/native/events/types.ts
  • packages/react-native-reanimated/src/css/native/index.ts
  • packages/react-native-reanimated/src/css/native/proxy.ts
  • packages/react-native-reanimated/src/initializers.native.ts

@MatiPl01
MatiPl01 force-pushed the @matipl01/css-events-js branch from 355eb14 to df29ca7 Compare August 12, 2026 08:06
@MatiPl01
MatiPl01 force-pushed the @matipl01/css-events-js branch from df29ca7 to d2cc7dd Compare August 12, 2026 08:27
@MatiPl01
MatiPl01 force-pushed the @matipl01/css-events-js branch from d2cc7dd to b573300 Compare August 12, 2026 09:05
@MatiPl01
MatiPl01 force-pushed the @matipl01/css-events-js branch from b573300 to acf660b Compare August 12, 2026 09:33
@MatiPl01
MatiPl01 force-pushed the @matipl01/css-events-js branch from acf660b to b39d059 Compare August 12, 2026 09:37
@MatiPl01
MatiPl01 force-pushed the @matipl01/css-events-js branch from b39d059 to 38ec587 Compare August 12, 2026 11:43
@MatiPl01
MatiPl01 force-pushed the @matipl01/css-events-js branch 2 times, most recently from 91605c5 to 16c9e24 Compare August 12, 2026 13:33
@MatiPl01
MatiPl01 force-pushed the @matipl01/css-events-js branch 2 times, most recently from 2a4478a to ef6b353 Compare August 12, 2026 13:45
Base automatically changed from @matipl01/css-events-cpp to main August 12, 2026 15:01
@MatiPl01
MatiPl01 force-pushed the @matipl01/css-events-js branch from ef6b353 to a90b33b Compare August 12, 2026 15:01
@MatiPl01
MatiPl01 merged commit 7627783 into main Aug 12, 2026
13 checks passed
@MatiPl01
MatiPl01 deleted the @matipl01/css-events-js branch August 12, 2026 15:06
m-bert added a commit to software-mansion/react-native-gesture-handler that referenced this pull request Aug 26, 2026
## Description

Since Reanimated 4.6.0 (software-mansion/react-native-reanimated#10107),
importing `react-native-reanimated` under Jest throws during module
evaluation:

```
    [Reanimated] `setCSSEventHandler` is not available in JSReanimated.
      at initializeReanimatedModule (src/initializers.native.ts:22)
      at Object.<anonymous> (src/index.ts:11)
```

Under `Jest`, `Reanimated` selects its `JSReanimated` module (`IS_JEST`
check in `reanimatedModuleInstance.native.ts`), whose
`setCSSEventHandler` stub throws, and `initializers.native.ts` calls it
unconditionally as an import side effect. Our `reanimatedWrapper`
catches the error and silently falls back to `Reanimated = undefined`.



This PR mocks `reanimatedWrapper` in `Errors.test.tsx` (same pattern as
`runOnJSReanimatedHandlers.test.tsx`), which makes the suite independent
of whether the real Reanimated can be imported under Jest. The mock
additionally provides `useComposedEventHandler`, which
`InterceptingGestureDetector` calls.

## Test plan

- yarn test — 19/19 suites, 159/159 tests pass (Errors.test.tsx was
failing on main before this change)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants