@rootnative/inertia 0.0.0-alpha.3 → 0.0.0-alpha.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/{chunk-S4AEU72O.js → chunk-2HYD2ZBK.js} +2 -2
  3. package/dist/chunk-3UTJJ4A3.js +8 -0
  4. package/dist/{chunk-K7ICHCTZ.js → chunk-4PEHWDAZ.js} +7 -7
  5. package/dist/chunk-4QGXK6TF.js +8 -0
  6. package/dist/{chunk-RJNR7CFN.mjs → chunk-6SMPIOIC.mjs} +1 -1
  7. package/dist/{chunk-JWHKMNYA.js → chunk-7AOERN53.js} +4 -3
  8. package/dist/{chunk-KVSJWO5X.js → chunk-7UDYEFBU.js} +22 -22
  9. package/dist/{chunk-UM3WVSKQ.mjs → chunk-ALRHDFZE.mjs} +1 -1
  10. package/dist/{chunk-KARV7QKF.mjs → chunk-CWLFUYIY.mjs} +1 -1
  11. package/dist/{chunk-6FENLMCA.mjs → chunk-CY7Y64C3.mjs} +17 -1
  12. package/dist/{chunk-UXK4YCT6.mjs → chunk-DWCLIBYO.mjs} +2 -2
  13. package/dist/{chunk-FSPQVLBF.mjs → chunk-JVBXPF2G.mjs} +1 -1
  14. package/dist/{chunk-E4MDU4YV.mjs → chunk-NXDJZD6A.mjs} +1 -1
  15. package/dist/{chunk-SFRNO6AW.js → chunk-PTRF47DA.js} +17 -0
  16. package/dist/{chunk-GJD4VVAS.mjs → chunk-R63GIUNU.mjs} +2 -1
  17. package/dist/{chunk-W6IS4HAK.mjs → chunk-RGNX6UZN.mjs} +2 -2
  18. package/dist/{chunk-5RCMIJGZ.js → chunk-TDSO63CJ.js} +2 -2
  19. package/dist/chunk-Z7HIOFKQ.js +8 -0
  20. package/dist/gestureLayer/index.js +10 -10
  21. package/dist/gestureLayer/index.mjs +3 -3
  22. package/dist/index.d.mts +19 -11
  23. package/dist/index.d.ts +19 -11
  24. package/dist/index.js +52 -44
  25. package/dist/index.mjs +28 -20
  26. package/dist/motion/Image.js +5 -5
  27. package/dist/motion/Image.mjs +4 -4
  28. package/dist/motion/Pressable.js +5 -5
  29. package/dist/motion/Pressable.mjs +4 -4
  30. package/dist/motion/ScrollView.js +5 -5
  31. package/dist/motion/ScrollView.mjs +4 -4
  32. package/dist/motion/Text.js +5 -5
  33. package/dist/motion/Text.mjs +4 -4
  34. package/dist/motion/View.js +5 -5
  35. package/dist/motion/View.mjs +4 -4
  36. package/dist/touch/index.js +3 -3
  37. package/dist/touch/index.mjs +1 -1
  38. package/package.json +2 -2
  39. package/src/gestures/focusVisibility.ts +15 -4
  40. package/src/internal/nonWorkletWarning.ts +41 -0
  41. package/src/layout/resolveLayout.ts +3 -2
  42. package/src/transitions/easing.ts +13 -8
  43. package/src/values/useTransform.ts +28 -12
  44. package/dist/chunk-NJYRN3WG.js +0 -8
  45. package/dist/chunk-R3ODWDTI.js +0 -8
  46. package/dist/chunk-UMFBAFZP.js +0 -8
package/CHANGELOG.md CHANGED
@@ -4,6 +4,22 @@ All notable changes to `@rootnative/inertia` are documented here. The format fol
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ### Changed
8
+
9
+ - **Non-worklet transformers and easings now dev-warn.** `useTransform`'s transformer overload and custom `timing.easing` functions must be worklets (`'worklet'` directive as the first statement). The previous "plain functions are auto-wrapped" promise was unfulfillable: the directive-wrapped fallback closes over the opaque function reference, not the shared values read inside it, so Reanimated cannot extract dependencies (a `useTransform` derived value silently only refreshed on React re-renders — found via a frozen TextField label float in the UI library) and native builds reject the plain function when the closure is serialized to the UI thread. The fallback wrapper remains as a web-only best effort, but both sites now `console.warn` once in dev (suppressed under Jest, where the shared stubs report every function as non-worklet). Docs (`transitions.md`, `layout.md`, `api/hooks.md`) and docstrings corrected to state the real contract.
10
+
11
+ ## [0.0.0-alpha.4] - 2026-07-21
12
+
13
+ ### Fixed
14
+
15
+ - **First mouse click after page load no longer draws a focus ring** (web). The `focusVisibility` input-modality listeners attached lazily on the first `isFocusVisible()` call — which happens _during_ the focus dispatch of that first click, after its `mousedown` had already passed unobserved — leaving the default `'keyboard'` modality and misclassifying the pointer interaction as keyboard focus. The listeners now install eagerly at module import (the lazy path remains as a safety net for environments where `document` appears after import).
16
+
17
+ ## [0.0.0-alpha.3] - 2026-07-21
18
+
19
+ ### Fixed
20
+
21
+ - **Named transitions resolve correctly across subpath entries.** `splitting: false` in the tsup config made every dist entry inline its own copy of `MotionConfigContext`, so the provider (root entry) and consumers (e.g. the `/gesture-layer` subpath) held different React contexts and every registered name silently fell back to the default spring. Dist now builds with code splitting so the context module is shared.
22
+
7
23
  ## [0.0.0-alpha.2] - 2026-07-20
