@rootnative/inertia 0.0.8 → 0.0.10

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 (101) hide show
  1. package/CHANGELOG.md +81 -1
  2. package/README.md +7 -7
  3. package/dist/applyBounds-BYGiHrYO.d.mts +18 -0
  4. package/dist/applyBounds-BYGiHrYO.d.ts +18 -0
  5. package/dist/{chunk-E3ALFSH2.js → chunk-2UGWAB6N.js} +78 -70
  6. package/dist/{chunk-ZBHQPVWE.js → chunk-3ZNHPT5Z.js} +2 -2
  7. package/dist/{chunk-IHVMNOS4.js → chunk-46766TBM.js} +2 -2
  8. package/dist/{chunk-MUT6BTZS.js → chunk-4EZ5DBL3.js} +10 -7
  9. package/dist/{chunk-MFAFB4K7.mjs → chunk-6FCATUMY.mjs} +8 -10
  10. package/dist/{chunk-6YIUETBF.mjs → chunk-7BH3CAO5.mjs} +1 -1
  11. package/dist/{chunk-JBK5ZLMH.mjs → chunk-CUHOCONB.mjs} +1 -1
  12. package/dist/{chunk-M4766VUV.mjs → chunk-DRA2K53O.mjs} +1 -1
  13. package/dist/{chunk-L4JFECXU.mjs → chunk-F4HMCXAX.mjs} +6 -3
  14. package/dist/{chunk-W7NTRSPD.mjs → chunk-HEAWMZEM.mjs} +105 -66
  15. package/dist/{chunk-IX6SEOSK.mjs → chunk-JENYDTXH.mjs} +52 -44
  16. package/dist/chunk-KFHZMFAX.js +23 -0
  17. package/dist/{chunk-6AN5X3YE.js → chunk-KXU6VH2Y.js} +10 -11
  18. package/dist/{chunk-WNVHPMBI.js → chunk-N33GSDNQ.js} +106 -65
  19. package/dist/chunk-OH46TGEA.mjs +20 -0
  20. package/dist/{chunk-QNLSCOR5.mjs → chunk-OLOSU2BD.mjs} +1 -1
  21. package/dist/chunk-PLKXCJIB.js +8 -0
  22. package/dist/{chunk-GSUC4HWP.mjs → chunk-QXKPIENP.mjs} +1 -1
  23. package/dist/chunk-UBHQJFUW.js +8 -0
  24. package/dist/{chunk-6NOCY764.js → chunk-VKXSL3ZL.js} +2 -2
  25. package/dist/chunk-XKNEQDAT.js +8 -0
  26. package/dist/{chunk-EN4PN7X3.mjs → chunk-Z23AMUSW.mjs} +1 -1
  27. package/dist/gestureLayer/index.d.mts +3 -3
  28. package/dist/gestureLayer/index.d.ts +3 -3
  29. package/dist/gestureLayer/index.js +12 -18
  30. package/dist/gestureLayer/index.mjs +5 -11
  31. package/dist/index.d.mts +105 -47
  32. package/dist/index.d.ts +105 -47
  33. package/dist/index.js +119 -92
  34. package/dist/index.mjs +71 -60
  35. package/dist/motion/FlatList.d.mts +1 -1
  36. package/dist/motion/FlatList.d.ts +1 -1
  37. package/dist/motion/FlatList.js +5 -5
  38. package/dist/motion/FlatList.mjs +4 -4
  39. package/dist/motion/Image.d.mts +1 -1
  40. package/dist/motion/Image.d.ts +1 -1
  41. package/dist/motion/Image.js +5 -5
  42. package/dist/motion/Image.mjs +4 -4
  43. package/dist/motion/Pressable.d.mts +1 -1
  44. package/dist/motion/Pressable.d.ts +1 -1
  45. package/dist/motion/Pressable.js +5 -5
  46. package/dist/motion/Pressable.mjs +4 -4
  47. package/dist/motion/ScrollView.d.mts +1 -1
  48. package/dist/motion/ScrollView.d.ts +1 -1
  49. package/dist/motion/ScrollView.js +5 -5
  50. package/dist/motion/ScrollView.mjs +4 -4
  51. package/dist/motion/Text.d.mts +1 -1
  52. package/dist/motion/Text.d.ts +1 -1
  53. package/dist/motion/Text.js +5 -5
  54. package/dist/motion/Text.mjs +4 -4
  55. package/dist/motion/View.d.mts +1 -1
  56. package/dist/motion/View.d.ts +1 -1
  57. package/dist/motion/View.js +5 -5
  58. package/dist/motion/View.mjs +4 -4
  59. package/dist/touch/index.d.mts +2 -1
  60. package/dist/touch/index.d.ts +2 -1
  61. package/dist/touch/index.js +16 -31
  62. package/dist/touch/index.mjs +11 -29
  63. package/dist/{types-DyJpG64F.d.mts → types-08mG8fNk.d.mts} +10 -3
  64. package/dist/{types-DyJpG64F.d.ts → types-08mG8fNk.d.ts} +10 -3
  65. package/dist/{useGesture-DbH46EBp.d.ts → useGesture-D1lHeQQ6.d.ts} +1 -1
  66. package/dist/{useGesture-CnZQnYHH.d.mts → useGesture-DjszaHWz.d.mts} +1 -1
  67. package/llms.txt +1 -1
  68. package/package.json +4 -2
  69. package/src/config/namedTransitions.ts +7 -9
  70. package/src/gestureLayer/index.ts +3 -0
  71. package/src/gestureLayer/useGestureLayer.ts +6 -9
  72. package/src/gestures/focusVisibility.ts +19 -17
  73. package/src/gestures/index.ts +1 -1
  74. package/src/index.ts +10 -0
  75. package/src/layout/resolveLayout.ts +4 -1
  76. package/src/layout/useSharedLayout.ts +2 -1
  77. package/src/motion/createMotionComponent.tsx +92 -44
  78. package/src/presence/Presence.tsx +5 -7
  79. package/src/touch/applyBounds.ts +30 -0
  80. package/src/touch/index.ts +1 -0
  81. package/src/touch/useTouchDrag.ts +15 -45
  82. package/src/transitions/constants.ts +14 -0
  83. package/src/transitions/easing.ts +23 -11
  84. package/src/transitions/index.ts +5 -0
  85. package/src/transitions/keys.ts +0 -2
  86. package/src/transitions/resolve.ts +86 -11
  87. package/src/transitions/resolveSequence.ts +3 -1
  88. package/src/transitions/runtime.ts +4 -7
  89. package/src/transitions/spring.ts +7 -2
  90. package/src/types.ts +9 -2
  91. package/src/values/extrapolation.ts +21 -0
  92. package/src/values/index.ts +2 -0
  93. package/src/values/useGesture.ts +9 -2
  94. package/src/values/useInterpolatedStyle.ts +42 -19
  95. package/src/values/useShadow.ts +18 -7
  96. package/src/values/useSpring.ts +34 -25
  97. package/src/values/useTransform.ts +24 -20
  98. package/src/values/useTranslateStyle.ts +31 -0
  99. package/dist/chunk-24NUL23E.js +0 -8
  100. package/dist/chunk-4XBX7KOD.js +0 -8
  101. package/dist/chunk-Z5USXWTE.js +0 -8