8
24
 
9
25
  ### Added
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var chunkKVSJWO5X_js = require('./chunk-KVSJWO5X.js');
3
+ var chunk7UDYEFBU_js = require('./chunk-7UDYEFBU.js');
4
4
  var reactNative = require('react-native');
5
5
 
6
- var MotionScrollView = chunkKVSJWO5X_js.createMotionComponent(reactNative.ScrollView);
6
+ var MotionScrollView = chunk7UDYEFBU_js.createMotionComponent(reactNative.ScrollView);
7
7
 
8
8
  exports.MotionScrollView = MotionScrollView;
@@ -0,0 +1,8 @@
1
+ 'use strict';
2
+
3
+ var chunk7UDYEFBU_js = require('./chunk-7UDYEFBU.js');
4
+ var reactNative = require('react-native');
5
+
6
+ var MotionImage = chunk7UDYEFBU_js.createMotionComponent(reactNative.Image);
7
+
8
+ exports.MotionImage = MotionImage;
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunkJWHKMNYA_js = require('./chunk-JWHKMNYA.js');
4
- var chunkSFRNO6AW_js = require('./chunk-SFRNO6AW.js');
3
+ var chunk7AOERN53_js = require('./chunk-7AOERN53.js');
4
+ var chunkPTRF47DA_js = require('./chunk-PTRF47DA.js');
5
5
  var react = require('react');
6
6
  var reactNativeReanimated = require('react-native-reanimated');
7
7
 
@@ -10,12 +10,12 @@ function useGesture(transition) {
10
10
  const focused = reactNativeReanimated.useSharedValue(0);
11
11
  const focusVisible = reactNativeReanimated.useSharedValue(0);
12
12
  const hovered = reactNativeReanimated.useSharedValue(0);
13
- const shouldReduceMotion = chunkJWHKMNYA_js.useShouldReduceMotion();
14
- const resolved = chunkJWHKMNYA_js.resolveNamedTransitionProp(transition, chunkJWHKMNYA_js.useNamedTransitions());
13
+ const shouldReduceMotion = chunk7AOERN53_js.useShouldReduceMotion();
14
+ const resolved = chunk7AOERN53_js.resolveNamedTransitionProp(transition, chunk7AOERN53_js.useNamedTransitions());
15
15
  const setLayer = react.useCallback(
16
16
  (sv, layer, target) => {
17
17
  const cfg = shouldReduceMotion ? { type: "no-animation" } : layerTransition(layer, resolved) ?? { type: "spring" };
18
- sv.value = chunkSFRNO6AW_js.resolveTransition(cfg, target);
18
+ sv.value = chunkPTRF47DA_js.resolveTransition(cfg, target);
19
19
  },
20
20
  // The transition is intentionally read on every call rather than cooked
21
21
  // into the dep array — a fresh literal each render would otherwise
@@ -34,7 +34,7 @@ function useGesture(transition) {
34
34
  onHoverOut: () => setLayer(hovered, "hovered", 0),
35
35
  onFocus: () => {
36
36
  setLayer(focused, "focused", 1);
37
- if (chunkJWHKMNYA_js.isFocusVisible()) setLayer(focusVisible, "focusVisible", 1);
37
+ if (chunk7AOERN53_js.isFocusVisible()) setLayer(focusVisible, "focusVisible", 1);
38
38
  },
39
39
  onBlur: () => {
40
40
  setLayer(focused, "focused", 0);
@@ -47,7 +47,7 @@ function useGesture(transition) {
47
47
  }
48
48
  function layerTransition(layer, transition) {
49
49
  if (!transition) return void 0;
50
- if (chunkSFRNO6AW_js.isTopLevelTransition(transition)) return transition;
50
+ if (chunkPTRF47DA_js.isTopLevelTransition(transition)) return transition;
51
51
  return transition[layer];
52
52
  }
53
53
 
@@ -0,0 +1,8 @@
1
+ 'use strict';
2
+
3
+ var chunk7UDYEFBU_js = require('./chunk-7UDYEFBU.js');
4
+ var reactNative = require('react-native');
5
+
6
+ var MotionView = chunk7UDYEFBU_js.createMotionComponent(reactNative.View);
7
+
8
+ exports.MotionView = MotionView;
@@ -1,4 +1,4 @@
1
- import { createMotionComponent } from './chunk-UXK4YCT6.mjs';
1
+ import { createMotionComponent } from './chunk-DWCLIBYO.mjs';
2
2
  import { View } from 'react-native';
3
3
 
4
4
  var MotionView = createMotionComponent(View);
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkSFRNO6AW_js = require('./chunk-SFRNO6AW.js');
3
+ var chunkPTRF47DA_js = require('./chunk-PTRF47DA.js');
4
4
  var react = require('react');
5
5
  var reactNativeReanimated = require('react-native-reanimated');
6
6
  var jsxRuntime = require('react/jsx-runtime');
@@ -32,7 +32,7 @@ function MotionConfig({
32
32
  children
33
33
  }) {
34
34
  const parent = useMotionConfig();
35
- const transitionsSig = chunkSFRNO6AW_js.stableSig(transitions);
35
+ const transitionsSig = chunkPTRF47DA_js.stableSig(transitions);
36
36
  const value = react.useMemo(
37
37
  () => ({
38
38
  reducedMotion: reducedMotion ?? parent.reducedMotion,
@@ -66,7 +66,7 @@ function resolveNamedTransitionProp(transition, registry) {
66
66
  if (typeof transition === "string") {
67
67
  return lookupNamedTransition(transition, registry);
68
68
  }
69
- if (chunkSFRNO6AW_js.isTopLevelTransition(transition)) return transition;
69
+ if (chunkPTRF47DA_js.isTopLevelTransition(transition)) return transition;
70
70
  const map = transition;
71
71
  let out = null;
72
72
  for (const key in map) {
@@ -96,6 +96,7 @@ function ensureInstalled() {
96
96
  document.addEventListener("touchstart", setPointer, true);
97
97
  installed = true;
98
98
  }
99
+ ensureInstalled();
99
100
  function isFocusVisible() {
100
101
  if (reactNative.Platform.OS !== "web") return true;
101
102
  ensureInstalled();
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunkJWHKMNYA_js = require('./chunk-JWHKMNYA.js');
4
- var chunkSFRNO6AW_js = require('./chunk-SFRNO6AW.js');
3
+ var chunk7AOERN53_js = require('./chunk-7AOERN53.js');
4
+ var chunkPTRF47DA_js = require('./chunk-PTRF47DA.js');
5
5
  var react = require('react');
6
6
  var jsxRuntime = require('react/jsx-runtime');
7
7
  var Animated = require('react-native-reanimated');
@@ -111,14 +111,14 @@ function resolveLayoutTransition(layout) {
111
111
  if (cfg.type === "no-animation") return void 0;
112
112
  if (cfg.type === "timing") {
113
113
  let builder2 = Animated.LinearTransition.duration(cfg.duration ?? 300);
114
- const easing = chunkSFRNO6AW_js.ensureWorkletEasing(cfg.easing);
114
+ const easing = chunkPTRF47DA_js.ensureWorkletEasing(cfg.easing);
115
115
  if (easing) builder2 = builder2.easing(easing);
116
116
  if (cfg.delay) builder2 = builder2.delay(cfg.delay);
117
117
  return builder2;
118
118
  }
119
119
  const spring = cfg.type === "decay" ? { type: "spring" } : cfg;
120
- const { stiffness, damping, mass } = chunkSFRNO6AW_js.springToReanimated({
121
- ...chunkSFRNO6AW_js.DEFAULT_SPRING,
120
+ const { stiffness, damping, mass } = chunkPTRF47DA_js.springToReanimated({
121
+ ...chunkPTRF47DA_js.DEFAULT_SPRING,
122
122
  ...spring
123
123
  });
124
124
  let builder = Animated.LinearTransition.springify().stiffness(stiffness).damping(damping).mass(mass);
@@ -257,8 +257,8 @@ function applyFlip(args) {
257
257
  );
258
258
  return;
259
259
  }
260
- const springCfg = transition?.type === "spring" ? { ...chunkSFRNO6AW_js.DEFAULT_SPRING, ...transition } : { type: "spring", ...chunkSFRNO6AW_js.DEFAULT_SPRING };
261
- const springParams = chunkSFRNO6AW_js.springToReanimated(springCfg);
260
+ const springCfg = transition?.type === "spring" ? { ...chunkPTRF47DA_js.DEFAULT_SPRING, ...transition } : { type: "spring", ...chunkPTRF47DA_js.DEFAULT_SPRING };
261
+ const springParams = chunkPTRF47DA_js.springToReanimated(springCfg);
262
262
  dx.value = Animated.withSequence(
263
263
  Animated.withTiming(deltaX, { duration: 0 }),
264
264
  Animated.withSpring(0, springParams)
@@ -379,14 +379,14 @@ var DEFAULT_RESTING = {
379
379
  function transitionFor(prop, transition) {
380
380
  if (!transition) return void 0;
381
381
  if (typeof transition === "string") return void 0;
382
- if (chunkSFRNO6AW_js.isTopLevelTransition(transition)) return transition;
382
+ if (chunkPTRF47DA_js.isTopLevelTransition(transition)) return transition;
383
383
  if (GESTURE_LAYER_NAME_SET.has(prop)) return void 0;
384
384
  return transition[prop];
385
385
  }
386
386
  function gestureLayerTransitionFor(layer, transition) {
387
387
  if (!transition) return void 0;
388
388
  if (typeof transition === "string") return void 0;
389
- if (chunkSFRNO6AW_js.isTopLevelTransition(transition)) return transition;
389
+ if (chunkPTRF47DA_js.isTopLevelTransition(transition)) return transition;
390
390
  return transition[layer];
391
391
  }
392
392
  function createMotionComponent(Component) {
@@ -411,12 +411,12 @@ function createMotionComponent(Component) {
411
411
  onLayout: userOnLayout,
412
412
  ...rest
413
413
  } = props;
414
- const namedTransitions = chunkJWHKMNYA_js.useNamedTransitions();
415
- const transition = chunkJWHKMNYA_js.resolveNamedTransitionProp(
414
+ const namedTransitions = chunk7AOERN53_js.useNamedTransitions();
415
+ const transition = chunk7AOERN53_js.resolveNamedTransitionProp(
416
416
  transitionProp,
417
417
  namedTransitions
418
418
  );
419
- const layout = typeof layoutProp === "string" ? chunkJWHKMNYA_js.lookupNamedTransition(layoutProp, namedTransitions) : layoutProp;
419
+ const layout = typeof layoutProp === "string" ? chunk7AOERN53_js.lookupNamedTransition(layoutProp, namedTransitions) : layoutProp;
420
420
  if (__DEV__ && typeof style === "function") {
421
421
  throw new Error(
422
422
  "[inertia] `style` must be a style object or array of style objects, not a function. The function-form `style={(state) => ...}` Pressable API is not supported \u2014 use `gesture.pressed` (or `gesture.focused`, etc.) to drive state-dependent styling instead."
@@ -424,7 +424,7 @@ function createMotionComponent(Component) {
424
424
  }
425
425
  const presence = usePresence();
426
426
  const isExiting = presence !== null && presence.isPresent === false;
427
- const shouldReduceMotion = chunkJWHKMNYA_js.useShouldReduceMotion();
427
+ const shouldReduceMotion = chunk7AOERN53_js.useShouldReduceMotion();
428
428
  const onAnimationEndRef = react.useRef(onAnimationEnd);
429
429
  onAnimationEndRef.current = onAnimationEnd;
430
430
  const variantKey = useControllerKey(controller);
@@ -509,13 +509,13 @@ function createMotionComponent(Component) {
509
509
  const gestureSV = Animated.useSharedValue(
510
510
  resolveGestureLayers(gesture)
511
511
  );
512
- const gestureTargetsSig = chunkSFRNO6AW_js.stableSig(gesture);
512
+ const gestureTargetsSig = chunkPTRF47DA_js.stableSig(gesture);
513
513
  react.useEffect(() => {
514
514
  gestureSV.value = resolveGestureLayers(gesture);
515
515
  }, [gestureTargetsSig]);
516
516
  const baseRecord = isExiting && exitRecord ? { ...animateRecord, ...exitRecord } : animateRecord;
517
- const baseSig = chunkSFRNO6AW_js.stableSig(baseRecord) + (isExiting ? "|exit" : "") + (shouldReduceMotion ? "|rm" : "");
518
- const transitionSig = chunkSFRNO6AW_js.stableSig(transition);
517
+ const baseSig = chunkPTRF47DA_js.stableSig(baseRecord) + (isExiting ? "|exit" : "") + (shouldReduceMotion ? "|rm" : "");
518
+ const transitionSig = chunkPTRF47DA_js.stableSig(transition);
519
519
  const safeToRemoveRef = react.useRef(void 0);
520
520
  safeToRemoveRef.current = presence?.safeToRemove;
521
521
  react.useEffect(() => {
@@ -563,7 +563,7 @@ function createMotionComponent(Component) {
563
563
  isExiting ? onSettle : void 0,
564
564
  TRANSFORM_KEY_SET.has(key) ? transformGroup : void 0
565
565
  );
566
- sharedValues[key].value = chunkSFRNO6AW_js.resolveAnimatableValue(
566
+ sharedValues[key].value = chunkPTRF47DA_js.resolveAnimatableValue(
567
567
  target,
568
568
  cfg,
569
569
  factory
@@ -612,7 +612,7 @@ function createMotionComponent(Component) {
612
612
  const sharedLayout = useSharedLayout({
613
613
  layoutId,
614
614
  userRef: ref,
615
- transition: chunkSFRNO6AW_js.isTopLevelTransition(transition) ? transition : void 0,
615
+ transition: chunkPTRF47DA_js.isTopLevelTransition(transition) ? transition : void 0,
616
616
  shouldReduceMotion,
617
617
  userOnLayout
618
618
  });
@@ -690,7 +690,7 @@ function createMotionComponent(Component) {
690
690
  setFocusVisible,
691
691
  setHovered
692
692
  );
693
- const layoutSig = chunkSFRNO6AW_js.stableSig(layout);
693
+ const layoutSig = chunkPTRF47DA_js.stableSig(layout);
694
694
  const layoutTransition = react.useMemo(
695
695
  () => shouldReduceMotion ? void 0 : resolveLayoutTransition(layout),
696
696
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -934,7 +934,7 @@ function resolveGestureLayers(gesture) {
934
934
  return out;
935
935
  }
936
936
  function useGestureLayerProgress(progress, active, declared, layer, transition, isExiting, shouldReduceMotion) {
937
- const layerCfgSig = chunkSFRNO6AW_js.stableSig(gestureLayerTransitionFor(layer, transition));
937
+ const layerCfgSig = chunkPTRF47DA_js.stableSig(gestureLayerTransitionFor(layer, transition));
938
938
  react.useEffect(() => {
939
939
  if (!declared) return;
940
940
  if (isExiting) {
@@ -943,7 +943,7 @@ function useGestureLayerProgress(progress, active, declared, layer, transition,
943
943
  }
944
944
  const target = active ? 1 : 0;
945
945
  const cfg = shouldReduceMotion ? { type: "no-animation" } : gestureLayerTransitionFor(layer, transition) ?? { type: "spring" };
946
- progress.value = chunkSFRNO6AW_js.resolveTransition(cfg, target);
946
+ progress.value = chunkPTRF47DA_js.resolveTransition(cfg, target);
947
947
  }, [active, declared, isExiting, shouldReduceMotion, layerCfgSig]);
948
948
  }
949
949
  function useGestureHandlers(gesture, rest, setPressed, setFocused, setFocusVisible, setHovered) {
@@ -967,7 +967,7 @@ function useGestureHandlers(gesture, rest, setPressed, setFocused, setFocusVisib
967
967
  if (gesture.focused || gesture.focusVisible) {
968
968
  handlers.onFocus = compose(rest.onFocus, () => {
969
969
  if (gesture.focused) setFocused(true);
970
- if (gesture.focusVisible && chunkJWHKMNYA_js.isFocusVisible()) setFocusVisible(true);
970
+ if (gesture.focusVisible && chunk7AOERN53_js.isFocusVisible()) setFocusVisible(true);
971
971
  });
972
972
  handlers.onBlur = compose(rest.onBlur, () => {
973
973
  if (gesture.focused) setFocused(false);
@@ -1,4 +1,4 @@
1
- import { createMotionComponent } from './chunk-UXK4YCT6.mjs';
1
+ import { createMotionComponent } from './chunk-DWCLIBYO.mjs';
2
2
  import { Image } from 'react-native';
3
3
 
4
4
  var MotionImage = createMotionComponent(Image);
@@ -1,4 +1,4 @@
1
- import { createMotionComponent } from './chunk-UXK4YCT6.mjs';
1
+ import { createMotionComponent } from './chunk-DWCLIBYO.mjs';
2
2
  import { ScrollView } from 'react-native';
3
3
 
4
4
  var MotionScrollView = createMotionComponent(ScrollView);
@@ -1,11 +1,27 @@
1
1
  import { isWorkletFunction } from 'react-native-worklets';
2
2
  import { withSequence, Easing, withDecay, withTiming, withSpring, withRepeat, withDelay } from 'react-native-reanimated';
3
3
 
4
+ // src/transitions/easing.ts
5
+
6
+ // src/internal/nonWorkletWarning.ts
7
+ var warned = /* @__PURE__ */ new Set();
8
+ function warnNonWorkletOnce(key, message) {
9
+ if (!__DEV__) return;
10
+ if (typeof process !== "undefined" && process.env?.JEST_WORKER_ID) return;
11
+ if (warned.has(key)) return;
12
+ warned.add(key);
13
+ console.warn(message);
14
+ }
15
+
4
16
  // src/transitions/easing.ts
5
17
  function ensureWorkletEasing(easing) {
6
18
  if (!easing) return void 0;
7
19
  const fn = isEasingFactory(easing) ? easing.factory() : easing;
8
20
  if (isWorkletFunction(fn)) return fn;
21
+ warnNonWorkletOnce(
22
+ "timing-easing",
23
+ "[inertia] timing easing: the provided easing function is not a worklet. The fallback wrapper works on web but native builds reject it when the transition runs on the UI thread. Add the 'worklet' directive as the first statement of the easing function, or use Reanimated's Easing.* helpers / inertia's cubicBezier(), which are already worklets."
24
+ );
9
25
  const wrapped = (t) => {
10
26
  "worklet";
11
27
  return fn(t);
@@ -254,4 +270,4 @@ function stableStringify(v) {
254
270
  return "{" + keys.map((k) => JSON.stringify(k) + ":" + stableStringify(obj[k])).join(",") + "}";
255
271
  }
256
272
 
257
- export { DEFAULT_SPRING, buildReleaseAnimation, cubicBezier, ensureWorkletEasing, isTopLevelTransition, resolveAnimatableValue, resolveTransition, springToReanimated, stableSig };
273
+ export { DEFAULT_SPRING, buildReleaseAnimation, cubicBezier, ensureWorkletEasing, isTopLevelTransition, resolveAnimatableValue, resolveTransition, springToReanimated, stableSig, warnNonWorkletOnce };
@@ -1,5 +1,5 @@
1
- import { useNamedTransitions, resolveNamedTransitionProp, lookupNamedTransition, useShouldReduceMotion, isFocusVisible } from './chunk-GJD4VVAS.mjs';
2
- import { stableSig, resolveAnimatableValue, isTopLevelTransition, resolveTransition, ensureWorkletEasing, springToReanimated, DEFAULT_SPRING } from './chunk-6FENLMCA.mjs';
1
+ import { useNamedTransitions, resolveNamedTransitionProp, lookupNamedTransition, useShouldReduceMotion, isFocusVisible } from './chunk-R63GIUNU.mjs';
2
+ import { stableSig, resolveAnimatableValue, isTopLevelTransition, resolveTransition, ensureWorkletEasing, springToReanimated, DEFAULT_SPRING } from './chunk-CY7Y64C3.mjs';
3
3
  import { createContext, useContext, useMemo, Children, isValidElement, useState, useRef, useCallback, forwardRef, useEffect } from 'react';
4
4
  import { jsx, Fragment } from 'react/jsx-runtime';
5
5
  import Animated, { useSharedValue, useAnimatedStyle, interpolateColor, reanimatedVersion, runOnJS, LinearTransition, withSequence, withTiming, withSpring } from 'react-native-reanimated';
@@ -1,4 +1,4 @@
1
- import { createMotionComponent } from './chunk-UXK4YCT6.mjs';
1
+ import { createMotionComponent } from './chunk-DWCLIBYO.mjs';
2
2
  import { Text } from 'react-native';
3
3
 
4
4
  var MotionText = createMotionComponent(Text);
@@ -1,4 +1,4 @@
1
- import { createMotionComponent } from './chunk-UXK4YCT6.mjs';
1
+ import { createMotionComponent } from './chunk-DWCLIBYO.mjs';
2
2
  import { Pressable } from 'react-native';
3
3
 
4
4
  var MotionPressable = createMotionComponent(Pressable);
@@ -3,11 +3,27 @@
3
3
  var reactNativeWorklets = require('react-native-worklets');
4
4
  var reactNativeReanimated = require('react-native-reanimated');
5
5
 
6
+ // src/transitions/easing.ts
7
+
8
+ // src/internal/nonWorkletWarning.ts
9
+ var warned = /* @__PURE__ */ new Set();
10
+ function warnNonWorkletOnce(key, message) {
11
+ if (!__DEV__) return;
12
+ if (typeof process !== "undefined" && process.env?.JEST_WORKER_ID) return;
13
+ if (warned.has(key)) return;
14
+ warned.add(key);
15
+ console.warn(message);
16
+ }
17
+
6
18
  // src/transitions/easing.ts
7
19
  function ensureWorkletEasing(easing) {
8
20
  if (!easing) return void 0;
9
21
  const fn = isEasingFactory(easing) ? easing.factory() : easing;
10
22
  if (reactNativeWorklets.isWorkletFunction(fn)) return fn;
23
+ warnNonWorkletOnce(
24
+ "timing-easing",
25
+ "[inertia] timing easing: the provided easing function is not a worklet. The fallback wrapper works on web but native builds reject it when the transition runs on the UI thread. Add the 'worklet' directive as the first statement of the easing function, or use Reanimated's Easing.* helpers / inertia's cubicBezier(), which are already worklets."
26
+ );
11
27
  const wrapped = (t) => {
12
28
  "worklet";
13
29
  return fn(t);
@@ -265,3 +281,4 @@ exports.resolveAnimatableValue = resolveAnimatableValue;
265
281
  exports.resolveTransition = resolveTransition;
266
282
  exports.springToReanimated = springToReanimated;
267
283
  exports.stableSig = stableSig;
284
+ exports.warnNonWorkletOnce = warnNonWorkletOnce;
@@ -1,4 +1,4 @@
1
- import { stableSig, isTopLevelTransition } from './chunk-6FENLMCA.mjs';
1
+ import { stableSig, isTopLevelTransition } from './chunk-CY7Y64C3.mjs';
2
2
  import { createContext, useContext, useMemo } from 'react';
3
3
  import { useReducedMotion } from 'react-native-reanimated';
4
4
  import { jsx } from 'react/jsx-runtime';
@@ -94,6 +94,7 @@ function ensureInstalled() {
94
94
  document.addEventListener("touchstart", setPointer, true);
95
95
  installed = true;
96
96
  }
97
+ ensureInstalled();
97
98
  function isFocusVisible() {
98
99
  if (Platform.OS !== "web") return true;
99
100
  ensureInstalled();
@@ -1,5 +1,5 @@
1
- import { useShouldReduceMotion, resolveNamedTransitionProp, useNamedTransitions, isFocusVisible } from './chunk-GJD4VVAS.mjs';
2
- import { resolveTransition, isTopLevelTransition } from './chunk-6FENLMCA.mjs';
1
+ import { useShouldReduceMotion, resolveNamedTransitionProp, useNamedTransitions, isFocusVisible } from './chunk-R63GIUNU.mjs';
2
+ import { resolveTransition, isTopLevelTransition } from './chunk-CY7Y64C3.mjs';
3
3
  import { useCallback, useMemo } from 'react';
4
4
  import { useSharedValue } from 'react-native-reanimated';
5
5
 
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var chunkKVSJWO5X_js = require('./chunk-KVSJWO5X.js');
3
+ var chunk7UDYEFBU_js = require('./chunk-7UDYEFBU.js');
4
4
  var reactNative = require('react-native');
5
5
 
6
- var MotionPressable = chunkKVSJWO5X_js.createMotionComponent(reactNative.Pressable);
6
+ var MotionPressable = chunk7UDYEFBU_js.createMotionComponent(reactNative.Pressable);
7
7
 
8
8
  exports.MotionPressable = MotionPressable;
@@ -0,0 +1,8 @@
1
+ 'use strict';
2
+
3
+ var chunk7UDYEFBU_js = require('./chunk-7UDYEFBU.js');
4
+ var reactNative = require('react-native');
5
+
6
+ var MotionText = chunk7UDYEFBU_js.createMotionComponent(reactNative.Text);
7
+
8
+ exports.MotionText = MotionText;
@@ -1,25 +1,25 @@
1
1
  'use strict';
2
2
 
3
- var chunkK7ICHCTZ_js = require('../chunk-K7ICHCTZ.js');
4
- var chunkJWHKMNYA_js = require('../chunk-JWHKMNYA.js');
5
- var chunkSFRNO6AW_js = require('../chunk-SFRNO6AW.js');
3
+ var chunk4PEHWDAZ_js = require('../chunk-4PEHWDAZ.js');
4
+ var chunk7AOERN53_js = require('../chunk-7AOERN53.js');
5
+ var chunkPTRF47DA_js = require('../chunk-PTRF47DA.js');
6
6
  var react = require('react');
7
7
  var reactNativeReanimated = require('react-native-reanimated');
8
8
 
9
9
  function useGestureLayer(states, options = {}) {
10
10
  const { disabled: isDisabled = false, transition: transitionInput } = options;
11
- const shouldReduceMotion = chunkJWHKMNYA_js.useShouldReduceMotion();
12
- const transition = chunkJWHKMNYA_js.resolveNamedTransitionProp(
11
+ const shouldReduceMotion = chunk7AOERN53_js.useShouldReduceMotion();
12
+ const transition = chunk7AOERN53_js.resolveNamedTransitionProp(
13
13
  transitionInput,
14
- chunkJWHKMNYA_js.useNamedTransitions()
14
+ chunk7AOERN53_js.useNamedTransitions()
15
15
  );
16
- const gesture = chunkK7ICHCTZ_js.useGesture(transition);
16
+ const gesture = chunk4PEHWDAZ_js.useGesture(transition);
17
17
  const disabledProgress = reactNativeReanimated.useSharedValue(0);
18
- const transitionSig = chunkSFRNO6AW_js.stableSig(transition);
18
+ const transitionSig = chunkPTRF47DA_js.stableSig(transition);
19
19
  react.useEffect(() => {
20
20
  const target = isDisabled ? 1 : 0;
21
21
  const cfg = shouldReduceMotion ? { type: "no-animation" } : disabledTransition(transition) ?? { type: "spring" };
22
- disabledProgress.value = chunkSFRNO6AW_js.resolveTransition(cfg, target);
22
+ disabledProgress.value = chunkPTRF47DA_js.resolveTransition(cfg, target);
23
23
  }, [isDisabled, shouldReduceMotion, transitionSig, disabledProgress]);
24
24
  const meta = react.useMemo(() => {
25
25
  const layers = {
@@ -154,7 +154,7 @@ function useGestureLayer(states, options = {}) {
154
154
  }
155
155
  function disabledTransition(transition) {
156
156
  if (!transition) return void 0;
157
- if (chunkSFRNO6AW_js.isTopLevelTransition(transition)) return transition;
157
+ if (chunkPTRF47DA_js.isTopLevelTransition(transition)) return transition;
158
158
  return void 0;
159
159
  }
160
160
 
@@ -1,6 +1,6 @@
1
- import { useGesture } from '../chunk-W6IS4HAK.mjs';
2
- import { useShouldReduceMotion, resolveNamedTransitionProp, useNamedTransitions } from '../chunk-GJD4VVAS.mjs';
3
- import { stableSig, resolveTransition, isTopLevelTransition } from '../chunk-6FENLMCA.mjs';
1
+ import { useGesture } from '../chunk-RGNX6UZN.mjs';
2
+ import { useShouldReduceMotion, resolveNamedTransitionProp, useNamedTransitions } from '../chunk-R63GIUNU.mjs';
3
+ import { stableSig, resolveTransition, isTopLevelTransition } from '../chunk-CY7Y64C3.mjs';
4
4
  import { useEffect, useMemo } from 'react';
5
5
  import { useSharedValue, useAnimatedStyle, interpolateColor } from 'react-native-reanimated';
6
6
 
package/dist/index.d.mts CHANGED
@@ -250,15 +250,15 @@ declare function cubicBezier(css: string): EasingInput;
250
250
  /**
251
251
  * Reanimated 3.9+ validates that easing functions used in nested-transition
252
252
  * contexts (variants, sequences, per-property maps) are worklets, and crashes
253
- * with `[Reanimated] The easing function is not a worklet` otherwise. The
254
- * library accepts plain functions on the public surface; this helper wraps
255
- * them so consumers don't have to think about the worklet boundary.
253
+ * with `[Reanimated] The easing function is not a worklet` otherwise.
256
254
  *
257
- * If the input is already a worklet (has been processed by the worklets babel
258
- * plugin), it's returned as-is. Otherwise it's wrapped in a function whose
259
- * body declares the `'worklet'` directive when our source is processed by
260
- * the consumer's worklets babel plugin (the default Expo/RN setup), the
261
- * wrapper becomes a real worklet that captures the user fn via closure.
255
+ * Custom easing functions MUST therefore be worklets put the `'worklet'`
256
+ * directive as the function's first statement (Reanimated's built-in
257
+ * `Easing.*` helpers and inertia's `cubicBezier()` already are). A plain
258
+ * function warns in dev and falls back to a directive-wrapped call-through;
259
+ * that wrapper works on web (single-threaded) but its closure holds the
260
+ * opaque plain function, which native builds reject when the transition's
261
+ * config is serialized to the UI thread.
262
262
  *
263
263
  * Reanimated 4 changed `Easing.bezier(...)` to return an
264
264
  * `EasingFunctionFactory` (`{ factory: () => EasingFunction }`) rather than
@@ -479,9 +479,17 @@ interface UseTransformOptions {
479
479
  * const distance = useTransform(() => Math.sqrt(x.value ** 2 + y.value ** 2))
480
480
  * ```
481
481
  *
482
- * The transformer must be a worklet (or a plain function we auto-wrap
483
- * see the easing wrapper for the rationale). It runs on the UI thread on
484
- * every frame where any read shared value changes.
482
+ * The transformer MUST be a worklet put the `'worklet'` directive as its
483
+ * first statement so the consumer's Babel plugin captures the shared values
484
+ * it reads as its closure. It runs on the UI thread on every frame where
485
+ * any read shared value changes.
486
+ *
487
+ * A plain function cannot work here, and the hook warns in dev when it gets
488
+ * one: the best-effort wrapper it falls back to closes over the opaque
489
+ * function reference, not the shared values read inside it, so Reanimated
490
+ * can't track them as dependencies — the derived value only refreshes on
491
+ * React re-renders, and native builds reject the plain function when the
492
+ * closure crosses to the UI thread.
485
493
  */
486
494
  declare function useTransform<T>(transformer: () => T): SharedValue<T>;
487
495
  /**
package/dist/index.d.ts CHANGED
@@ -250,15 +250,15 @@ declare function cubicBezier(css: string): EasingInput;
250
250
  /**
251
251
  * Reanimated 3.9+ validates that easing functions used in nested-transition
252
252
  * contexts (variants, sequences, per-property maps) are worklets, and crashes
253
- * with `[Reanimated] The easing function is not a worklet` otherwise. The
254
- * library accepts plain functions on the public surface; this helper wraps
255
- * them so consumers don't have to think about the worklet boundary.
253
+ * with `[Reanimated] The easing function is not a worklet` otherwise.
256
254
  *
257
- * If the input is already a worklet (has been processed by the worklets babel
258
- * plugin), it's returned as-is. Otherwise it's wrapped in a function whose
259
- * body declares the `'worklet'` directive when our source is processed by
260
- * the consumer's worklets babel plugin (the default Expo/RN setup), the
261
- * wrapper becomes a real worklet that captures the user fn via closure.
255
+ * Custom easing functions MUST therefore be worklets put the `'worklet'`
256
+ * directive as the function's first statement (Reanimated's built-in
257
+ * `Easing.*` helpers and inertia's `cubicBezier()` already are). A plain
258
+ * function warns in dev and falls back to a directive-wrapped call-through;
259
+ * that wrapper works on web (single-threaded) but its closure holds the
260
+ * opaque plain function, which native builds reject when the transition's
261
+ * config is serialized to the UI thread.
262
262
  *
263
263
  * Reanimated 4 changed `Easing.bezier(...)` to return an
264
264
  * `EasingFunctionFactory` (`{ factory: () => EasingFunction }`) rather than
@@ -479,9 +479,17 @@ interface UseTransformOptions {
479
479
  * const distance = useTransform(() => Math.sqrt(x.value ** 2 + y.value ** 2))
480
480
  * ```
481
481
  *
482
- * The transformer must be a worklet (or a plain function we auto-wrap
483
- * see the easing wrapper for the rationale). It runs on the UI thread on
484
- * every frame where any read shared value changes.
482
+ * The transformer MUST be a worklet put the `'worklet'` directive as its
483
+ * first statement so the consumer's Babel plugin captures the shared values
484
+ * it reads as its closure. It runs on the UI thread on every frame where
485
+ * any read shared value changes.
486
+ *
487
+ * A plain function cannot work here, and the hook warns in dev when it gets
488
+ * one: the best-effort wrapper it falls back to closes over the opaque
489
+ * function reference, not the shared values read inside it, so Reanimated
490
+ * can't track them as dependencies — the derived value only refreshes on
491
+ * React re-renders, and native builds reject the plain function when the
492
+ * closure crosses to the UI thread.
485
493
  */
486
494
  declare function useTransform<T>(transformer: () => T): SharedValue<T>;
487
495
  /**