@@ -1,4 +1,4 @@
1
- import { stableSig, isTopLevelTransition } from './chunk-W7NTRSPD.mjs';
1
+ import { stableSig, warnOnce, isTopLevelTransition } from './chunk-HEAWMZEM.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';
@@ -47,11 +47,10 @@ var UNKNOWN_NAME_FALLBACK = { type: "spring" };
47
47
  function lookupNamedTransition(name, registry) {
48
48
  const cfg = registry[name];
49
49
  if (cfg) return cfg;
50
- if (__DEV__) {
51
- console.warn(
52
- `[inertia] Unknown transition name "${name}" \u2014 falling back to the default spring. Register it on a provider: <MotionConfig transitions={{ '${name}': { ... } }}>.`
53
- );
54
- }
50
+ warnOnce(
51
+ `unknown-transition:${name}`,
52
+ `[inertia] Unknown transition name "${name}" \u2014 falling back to the default spring. Register it on a provider: <MotionConfig transitions={{ '${name}': { ... } }}>.`
53
+ );
55
54
  return UNKNOWN_NAME_FALLBACK;
56
55
  }
57
56
  function resolveNamedTransition(input, registry) {
@@ -84,7 +83,7 @@ function setKeyboard() {
84
83
  function setPointer() {
85
84
  modality = "pointer";
86
85
  }
87
- function ensureInstalled() {
86
+ function installFocusVisibility() {
88
87
  if (installed) return;
89
88
  if (Platform.OS !== "web") return;
90
89
  if (typeof document === "undefined") return;
@@ -94,11 +93,10 @@ function ensureInstalled() {
94
93
  document.addEventListener("touchstart", setPointer, true);
95
94
  installed = true;
96
95
  }
97
- ensureInstalled();
98
96
  function isFocusVisible() {
99
97
  if (Platform.OS !== "web") return true;
100
- ensureInstalled();
98
+ installFocusVisibility();
101
99
  return modality === "keyboard";
102
100
  }
103
101
 
104
- export { MotionConfig, isFocusVisible, lookupNamedTransition, resolveNamedTransition, resolveNamedTransitionProp, useMotionConfig, useNamedTransitions, useShouldReduceMotion };
102
+ export { MotionConfig, installFocusVisibility, isFocusVisible, lookupNamedTransition, resolveNamedTransition, resolveNamedTransitionProp, useMotionConfig, useNamedTransitions, useShouldReduceMotion };
@@ -1,4 +1,4 @@
1
- import { createMotionComponent } from './chunk-IX6SEOSK.mjs';
1
+ import { createMotionComponent } from './chunk-JENYDTXH.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-IX6SEOSK.mjs';
1
+ import { createMotionComponent } from './chunk-JENYDTXH.mjs';
2
2
  import { Pressable } from 'react-native';
3
3
 
4
4
  var MotionPressable = createMotionComponent(Pressable);
@@ -1,4 +1,4 @@
1
- import { createMotionComponent } from './chunk-IX6SEOSK.mjs';
1
+ import { createMotionComponent } from './chunk-JENYDTXH.mjs';
2
2
  import { ScrollView } from 'react-native';
3
3
 
4
4
  var MotionScrollView = createMotionComponent(ScrollView);
@@ -1,6 +1,6 @@
1
- import { useShouldReduceMotion, resolveNamedTransitionProp, useNamedTransitions, isFocusVisible } from './chunk-MFAFB4K7.mjs';
2
- import { resolveTransition, isTopLevelTransition } from './chunk-W7NTRSPD.mjs';
3
- import { useCallback, useMemo } from 'react';
1
+ import { useShouldReduceMotion, resolveNamedTransitionProp, useNamedTransitions, installFocusVisibility, isFocusVisible } from './chunk-6FCATUMY.mjs';
2
+ import { resolveTransition, isTopLevelTransition } from './chunk-HEAWMZEM.mjs';
3
+ import { useEffect, useCallback, useMemo } from 'react';
4
4
  import { useSharedValue } from 'react-native-reanimated';
5
5
 
6
6
  function useGesture(transition) {
@@ -10,6 +10,9 @@ function useGesture(transition) {
10
10
  const hovered = useSharedValue(0);
11
11
  const shouldReduceMotion = useShouldReduceMotion();
12
12
  const resolved = resolveNamedTransitionProp(transition, useNamedTransitions());
13
+ useEffect(() => {
14
+ installFocusVisibility();
15
+ }, []);
13
16
  const setLayer = useCallback(
14
17
  (sv, layer, target) => {
15
18
  const cfg = shouldReduceMotion ? { type: "no-animation" } : layerTransition(layer, resolved) ?? { type: "spring" };
@@ -1,7 +1,48 @@
1
1
  import { isWorkletFunction } from 'react-native-worklets';
2
2
  import { withDelay, withSequence, Easing, withDecay, withTiming, withSpring, withRepeat } from 'react-native-reanimated';
3
3
 
4
- // src/transitions/easing.ts
4
+ // src/transitions/sig.ts
5
+ function stableSig(value) {
6
+ if (value === void 0) return "";
7
+ try {
8
+ return stableStringify(value);
9
+ } catch {
10
+ return String(value);
11
+ }
12
+ }
13
+ function stableStringify(v) {
14
+ if (v === null || typeof v !== "object") {
15
+ if (typeof v === "function" || v === void 0) return "null";
16
+ return JSON.stringify(v);
17
+ }
18
+ if (Array.isArray(v)) {
19
+ return "[" + v.map(stableStringify).join(",") + "]";
20
+ }
21
+ const obj = v;
22
+ const keys = Object.keys(obj).sort();
23
+ return "{" + keys.map((k) => JSON.stringify(k) + ":" + stableStringify(obj[k])).join(",") + "}";
24
+ }
25
+
26
+ // src/transitions/keys.ts
27
+ var TRANSITION_CONFIG_KEYS = /* @__PURE__ */ new Set([
28
+ "type",
29
+ "tension",
30
+ "friction",
31
+ "mass",
32
+ "velocity",
33
+ "duration",
34
+ "easing",
35
+ "delay",
36
+ "repeat",
37
+ "deceleration",
38
+ "clamp"
39
+ ]);
40
+ function isTopLevelTransition(t) {
41
+ if (t === null || typeof t !== "object") return false;
42
+ const keys = Object.keys(t);
43
+ if (keys.length === 0) return false;
44
+ return keys.every((k) => TRANSITION_CONFIG_KEYS.has(k));
45
+ }
5
46
 
6
47
  // src/internal/warnOnce.ts
7
48
  var warned = /* @__PURE__ */ new Set();
@@ -22,7 +63,7 @@ function warnNonWorkletOnce(key, message) {
22
63
  // src/transitions/easing.ts
23
64
  function ensureWorkletEasing(easing) {
24
65
  if (!easing) return void 0;
25
- const fn = isEasingFactory(easing) ? easing.factory() : easing;
66
+ const fn = unwrapEasingFactory(easing);
26
67
  if (isWorkletFunction(fn)) return fn;
27
68
  warnNonWorkletOnce(
28
69
  "timing-easing",
@@ -34,10 +75,18 @@ function ensureWorkletEasing(easing) {
34
75
  };
35
76
  return wrapped;
36
77
  }
37
- function isEasingFactory(value) {
38
- return typeof value === "object" && value !== null && "factory" in value && typeof value.factory === "function";
78
+ function unwrapEasingFactory(easing) {
79
+ "worklet";
80
+ if (typeof easing === "object" && easing !== null && "factory" in easing && typeof easing.factory === "function") {
81
+ return easing.factory();
82
+ }
83
+ return easing;
39
84
  }
40
85
 
86
+ // src/transitions/constants.ts
87
+ var DEFAULT_TIMING_DURATION = 250;
88
+ var DEFAULT_LAYOUT_DURATION = 300;
89
+
41
90
  // src/transitions/spring.ts
42
91
  var DEFAULT_SPRING = {
43
92
  tension: 170,
@@ -50,14 +99,11 @@ function springToReanimated(t) {
50
99
  stiffness: t.tension ?? DEFAULT_SPRING.tension,
51
100
  damping: t.friction ?? DEFAULT_SPRING.friction,
52
101
  mass: t.mass ?? DEFAULT_SPRING.mass,
53
- velocity: t.velocity,
54
- restSpeedThreshold: t.restSpeedThreshold,
55
- restDisplacementThreshold: t.restDisplacementThreshold
102
+ velocity: t.velocity
56
103
  };
57
104
  }
58
105
 
59
106
  // src/transitions/resolve.ts
60
- var DEFAULT_TIMING_DURATION = 250;
61
107
  function buildSpring(cfg, toValue, cb) {
62
108
  return withSpring(toValue, springToReanimated(cfg), cb);
63
109
  }
@@ -90,17 +136,54 @@ function buildOne(cfg, toValue, cb) {
90
136
  if (cfg.type === "timing") return buildTiming(cfg, toValue, cb);
91
137
  return buildSpring(cfg, toValue, cb);
92
138
  }
93
- function applyRepeat(animation, repeat) {
94
- if (repeat === void 0) return animation;
139
+ function normalizeRepeat(repeat) {
140
+ if (repeat === void 0) return void 0;
95
141
  if (repeat === "infinite") {
96
- return withRepeat(animation, -1, true);
142
+ return {
143
+ count: Number.POSITIVE_INFINITY,
144
+ alternate: true,
145
+ explicitAlternate: false
146
+ };
147
+ }
148
+ const rawCount = typeof repeat === "number" ? repeat : repeat.count;
149
+ const alternate = typeof repeat === "number" ? true : repeat.alternate;
150
+ if (rawCount === "infinite") {
151
+ return {
152
+ count: Number.POSITIVE_INFINITY,
153
+ alternate: alternate ?? true,
154
+ explicitAlternate: alternate !== void 0
155
+ };
156
+ }
157
+ if (!(rawCount >= 1)) {
158
+ warnOnce(
159
+ `repeat-count:${String(rawCount)}`,
160
+ `[inertia] repeat count ${String(rawCount)} is below 1 \u2014 the animation runs once. Use \`repeat: 2\` or more to repeat, or \`repeat: 'infinite'\`. (Reanimated reads a count of 0 as endless, so it is not forwarded.)`
161
+ );
162
+ return void 0;
97
163
  }
98
- if (typeof repeat === "number") {
99
- return withRepeat(animation, repeat, true);
164
+ return {
165
+ count: rawCount,
166
+ alternate: alternate ?? true,
167
+ explicitAlternate: alternate !== void 0
168
+ };
169
+ }
170
+ function repeatIterationsOf(repeat) {
171
+ return normalizeRepeat(repeat)?.count ?? 1;
172
+ }
173
+ function applyRepeat(animation, repeat, options) {
174
+ const r = normalizeRepeat(repeat);
175
+ if (r === void 0) return animation;
176
+ const count = Number.isFinite(r.count) ? r.count : -1;
177
+ if (options?.sequence) {
178
+ if (r.explicitAlternate && r.alternate) {
179
+ warnOnce(
180
+ "repeat-sequence-alternate",
181
+ "[inertia] repeat.alternate has no effect on a sequence \u2014 Reanimated restarts a sequence at its first step on every pass. Append the reverse steps to the sequence to alternate."
182
+ );
183
+ }
184
+ return withRepeat(animation, count, false);
100
185
  }
101
- const count = repeat.count === "infinite" ? -1 : repeat.count;
102
- const alternate = repeat.alternate ?? true;
103
- return withRepeat(animation, count, alternate);
186
+ return withRepeat(animation, count, r.alternate);
104
187
  }
105
188
  function applyDelay(animation, delay) {
106
189
  if (!delay || delay <= 0) return animation;
@@ -139,7 +222,9 @@ function resolveAnimatableValue(value, base, factory) {
139
222
  (step2, i) => resolveStep(step2, stepBase, factory?.("step", i))
140
223
  );
141
224
  const seq = withSequence(...animations);
142
- return applyRepeat(seq, base ? repeatOf(base) : void 0);
225
+ return applyRepeat(seq, base ? repeatOf(base) : void 0, {
226
+ sequence: true
227
+ });
143
228
  }
144
229
  const step = value;
145
230
  const cb = factory?.("animation", void 0);
@@ -209,7 +294,6 @@ function bezier(x1, y1, x2, y2, source) {
209
294
  }
210
295
  return Easing.bezier(x1, y1, x2, y2);
211
296
  }
212
- var DEFAULT_TIMING_DURATION2 = 250;
213
297
  function buildReleaseAnimation(transition, toValue, callback) {
214
298
  "worklet";
215
299
  if (transition.type === "no-animation") {
@@ -226,11 +310,11 @@ function buildReleaseAnimation(transition, toValue, callback) {
226
310
  }
227
311
  if (transition.type === "timing") {
228
312
  const e = transition.easing;
229
- const easingFn = e && typeof e === "object" && "factory" in e ? e.factory() : e ?? Easing.inOut(Easing.ease);
313
+ const easingFn = e ? unwrapEasingFactory(e) : Easing.inOut(Easing.ease);
230
314
  return withTiming(
231
315
  toValue,
232
316
  {
233
- duration: transition.duration ?? DEFAULT_TIMING_DURATION2,
317
+ duration: transition.duration ?? DEFAULT_TIMING_DURATION,
234
318
  easing: easingFn
235
319
  },
236
320
  callback
@@ -239,49 +323,4 @@ function buildReleaseAnimation(transition, toValue, callback) {
239
323
  return withSpring(toValue, springToReanimated(transition), callback);
240
324
  }
241
325
 
242
- // src/transitions/keys.ts
243
- var TRANSITION_CONFIG_KEYS = /* @__PURE__ */ new Set([
244
- "type",
245
- "tension",
246
- "friction",
247
- "mass",
248
- "velocity",
249
- "restSpeedThreshold",
250
- "restDisplacementThreshold",
251
- "duration",
252
- "easing",
253
- "delay",
254
- "repeat",
255
- "deceleration",
256
- "clamp"
257
- ]);
258
- function isTopLevelTransition(t) {
259
- if (t === null || typeof t !== "object") return false;
260
- const keys = Object.keys(t);
261
- if (keys.length === 0) return false;
262
- return keys.every((k) => TRANSITION_CONFIG_KEYS.has(k));
263
- }
264
-
265
- // src/transitions/sig.ts
266
- function stableSig(value) {
267
- if (value === void 0) return "";
268
- try {
269
- return stableStringify(value);
270
- } catch {
271
- return String(value);
272
- }
273
- }
274
- function stableStringify(v) {
275
- if (v === null || typeof v !== "object") {
276
- if (typeof v === "function" || v === void 0) return "null";
277
- return JSON.stringify(v);
278
- }
279
- if (Array.isArray(v)) {
280
- return "[" + v.map(stableStringify).join(",") + "]";
281
- }
282
- const obj = v;
283
- const keys = Object.keys(obj).sort();
284
- return "{" + keys.map((k) => JSON.stringify(k) + ":" + stableStringify(obj[k])).join(",") + "}";
285
- }
286
-
287
- export { DEFAULT_SPRING, applyDelay, buildReleaseAnimation, cubicBezier, ensureWorkletEasing, isTopLevelTransition, resolveAnimatableValue, resolveTransition, springToReanimated, stableSig, warnNonWorkletOnce, warnOnce };
326
+ export { DEFAULT_LAYOUT_DURATION, DEFAULT_SPRING, applyDelay, buildReleaseAnimation, cubicBezier, ensureWorkletEasing, isTopLevelTransition, repeatIterationsOf, resolveAnimatableValue, resolveTransition, springToReanimated, stableSig, warnNonWorkletOnce, warnOnce };
@@ -1,5 +1,5 @@
1
- import { useNamedTransitions, resolveNamedTransitionProp, lookupNamedTransition, useShouldReduceMotion, isFocusVisible } from './chunk-MFAFB4K7.mjs';
2
- import { warnOnce, stableSig, applyDelay, resolveAnimatableValue, isTopLevelTransition, resolveTransition, ensureWorkletEasing, springToReanimated, DEFAULT_SPRING } from './chunk-W7NTRSPD.mjs';
1
+ import { useNamedTransitions, resolveNamedTransitionProp, lookupNamedTransition, useShouldReduceMotion, installFocusVisibility, isFocusVisible } from './chunk-6FCATUMY.mjs';
2
+ import { warnOnce, stableSig, applyDelay, resolveAnimatableValue, isTopLevelTransition, resolveTransition, repeatIterationsOf, DEFAULT_LAYOUT_DURATION, ensureWorkletEasing, springToReanimated, DEFAULT_SPRING } from './chunk-HEAWMZEM.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, cancelAnimation, useAnimatedStyle, interpolateColor, reanimatedVersion, runOnJS, LinearTransition, withSequence, withTiming, withSpring } from 'react-native-reanimated';
@@ -39,11 +39,10 @@ function Presence({ children }) {
39
39
  Children.forEach(children, (child) => {
40
40
  if (!isValidElement(child)) return;
41
41
  if (child.key === null) {
42
- if (__DEV__) {
43
- console.warn(
44
- "[inertia] <Presence> children must have a `key`. Skipping a keyless child."
45
- );
46
- }
42
+ warnOnce(
43
+ "presence-keyless-child",
44
+ "[inertia] <Presence> children must have a `key`. Skipping a keyless child."
45
+ );
47
46
  return;
48
47
  }
49
48
  out.push(child);
@@ -358,7 +357,9 @@ function resolveLayoutTransition(layout) {
358
357
  const cfg = layout === true ? { type: "spring" } : layout;
359
358
  if (cfg.type === "no-animation") return void 0;
360
359
  if (cfg.type === "timing") {
361
- let builder2 = LinearTransition.duration(cfg.duration ?? 300);
360
+ let builder2 = LinearTransition.duration(
361
+ cfg.duration ?? DEFAULT_LAYOUT_DURATION
362
+ );
362
363
  const easing = ensureWorkletEasing(cfg.easing);
363
364
  if (easing) builder2 = builder2.easing(easing);
364
365
  if (cfg.delay) builder2 = builder2.delay(cfg.delay);
@@ -554,7 +555,7 @@ function useSharedLayout(options) {
554
555
  }
555
556
  function legBuilder(transition) {
556
557
  if (transition?.type === "timing") {
557
- const duration = transition.duration ?? 300;
558
+ const duration = transition.duration ?? DEFAULT_LAYOUT_DURATION;
558
559
  return (from, to) => withSequence(
559
560
  withTiming(from, { duration: 0 }),
560
561
  withTiming(to, { duration })
@@ -974,11 +975,8 @@ function createMotionComponent(Component) {
974
975
  }
975
976
  }
976
977
  }
977
- const activeKeysRef = useRef(null);
978
- const hasTransformRef = useRef(false);
979
- const hasShadowOffsetRef = useRef(false);
980
- const hasBoxShadowRef = useRef(false);
981
- const prevActive = activeKeysRef.current;
978
+ const activeSetRef = useRef(null);
979
+ const prevActive = activeSetRef.current?.keys ?? null;
982
980
  let grew = prevActive === null;
983
981
  if (!grew && prevActive) {
984
982
  for (const k of touched) {
@@ -991,30 +989,32 @@ function createMotionComponent(Component) {
991
989
  if (grew) {
992
990
  const merged = new Set(prevActive ?? []);
993
991
  for (const k of touched) merged.add(k);
994
- activeKeysRef.current = ALL_KEYS.filter((k) => merged.has(k));
995
- hasTransformRef.current = activeKeysRef.current.some(
996
- (k) => TRANSFORM_KEY_SET.has(k)
997
- );
998
- hasShadowOffsetRef.current = activeKeysRef.current.some(
999
- (k) => SHADOW_OFFSET_KEY_SET.has(k)
1000
- );
1001
- hasBoxShadowRef.current = activeKeysRef.current.includes("boxShadow");
1002
- if (__DEV__ && hasBoxShadowRef.current && activeKeysRef.current.some(
1003
- (k) => k !== "boxShadow" && k.startsWith("shadow")
1004
- )) {
992
+ const keys = ALL_KEYS.filter((k) => merged.has(k));
993
+ activeSetRef.current = {
994
+ keys,
995
+ hasTransform: keys.some((k) => TRANSFORM_KEY_SET.has(k)),
996
+ hasShadowOffset: keys.some((k) => SHADOW_OFFSET_KEY_SET.has(k)),
997
+ hasBoxShadow: keys.includes("boxShadow")
998
+ };
999
+ if (__DEV__ && activeSetRef.current.hasBoxShadow && keys.some((k) => k !== "boxShadow" && k.startsWith("shadow"))) {
1005
1000
  warnOnce(
1006
1001
  "boxShadow-with-native-shadow",
1007
1002
  "[inertia] `boxShadow` is animated alongside the native `shadow*` keys on the same element, which applies two shadow systems at once. Pick one: `boxShadow` for the cross-platform CSS form, or the native `shadow*` keys."
1008
1003
  );
1009
1004
  }
1010
1005
  }
1006
+ const activeKeys = activeSetRef.current.keys;
1007
+ const activeSetSV = useSharedValue(activeSetRef.current);
1008
+ const activeSet = activeSetRef.current;
1009
+ useEffect(() => {
1010
+ if (activeSetSV.value !== activeSet) activeSetSV.value = activeSet;
1011
+ }, [activeSetSV, activeSet]);
1011
1012
  const drivenNow = /* @__PURE__ */ new Set();
1012
1013
  collectTouchedKeys(drivenNow, animateRecord);
1013
1014
  if (initialRecord) collectTouchedKeys(drivenNow, initialRecord);
1014
1015
  if (isExiting && exitRecord) collectTouchedKeys(drivenNow, exitRecord);
1015
1016
  const everDrivenRef = useRef(/* @__PURE__ */ new Set());
1016
1017
  for (const k of drivenNow) everDrivenRef.current.add(k);
1017
- const activeKeys = activeKeysRef.current;
1018
1018
  const everDriven = everDrivenRef.current;
1019
1019
  const styleResting = {};
1020
1020
  let styleRestingShadow = null;
@@ -1072,7 +1072,7 @@ function createMotionComponent(Component) {
1072
1072
  );
1073
1073
  const styleRestingSig = stableSig(styleResting);
1074
1074
  useEffect(() => {
1075
- for (const key of activeKeysRef.current) {
1075
+ for (const key of activeKeys) {
1076
1076
  if (everDrivenRef.current.has(key)) continue;
1077
1077
  sharedValues[key].value = styleResting[key] ?? DEFAULT_RESTING[key];
1078
1078
  if (key === "boxShadow") {
@@ -1105,6 +1105,7 @@ function createMotionComponent(Component) {
1105
1105
  const baseRecord = isExiting && exitRecord ? { ...animateRecord, ...exitRecord } : animateRecord;
1106
1106
  const baseSig = stableSig(baseRecord) + (isExiting ? "|exit" : "") + (shouldReduceMotion ? "|rm" : "");
1107
1107
  const transitionSig = stableSig(transition);
1108
+ const hasAnimationEnd = onAnimationEnd !== void 0;
1108
1109
  const safeToRemoveRef = useRef(void 0);
1109
1110
  safeToRemoveRef.current = presence?.safeToRemove;
1110
1111
  useEffect(() => {
@@ -1191,7 +1192,10 @@ function createMotionComponent(Component) {
1191
1192
  if (isExiting && pending === 0) {
1192
1193
  safeToRemoveRef.current?.();
1193
1194
  }
1194
- }, [baseSig, transitionSig]);
1195
+ return () => {
1196
+ done = true;
1197
+ };
1198
+ }, [baseSig, transitionSig, hasAnimationEnd]);
1195
1199
  useGestureLayerProgress(
1196
1200
  pressedProgress,
1197
1201
  pressed,
@@ -1232,7 +1236,7 @@ function createMotionComponent(Component) {
1232
1236
  if (!hasLayoutId) return void 0;
1233
1237
  const out = {};
1234
1238
  let any = false;
1235
- for (const key of activeKeysRef.current) {
1239
+ for (const key of activeKeys) {
1236
1240
  if (!SHARED_STYLE_KEY_SET.has(key)) continue;
1237
1241
  const v = sharedValues[key].value;
1238
1242
  if (typeof v !== "number" && typeof v !== "string") continue;
@@ -1252,10 +1256,11 @@ function createMotionComponent(Component) {
1252
1256
  const flip = sharedLayout.flip;
1253
1257
  const carry = sharedLayout.carry;
1254
1258
  const animatedStyle = useAnimatedStyle(() => {
1255
- const activeKeys2 = activeKeysRef.current;
1256
- const hasTransform = hasTransformRef.current;
1257
- const hasShadowOffset = hasShadowOffsetRef.current;
1258
- const hasBoxShadow = hasBoxShadowRef.current;
1259
+ const activeSet2 = activeSetSV.value;
1260
+ const activeKeys2 = activeSet2.keys;
1261
+ const hasTransform = activeSet2.hasTransform;
1262
+ const hasShadowOffset = activeSet2.hasShadowOffset;
1263
+ const hasBoxShadow = activeSet2.hasBoxShadow;
1259
1264
  const out = {};
1260
1265
  const transform = [];
1261
1266
  let shadowOffsetW = 0;
@@ -1554,12 +1559,7 @@ function stepCountOf(v) {
1554
1559
  }
1555
1560
  function totalIterationsOf(cfg) {
1556
1561
  if (!cfg || cfg.type === "no-animation" || cfg.type === "decay") return 1;
1557
- const r = cfg.repeat;
1558
- if (r === void 0) return 1;
1559
- if (r === "infinite") return Number.POSITIVE_INFINITY;
1560
- if (typeof r === "number") return r;
1561
- if (r.count === "infinite") return Number.POSITIVE_INFINITY;
1562
- return r.count;
1562
+ return repeatIterationsOf(cfg.repeat);
1563
1563
  }
1564
1564
  function reachesTerminalPhase(cfg) {
1565
1565
  return Number.isFinite(totalIterationsOf(cfg));
@@ -1586,16 +1586,21 @@ function useControllerKey(controller) {
1586
1586
  return controller?.current;
1587
1587
  }
1588
1588
  function resolveAnimateInput(animate, variants, controllerKey) {
1589
+ if (controllerKey !== void 0 && animate !== void 0) {
1590
+ warnOnce(
1591
+ "controller-and-animate",
1592
+ "[inertia] Both `controller` and `animate` are set on the same primitive. The controller drives the animation and `animate` is ignored \u2014 remove one of the two."
1593
+ );
1594
+ }
1589
1595
  if (controllerKey !== void 0 && variants && controllerKey in variants) {
1590
1596
  return variants[controllerKey];
1591
1597
  }
1592
1598
  if (typeof animate === "string") {
1593
1599
  if (variants && animate in variants) return variants[animate];
1594
- if (__DEV__) {
1595
- console.warn(
1596
- `[inertia] animate="${animate}" but no matching variant. Did you forget to pass \`variants\`?`
1597
- );
1598
- }
1600
+ warnOnce(
1601
+ `missing-variant:${animate}`,
1602
+ `[inertia] animate="${animate}" but no matching variant. Did you forget to pass \`variants\`?`
1603
+ );
1599
1604
  return void 0;
1600
1605
  }
1601
1606
  return animate;
@@ -1663,6 +1668,9 @@ function useGestureHandlers(gesture, rest, setPressed, setFocused, setFocusVisib
1663
1668
  const hasFocused = gesture?.focused ? 1 : 0;
1664
1669
  const hasFocusVisible = gesture?.focusVisible ? 1 : 0;
1665
1670
  const hasHovered = gesture?.hovered ? 1 : 0;
1671
+ useEffect(() => {
1672
+ if (hasFocusVisible) installFocusVisibility();
1673
+ }, [hasFocusVisible]);
1666
1674
  return useMemo(() => {
1667
1675
  if (!gesture) return {};
1668
1676
  const handlers = {};
@@ -0,0 +1,23 @@
1
+ 'use strict';
2
+
3
+ var reactNativeReanimated = require('react-native-reanimated');
4
+
5
+ // src/touch/applyBounds.ts
6
+ function applyBounds(value, min, max, elastic) {
7
+ "worklet";
8
+ if (min !== void 0 && value < min) {
9
+ return elastic > 0 ? min + (value - min) * elastic : min;
10
+ }
11
+ if (max !== void 0 && value > max) {
12
+ return elastic > 0 ? max + (value - max) * elastic : max;
13
+ }
14
+ return value;
15
+ }
16
+ function useTranslateStyle(x, y) {
17
+ return reactNativeReanimated.useAnimatedStyle(() => ({
18
+ transform: [{ translateX: x.value }, { translateY: y.value }]
19
+ }));
20
+ }
21
+
22
+ exports.applyBounds = applyBounds;
23
+ exports.useTranslateStyle = useTranslateStyle;
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkWNVHPMBI_js = require('./chunk-WNVHPMBI.js');
3
+ var chunkN33GSDNQ_js = require('./chunk-N33GSDNQ.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 = chunkWNVHPMBI_js.stableSig(transitions);
35
+ const transitionsSig = chunkN33GSDNQ_js.stableSig(transitions);
36
36
  const value = react.useMemo(
37
37
  () => ({
38
38
  reducedMotion: reducedMotion ?? parent.reducedMotion,
@@ -49,11 +49,10 @@ var UNKNOWN_NAME_FALLBACK = { type: "spring" };
49
49
  function lookupNamedTransition(name, registry) {
50
50
  const cfg = registry[name];
51
51
  if (cfg) return cfg;
52
- if (__DEV__) {
53
- console.warn(
54
- `[inertia] Unknown transition name "${name}" \u2014 falling back to the default spring. Register it on a provider: <MotionConfig transitions={{ '${name}': { ... } }}>.`
55
- );
56
- }
52
+ chunkN33GSDNQ_js.warnOnce(
53
+ `unknown-transition:${name}`,
54
+ `[inertia] Unknown transition name "${name}" \u2014 falling back to the default spring. Register it on a provider: <MotionConfig transitions={{ '${name}': { ... } }}>.`
55
+ );
57
56
  return UNKNOWN_NAME_FALLBACK;
58
57
  }
59
58
  function resolveNamedTransition(input, registry) {
@@ -66,7 +65,7 @@ function resolveNamedTransitionProp(transition, registry) {
66
65
  if (typeof transition === "string") {
67
66
  return lookupNamedTransition(transition, registry);
68
67
  }
69
- if (chunkWNVHPMBI_js.isTopLevelTransition(transition)) return transition;
68
+ if (chunkN33GSDNQ_js.isTopLevelTransition(transition)) return transition;
70
69
  const map = transition;
71
70
  let out = null;
72
71
  for (const key in map) {
@@ -86,7 +85,7 @@ function setKeyboard() {
86
85
  function setPointer() {
87
86
  modality = "pointer";
88
87
  }
89
- function ensureInstalled() {
88
+ function installFocusVisibility() {
90
89
  if (installed) return;
91
90
  if (reactNative.Platform.OS !== "web") return;
92
91
  if (typeof document === "undefined") return;
@@ -96,14 +95,14 @@ function ensureInstalled() {
96
95
  document.addEventListener("touchstart", setPointer, true);
97
96
  installed = true;
98
97
  }
99
- ensureInstalled();
100
98
  function isFocusVisible() {
101
99
  if (reactNative.Platform.OS !== "web") return true;
102
- ensureInstalled();
100
+ installFocusVisibility();
103
101
  return modality === "keyboard";
104
102
  }
105
103
 
106
104
  exports.MotionConfig = MotionConfig;
105
+ exports.installFocusVisibility = installFocusVisibility;
107
106
  exports.isFocusVisible = isFocusVisible;
108
107
  exports.lookupNamedTransition = lookupNamedTransition;
109
108
  exports.resolveNamedTransition = resolveNamedTransition;