@rootnative/inertia 0.0.3 → 0.0.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 (75) hide show
  1. package/CHANGELOG.md +92 -5
  2. package/README.md +9 -3
  3. package/dist/{chunk-OQV66TBQ.mjs → chunk-27MKBTSG.mjs} +1 -1
  4. package/dist/{chunk-3XTVY34H.js → chunk-27U6766G.js} +2 -2
  5. package/dist/{chunk-4PEHWDAZ.js → chunk-4NAMD62I.js} +7 -7
  6. package/dist/chunk-67GHRCF6.js +8 -0
  7. package/dist/{chunk-SGUHE5CX.mjs → chunk-COEJVWRZ.mjs} +1 -1
  8. package/dist/chunk-GPOMFIIU.js +8 -0
  9. package/dist/{chunk-BQQTHG2V.mjs → chunk-GTJ6VAH5.mjs} +1 -1
  10. package/dist/chunk-K63LXGKS.js +8 -0
  11. package/dist/{chunk-46P57VMY.mjs → chunk-OAUWLPQH.mjs} +1 -1
  12. package/dist/{chunk-7AOERN53.js → chunk-OBRGJAST.js} +3 -3
  13. package/dist/{chunk-RGNX6UZN.mjs → chunk-OW5XTGVN.mjs} +2 -2
  14. package/dist/{chunk-PTRF47DA.js → chunk-PM6CVGXJ.js} +11 -3
  15. package/dist/{chunk-W5MC3P4N.js → chunk-QQVDZKSD.js} +2 -2
  16. package/dist/{chunk-CY7Y64C3.mjs → chunk-REYL77RE.mjs} +11 -4
  17. package/dist/{chunk-CSODMRJ7.mjs → chunk-RIVVBABB.mjs} +597 -134
  18. package/dist/{chunk-BP3Y2SHQ.js → chunk-VQ5D35UA.js} +617 -152
  19. package/dist/{chunk-O22NXXCZ.mjs → chunk-XSK5MNUH.mjs} +1 -1
  20. package/dist/{chunk-R63GIUNU.mjs → chunk-Z3HCJ43H.mjs} +1 -1
  21. package/dist/gestureLayer/index.d.mts +2 -2
  22. package/dist/gestureLayer/index.d.ts +2 -2
  23. package/dist/gestureLayer/index.js +10 -10
  24. package/dist/gestureLayer/index.mjs +3 -3
  25. package/dist/index.d.mts +4 -4
  26. package/dist/index.d.ts +4 -4
  27. package/dist/index.js +48 -169
  28. package/dist/index.mjs +17 -137
  29. package/dist/motion/Image.d.mts +1 -1
  30. package/dist/motion/Image.d.ts +1 -1
  31. package/dist/motion/Image.js +5 -5
  32. package/dist/motion/Image.mjs +4 -4
  33. package/dist/motion/Pressable.d.mts +1 -1
  34. package/dist/motion/Pressable.d.ts +1 -1
  35. package/dist/motion/Pressable.js +5 -5
  36. package/dist/motion/Pressable.mjs +4 -4
  37. package/dist/motion/ScrollView.d.mts +1 -1
  38. package/dist/motion/ScrollView.d.ts +1 -1
  39. package/dist/motion/ScrollView.js +5 -5
  40. package/dist/motion/ScrollView.mjs +4 -4
  41. package/dist/motion/Text.d.mts +1 -1
  42. package/dist/motion/Text.d.ts +1 -1
  43. package/dist/motion/Text.js +5 -5
  44. package/dist/motion/Text.mjs +4 -4
  45. package/dist/motion/View.d.mts +1 -1
  46. package/dist/motion/View.d.ts +1 -1
  47. package/dist/motion/View.js +5 -5
  48. package/dist/motion/View.mjs +4 -4
  49. package/dist/touch/index.d.mts +1 -1
  50. package/dist/touch/index.d.ts +1 -1
  51. package/dist/touch/index.js +3 -3
  52. package/dist/touch/index.mjs +1 -1
  53. package/dist/{types-G1dBU2IQ.d.mts → types-BQgLJeQG.d.mts} +85 -14
  54. package/dist/{types-G1dBU2IQ.d.ts → types-BQgLJeQG.d.ts} +85 -14
  55. package/dist/{useGesture-D1e4ixJo.d.ts → useGesture-B0_CzOUz.d.ts} +1 -1
  56. package/dist/{useGesture-RFY6kTL3.d.mts → useGesture-DfaTx-3t.d.mts} +1 -1
  57. package/llms.txt +3 -1
  58. package/package.json +1 -1
  59. package/src/index.ts +2 -1
  60. package/src/internal/boxShadow.ts +177 -6
  61. package/src/internal/nonWorkletWarning.ts +4 -6
  62. package/src/internal/warnOnce.ts +28 -0
  63. package/src/layout/index.ts +10 -0
  64. package/src/layout/measureWindow.ts +135 -0
  65. package/src/layout/sharedRegistry.ts +107 -18
  66. package/src/layout/useSharedLayout.ts +256 -91
  67. package/src/motion/createMotionComponent.tsx +497 -74
  68. package/src/motion/installCheck.ts +1 -1
  69. package/src/transitions/index.ts +1 -1
  70. package/src/transitions/resolveSequence.ts +12 -0
  71. package/src/types.ts +155 -12
  72. package/src/values/useColorTransition.ts +1 -1
  73. package/dist/chunk-FNVFV4EY.js +0 -8
  74. package/dist/chunk-FWQOXA43.js +0 -8
  75. package/dist/chunk-KBP4LR75.js +0 -8
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunk7AOERN53_js = require('./chunk-7AOERN53.js');
4
- var chunkPTRF47DA_js = require('./chunk-PTRF47DA.js');
3
+ var chunkOBRGJAST_js = require('./chunk-OBRGJAST.js');
4
+ var chunkPM6CVGXJ_js = require('./chunk-PM6CVGXJ.js');
5
5
  var react = require('react');
6
6
  var jsxRuntime = require('react/jsx-runtime');
7
7
  var Animated = require('react-native-reanimated');
@@ -135,20 +135,189 @@ function PresenceItem({
135
135
  );
136
136
  return /* @__PURE__ */ jsxRuntime.jsx(PresenceContext.Provider, { value, children });
137
137
  }
138
+
139
+ // src/internal/boxShadow.ts
140
+ var LENGTH = /^[+-]?(\d+\.?\d*|\.\d+)(px)?$/i;
141
+ var UNIT_LIKE = /^[+-]?(\d+\.?\d*|\.\d+)[a-z%]+$/i;
142
+ function invalid(input, reason) {
143
+ return new Error(
144
+ `[inertia] parseBoxShadow: ${reason} in ${JSON.stringify(input)}. Expected CSS box-shadow syntax with px lengths: '[inset] <offset-x> <offset-y> [blur] [spread] [color], ...'`
145
+ );
146
+ }
147
+ function splitLayers(input) {
148
+ const layers = [];
149
+ let depth = 0;
150
+ let start = 0;
151
+ for (let i = 0; i < input.length; i++) {
152
+ const ch = input[i];
153
+ if (ch === "(") depth++;
154
+ else if (ch === ")") depth--;
155
+ else if (ch === "," && depth === 0) {
156
+ layers.push(input.slice(start, i));
157
+ start = i + 1;
158
+ }
159
+ }
160
+ layers.push(input.slice(start));
161
+ return layers;
162
+ }
163
+ function tokenize(layer) {
164
+ const tokens = [];
165
+ let depth = 0;
166
+ let current = "";
167
+ for (const ch of layer) {
168
+ if (ch === "(") depth++;
169
+ else if (ch === ")") depth--;
170
+ if (depth === 0 && /\s/.test(ch)) {
171
+ if (current) tokens.push(current);
172
+ current = "";
173
+ } else {
174
+ current += ch;
175
+ }
176
+ }
177
+ if (current) tokens.push(current);
178
+ return tokens;
179
+ }
180
+ function parseBoxShadow(input) {
181
+ const trimmed = input.trim();
182
+ if (trimmed === "") throw invalid(input, "empty string");
183
+ if (trimmed.toLowerCase() === "none") return [];
184
+ return splitLayers(trimmed).map((layerString) => {
185
+ const tokens = tokenize(layerString.trim());
186
+ if (tokens.length === 0) throw invalid(input, "empty layer");
187
+ const lengths = [];
188
+ let color;
189
+ let inset = false;
190
+ for (const token of tokens) {
191
+ if (token.toLowerCase() === "inset") {
192
+ if (inset) throw invalid(input, "duplicate 'inset'");
193
+ inset = true;
194
+ } else if (LENGTH.test(token)) {
195
+ lengths.push(parseFloat(token));
196
+ } else if (UNIT_LIKE.test(token)) {
197
+ throw invalid(input, `unsupported unit in ${JSON.stringify(token)}`);
198
+ } else {
199
+ if (color !== void 0) throw invalid(input, "multiple colors");
200
+ color = token;
201
+ }
202
+ }
203
+ if (lengths.length < 2 || lengths.length > 4) {
204
+ throw invalid(input, `expected 2-4 lengths, got ${lengths.length}`);
205
+ }
206
+ const [offsetX = 0, offsetY = 0, blurRadius = 0, spreadDistance = 0] = lengths;
207
+ if (blurRadius < 0) throw invalid(input, "negative blur radius");
208
+ return {
209
+ offsetX,
210
+ offsetY,
211
+ blurRadius,
212
+ spreadDistance,
213
+ color: color ?? "black",
214
+ inset
215
+ };
216
+ });
217
+ }
218
+ function resolveBoxShadowInput(input) {
219
+ if (input === void 0) return [];
220
+ if (typeof input === "string") return parseBoxShadow(input);
221
+ return input.map((layer) => ({
222
+ offsetX: coerceLength(layer.offsetX, "offsetX"),
223
+ offsetY: coerceLength(layer.offsetY, "offsetY"),
224
+ blurRadius: coerceLength(layer.blurRadius, "blurRadius"),
225
+ spreadDistance: coerceLength(layer.spreadDistance, "spreadDistance"),
226
+ color: layer.color ?? "black",
227
+ inset: layer.inset ?? false
228
+ }));
229
+ }
230
+ function pairBoxShadowLayers(from, to) {
231
+ const count = Math.max(from.length, to.length);
232
+ const pairs = [];
233
+ for (let i = 0; i < count; i++) {
234
+ const a = from[i];
235
+ const b = to[i];
236
+ const fromLayer = a ?? invisibleLayer(b.inset);
237
+ const toLayer = b ?? invisibleLayer(a.inset);
238
+ if (fromLayer.inset !== toLayer.inset) {
239
+ throw new Error(
240
+ `[inertia] useShadow: boxShadow layer ${i} is 'inset' on one side but not the other \u2014 inset cannot be interpolated. Give both sides the same inset-ness (pad with a transparent layer if needed).`
241
+ );
242
+ }
243
+ pairs.push({ from: fromLayer, to: toLayer });
244
+ }
245
+ return pairs;
246
+ }
247
+ function invisibleLayer(inset) {
248
+ return {
249
+ offsetX: 0,
250
+ offsetY: 0,
251
+ blurRadius: 0,
252
+ spreadDistance: 0,
253
+ color: "transparent",
254
+ inset
255
+ };
256
+ }
257
+ function coerceLength(value, field) {
258
+ if (value === void 0) return 0;
259
+ if (typeof value === "number") return value;
260
+ const trimmed = typeof value === "string" ? value.trim() : "";
261
+ if (!LENGTH.test(trimmed)) {
262
+ throw new Error(
263
+ `[inertia] boxShadow: ${field} must be a number or a px length, got ${JSON.stringify(value)}.`
264
+ );
265
+ }
266
+ return parseFloat(trimmed);
267
+ }
268
+ function strip(layer) {
269
+ const { inset: _inset, ...rest } = layer;
270
+ return rest;
271
+ }
272
+ function markInset(insets, i, count) {
273
+ const list = insets ?? new Array(count).fill(false);
274
+ list[i] = true;
275
+ return list;
276
+ }
277
+ function normalizeBoxShadow(input) {
278
+ const resolved = resolveBoxShadowInput(input);
279
+ const layers = [];
280
+ let insets = null;
281
+ for (let i = 0; i < resolved.length; i++) {
282
+ const layer = resolved[i];
283
+ layers.push(strip(layer));
284
+ if (layer.inset) insets = markInset(insets, i, resolved.length);
285
+ }
286
+ return { layers, insets };
287
+ }
288
+ function prepareBoxShadowAnimation(current, target) {
289
+ const pairs = pairBoxShadowLayers(
290
+ current.layers.map((layer, i) => ({
291
+ ...layer,
292
+ inset: current.insets?.[i] ?? false
293
+ })),
294
+ resolveBoxShadowInput(target)
295
+ );
296
+ const from = [];
297
+ const to = [];
298
+ let insets = null;
299
+ for (let i = 0; i < pairs.length; i++) {
300
+ const pair = pairs[i];
301
+ from.push(strip(pair.from));
302
+ to.push(strip(pair.to));
303
+ if (pair.to.inset) insets = markInset(insets, i, pairs.length);
304
+ }
305
+ return { from, to, insets };
306
+ }
138
307
  function resolveLayoutTransition(layout) {
139
308
  if (!layout) return void 0;
140
309
  const cfg = layout === true ? { type: "spring" } : layout;
141
310
  if (cfg.type === "no-animation") return void 0;
142
311
  if (cfg.type === "timing") {
143
312
  let builder2 = Animated.LinearTransition.duration(cfg.duration ?? 300);
144
- const easing = chunkPTRF47DA_js.ensureWorkletEasing(cfg.easing);
313
+ const easing = chunkPM6CVGXJ_js.ensureWorkletEasing(cfg.easing);
145
314
  if (easing) builder2 = builder2.easing(easing);
146
315
  if (cfg.delay) builder2 = builder2.delay(cfg.delay);
147
316
  return builder2;
148
317
  }
149
318
  const spring = cfg.type === "decay" ? { type: "spring" } : cfg;
150
- const { stiffness, damping, mass } = chunkPTRF47DA_js.springToReanimated({
151
- ...chunkPTRF47DA_js.DEFAULT_SPRING,
319
+ const { stiffness, damping, mass } = chunkPM6CVGXJ_js.springToReanimated({
320
+ ...chunkPM6CVGXJ_js.DEFAULT_SPRING,
152
321
  ...spring
153
322
  });
154
323
  let builder = Animated.LinearTransition.springify().stiffness(stiffness).damping(damping).mass(mass);
@@ -168,72 +337,138 @@ function sweepExpired(at) {
168
337
  if (entry.expiresAt < at) REGISTRY.delete(id);
169
338
  }
170
339
  }
171
- function registerLayout(id, rect) {
340
+ function registerLayout(id, rect, remeasure, readStyles) {
172
341
  const at = now();
173
342
  sweepExpired(at);
174
- REGISTRY.set(id, { rect, expiresAt: at + SHARED_LAYOUT_TTL_MS });
343
+ REGISTRY.set(id, {
344
+ rect,
345
+ expiresAt: at + SHARED_LAYOUT_TTL_MS,
346
+ remeasure,
347
+ readStyles
348
+ });
175
349
  }
176
- function releaseLayout(id, rect) {
350
+ function releaseLayout(id, rect, styles) {
177
351
  const at = now();
178
352
  sweepExpired(at);
179
- REGISTRY.set(id, { rect, expiresAt: at + SHARED_LAYOUT_TTL_MS });
353
+ REGISTRY.set(id, { rect, expiresAt: at + SHARED_LAYOUT_TTL_MS, styles });
180
354
  }
181
355
  function consumeLayout(id) {
182
356
  const entry = REGISTRY.get(id);
183
357
  if (!entry) return void 0;
184
358
  REGISTRY.delete(id);
185
359
  if (entry.expiresAt < now()) return void 0;
186
- return entry.rect;
360
+ return {
361
+ rect: entry.rect,
362
+ remeasure: entry.remeasure,
363
+ styles: entry.styles,
364
+ readStyles: entry.readStyles
365
+ };
366
+ }
367
+
368
+ // src/layout/measureWindow.ts
369
+ var defaultMeasurer = (node) => {
370
+ const measure = node?.measureInWindow;
371
+ if (typeof measure !== "function") return void 0;
372
+ let result;
373
+ let returned = false;
374
+ try {
375
+ measure.call(node, (x, y, width, height) => {
376
+ if (returned) return;
377
+ result = { x, y, width, height };
378
+ });
379
+ } catch {
380
+ returned = true;
381
+ return void 0;
382
+ }
383
+ returned = true;
384
+ return result;
385
+ };
386
+ var measurer = defaultMeasurer;
387
+ function usable(rect) {
388
+ const { x, y, width, height } = rect;
389
+ for (const v of [x, y, width, height]) {
390
+ if (typeof v !== "number" || !Number.isFinite(v)) return false;
391
+ }
392
+ return width !== 0 || height !== 0;
393
+ }
394
+ function measureWindowRect(node) {
395
+ const measured = measurer(node);
396
+ if (!measured || !usable(measured)) return void 0;
397
+ return toSharedRect(measured, "window");
398
+ }
399
+ function toSharedRect(rect, space) {
400
+ return { ...rect, space };
187
401
  }
188
402
  function useSharedLayout(options) {
189
- const { layoutId, userRef, transition, shouldReduceMotion, userOnLayout } = options;
403
+ const {
404
+ layoutId,
405
+ userRef,
406
+ transition,
407
+ shouldReduceMotion,
408
+ userOnLayout,
409
+ readStyles
410
+ } = options;
190
411
  const dx = Animated.useSharedValue(0);
191
412
  const dy = Animated.useSharedValue(0);
192
413
  const sx = Animated.useSharedValue(1);
193
414
  const sy = Animated.useSharedValue(1);
415
+ const snapshot = Animated.useSharedValue(null);
416
+ const carryProgress = Animated.useSharedValue(0);
194
417
  const lastRectRef = react.useRef(null);
195
418
  const consumedRef = react.useRef(false);
419
+ const nodeRef = react.useRef(null);
196
420
  const transitionRef = react.useRef(transition);
197
421
  transitionRef.current = transition;
198
422
  const reducedMotionRef = react.useRef(shouldReduceMotion);
199
423
  reducedMotionRef.current = shouldReduceMotion;
424
+ const readStylesRef = react.useRef(readStyles);
425
+ readStylesRef.current = readStyles;
200
426
  const setRef = react.useCallback(
201
427
  (node) => {
428
+ nodeRef.current = node;
202
429
  if (typeof userRef === "function") userRef(node);
203
430
  else if (userRef) userRef.current = node;
204
431
  },
205
432
  [userRef]
206
433
  );
434
+ const remeasure = react.useCallback(() => measureWindowRect(nodeRef.current), []);
435
+ const snapshotStyles = react.useCallback(() => readStylesRef.current?.(), []);
436
+ const startTransition = react.useCallback(
437
+ (source, sourceRect, target) => {
438
+ if (sourceRect.space !== target.space) return;
439
+ const shared = {
440
+ transition: transitionRef.current,
441
+ shouldReduceMotion: reducedMotionRef.current
442
+ };
443
+ applyFlip({ source: sourceRect, target, dx, dy, sx, sy, ...shared });
444
+ applyStyleCarry({
445
+ snapshot,
446
+ progress: carryProgress,
447
+ // Prefer a live read for the same reason the rect is re-measured: a
448
+ // still-mounted source may have moved on since its last layout.
449
+ styles: source.readStyles?.() ?? source.styles,
450
+ ...shared
451
+ });
452
+ },
453
+ [dx, dy, sx, sy, snapshot, carryProgress]
454
+ );
207
455
  const onLayout = react.useCallback(
208
456
  (event) => {
209
457
  userOnLayout?.(event);
210
458
  if (!layoutId) return;
211
459
  const { x, y, width, height } = event.nativeEvent.layout;
212
- const rect = { x, y, width, height };
213
- lastRectRef.current = rect;
214
460
  let source;
215
461
  if (!consumedRef.current) {
216
462
  consumedRef.current = true;
217
463
  source = consumeLayout(layoutId);
218
464
  }
219
- registerLayout(layoutId, rect);
220
- if (source) {
221
- applyFlip({
222
- source,
223
- target: rect,
224
- dx,
225
- dy,
226
- sx,
227
- sy,
228
- transition: transitionRef.current,
229
- shouldReduceMotion: reducedMotionRef.current
230
- });
231
- }
465
+ const rect = measureWindowRect(nodeRef.current) ?? { x, y, width, height, space: "parent" };
466
+ lastRectRef.current = rect;
467
+ registerLayout(layoutId, rect, remeasure, snapshotStyles);
468
+ if (!source) return;
469
+ startTransition(source, source.remeasure?.() ?? source.rect, rect);
232
470
  },
233
- // dx/dy/sx/sy are stable refs from useSharedValue, but eslint's
234
- // exhaustive-deps would flag them — including them is harmless and
235
- // silences the warning.
236
- [layoutId, userOnLayout, dx, dy, sx, sy]
471
+ [layoutId, userOnLayout, remeasure, snapshotStyles, startTransition]
237
472
  );
238
473
  react.useEffect(() => {
239
474
  consumedRef.current = false;
@@ -243,18 +478,49 @@ function useSharedLayout(options) {
243
478
  if (!layoutId) return;
244
479
  const rect = lastRectRef.current;
245
480
  if (!rect) return;
246
- releaseLayout(layoutId, rect);
481
+ releaseLayout(layoutId, rect, snapshotStyles());
247
482
  };
248
- }, [layoutId]);
483
+ }, [layoutId, snapshotStyles]);
484
+ react.useEffect(
485
+ () => () => {
486
+ Animated.cancelAnimation(dx);
487
+ Animated.cancelAnimation(dy);
488
+ Animated.cancelAnimation(sx);
489
+ Animated.cancelAnimation(sy);
490
+ Animated.cancelAnimation(carryProgress);
491
+ },
492
+ // The FLIP shared values are identity-stable per hook instance.
493
+ // eslint-disable-next-line react-hooks/exhaustive-deps
494
+ []
495
+ );
249
496
  return react.useMemo(
250
497
  () => ({
251
498
  flip: { dx, dy, sx, sy },
499
+ carry: { snapshot, progress: carryProgress },
252
500
  setRef,
253
501
  onLayout
254
502
  }),
255
- [dx, dy, sx, sy, setRef, onLayout]
503
+ [dx, dy, sx, sy, snapshot, carryProgress, setRef, onLayout]
256
504
  );
257
505
  }
506
+ function legBuilder(transition) {
507
+ if (transition?.type === "timing") {
508
+ const duration = transition.duration ?? 300;
509
+ return (from, to) => Animated.withSequence(
510
+ Animated.withTiming(from, { duration: 0 }),
511
+ Animated.withTiming(to, { duration })
512
+ );
513
+ }
514
+ const springCfg = transition?.type === "spring" ? { ...chunkPM6CVGXJ_js.DEFAULT_SPRING, ...transition } : { type: "spring", ...chunkPM6CVGXJ_js.DEFAULT_SPRING };
515
+ const springParams = chunkPM6CVGXJ_js.springToReanimated(springCfg);
516
+ return (from, to) => Animated.withSequence(
517
+ Animated.withTiming(from, { duration: 0 }),
518
+ Animated.withSpring(to, springParams)
519
+ );
520
+ }
521
+ function shouldSnap(transition, shouldReduceMotion) {
522
+ return shouldReduceMotion || transition?.type === "no-animation";
523
+ }
258
524
  function applyFlip(args) {
259
525
  const { source, target, dx, dy, sx, sy, transition, shouldReduceMotion } = args;
260
526
  const sourceCenterX = source.x + source.width / 2;
@@ -265,58 +531,29 @@ function applyFlip(args) {
265
531
  const deltaY = sourceCenterY - targetCenterY;
266
532
  const scaleX = target.width > 0 ? source.width / target.width : 1;
267
533
  const scaleY = target.height > 0 ? source.height / target.height : 1;
268
- if (shouldReduceMotion) {
269
- dx.value = 0;
270
- dy.value = 0;
271
- sx.value = 1;
272
- sy.value = 1;
273
- return;
274
- }
275
- if (transition?.type === "no-animation") {
534
+ if (shouldSnap(transition, shouldReduceMotion)) {
276
535
  dx.value = 0;
277
536
  dy.value = 0;
278
537
  sx.value = 1;
279
538
  sy.value = 1;
280
539
  return;
281
540
  }
282
- if (transition?.type === "timing") {
283
- const duration = transition.duration ?? 300;
284
- dx.value = Animated.withSequence(
285
- Animated.withTiming(deltaX, { duration: 0 }),
286
- Animated.withTiming(0, { duration })
287
- );
288
- dy.value = Animated.withSequence(
289
- Animated.withTiming(deltaY, { duration: 0 }),
290
- Animated.withTiming(0, { duration })
291
- );
292
- sx.value = Animated.withSequence(
293
- Animated.withTiming(scaleX, { duration: 0 }),
294
- Animated.withTiming(1, { duration })
295
- );
296
- sy.value = Animated.withSequence(
297
- Animated.withTiming(scaleY, { duration: 0 }),
298
- Animated.withTiming(1, { duration })
299
- );
541
+ const leg = legBuilder(transition);
542
+ dx.value = leg(deltaX, 0);
543
+ dy.value = leg(deltaY, 0);
544
+ sx.value = leg(scaleX, 1);
545
+ sy.value = leg(scaleY, 1);
546
+ }
547
+ function applyStyleCarry(args) {
548
+ const { snapshot, progress, styles, transition, shouldReduceMotion } = args;
549
+ if (!styles) return;
550
+ if (shouldSnap(transition, shouldReduceMotion)) {
551
+ snapshot.value = null;
552
+ progress.value = 0;
300
553
  return;
301
554
  }
302
- const springCfg = transition?.type === "spring" ? { ...chunkPTRF47DA_js.DEFAULT_SPRING, ...transition } : { type: "spring", ...chunkPTRF47DA_js.DEFAULT_SPRING };
303
- const springParams = chunkPTRF47DA_js.springToReanimated(springCfg);
304
- dx.value = Animated.withSequence(
305
- Animated.withTiming(deltaX, { duration: 0 }),
306
- Animated.withSpring(0, springParams)
307
- );
308
- dy.value = Animated.withSequence(
309
- Animated.withTiming(deltaY, { duration: 0 }),
310
- Animated.withSpring(0, springParams)
311
- );
312
- sx.value = Animated.withSequence(
313
- Animated.withTiming(scaleX, { duration: 0 }),
314
- Animated.withSpring(1, springParams)
315
- );
316
- sy.value = Animated.withSequence(
317
- Animated.withTiming(scaleY, { duration: 0 }),
318
- Animated.withSpring(1, springParams)
319
- );
555
+ snapshot.value = styles;
556
+ progress.value = legBuilder(transition)(1, 0);
320
557
  }
321
558
  var alreadyChecked = false;
322
559
  function ensureReanimatedInstalled() {
@@ -330,7 +567,7 @@ function ensureReanimatedInstalled() {
330
567
  const major = parseInt(version.split(".")[0] ?? "0", 10);
331
568
  if (major < 4) {
332
569
  console.error(
333
- `[inertia] react-native-reanimated v${version} is installed, but @rootnative/inertia requires v4.0.0 or later. Upgrade with \`pnpm add react-native-reanimated@^4\` (or your package manager's equivalent).`
570
+ `[inertia] react-native-reanimated ${version} is installed, but @rootnative/inertia requires 4.0.0 or later. Upgrade with \`pnpm add react-native-reanimated@^4\` (or your package manager's equivalent).`
334
571
  );
335
572
  return;
336
573
  }
@@ -363,7 +600,79 @@ var NUMERIC_TOP_LEVEL_KEYS = [
363
600
  "borderRadius",
364
601
  "shadowOpacity",
365
602
  "shadowRadius",
366
- "elevation"
603
+ "elevation",
604
+ // ─── Added in 0.0.5 ──────────────────────────────────────────────────────
605
+ //
606
+ // Every key below rides the generic numeric path: one shared value, resolved
607
+ // on the JS thread, emitted by the worklet through the same `out[key] = v`
608
+ // branch as `opacity`. None needs a new interpolation mode, so the cost is
609
+ // the shared value plus a `DEFAULT_RESTING` entry.
610
+ //
611
+ // The load-bearing constraint is the resting default, not the plumbing. A
612
+ // key declared only in `gesture` / `exit` / a non-active variant rests at
613
+ // `DEFAULT_RESTING` unless the static `style` names it, and the animated
614
+ // style merges *after* `style` — so a non-identity default silently stomps
615
+ // the layout. That is the `0.0.3` P0 class, and it is why the sizing and
616
+ // spacing keys below default to `0` only in the sense RN itself does (an
617
+ // unset `padding` *is* 0); `minWidth`/`maxWidth`/`aspectRatio` are
618
+ // deliberately excluded — their "unset" is not a number, so no default can
619
+ // stand in for it without changing layout on activation.
620
+ //
621
+ // Per-corner radii. Animating one corner is common (a card expanding into a
622
+ // sheet keeps its top corners and squares off the bottom); `borderRadius`
623
+ // alone can't express it.
624
+ "borderTopLeftRadius",
625
+ "borderTopRightRadius",
626
+ "borderBottomLeftRadius",
627
+ "borderBottomRightRadius",
628
+ // Border widths. `borderWidth` is the common case; the per-edge keys matter
629
+ // for underline-style focus affordances (`borderBottomWidth` on a field).
630
+ "borderWidth",
631
+ "borderTopWidth",
632
+ "borderRightWidth",
633
+ "borderBottomWidth",
634
+ "borderLeftWidth",
635
+ // Absolute-position insets. Bread-and-butter for drawers, tooltips, and
636
+ // anything pinned to an edge that slides in.
637
+ "top",
638
+ "right",
639
+ "bottom",
640
+ "left",
641
+ // Spacing. Padding animates the box from the inside (a button growing its
642
+ // hit area on press); margin shifts it within its parent's flow.
643
+ "padding",
644
+ "paddingTop",
645
+ "paddingRight",
646
+ "paddingBottom",
647
+ "paddingLeft",
648
+ "paddingHorizontal",
649
+ "paddingVertical",
650
+ "margin",
651
+ "marginTop",
652
+ "marginRight",
653
+ "marginBottom",
654
+ "marginLeft",
655
+ "marginHorizontal",
656
+ "marginVertical",
657
+ // Flex sizing. `flex` / `flexGrow` interpolate the split between siblings —
658
+ // the idiomatic RN way to animate a pane resize without measuring.
659
+ "flex",
660
+ "flexGrow",
661
+ "flexShrink",
662
+ // Text metrics. `TextStyle`-only at the type level (`AnimateStyle<C>` gates
663
+ // them per primitive), but the runtime table is shared across primitives —
664
+ // an unused slot is one ref, same as `tintColor` has always been.
665
+ "fontSize",
666
+ "letterSpacing",
667
+ "lineHeight",
668
+ // Stacking. Integer-valued in practice, and interpolating it mid-flight is
669
+ // rarely what you want, but a `no-animation` transition on `zIndex` is the
670
+ // clean way to reorder at a step boundary in a sequence.
671
+ "zIndex",
672
+ // Gap. Row/column gaps animate a list's density without touching children.
673
+ "gap",
674
+ "rowGap",
675
+ "columnGap"
367
676
  ];
368
677
  var COLOR_KEYS = [
369
678
  "backgroundColor",
@@ -373,15 +682,28 @@ var COLOR_KEYS = [
373
682
  "shadowColor"
374
683
  ];
375
684
  var SHADOW_OFFSET_KEYS = ["shadowOffsetWidth", "shadowOffsetHeight"];
685
+ var STRUCTURED_KEYS = ["boxShadow"];
686
+ var SHARED_STYLE_KEYS = [
687
+ "opacity",
688
+ "borderRadius",
689
+ "backgroundColor",
690
+ "borderColor",
691
+ "color",
692
+ "tintColor"
693
+ ];
376
694
  var ALL_KEYS = [
377
695
  ...TRANSFORM_KEYS,
378
696
  ...NUMERIC_TOP_LEVEL_KEYS,
379
697
  ...COLOR_KEYS,
380
- ...SHADOW_OFFSET_KEYS
698
+ ...SHADOW_OFFSET_KEYS,
699
+ ...STRUCTURED_KEYS
381
700
  ];
382
701
  var TRANSFORM_KEY_SET = new Set(TRANSFORM_KEYS);
383
702
  var COLOR_KEY_SET = new Set(COLOR_KEYS);
384
703
  var SHADOW_OFFSET_KEY_SET = new Set(SHADOW_OFFSET_KEYS);
704
+ var STRUCTURED_KEY_SET = new Set(STRUCTURED_KEYS);
705
+ var SHARED_STYLE_KEY_SET = new Set(SHARED_STYLE_KEYS);
706
+ var NO_BOX_SHADOW = Object.freeze([]);
385
707
  var GESTURE_LAYER_NAMES = [
386
708
  "hovered",
387
709
  "focused",
@@ -406,6 +728,54 @@ var DEFAULT_RESTING = {
406
728
  shadowOpacity: 0,
407
729
  shadowRadius: 0,
408
730
  elevation: 0,
731
+ // 0.0.5 keys. Every one of these is 0 because that is RN's own unset value
732
+ // for it — an element with no `paddingTop` has 0 padding, no `borderWidth`
733
+ // has none, no `top` is unpinned at 0 within its positioning context. So a
734
+ // key that reaches its resting default lands where the element already was.
735
+ //
736
+ // The exception worth naming: `flex` / `flexGrow` / `flexShrink` do NOT have
737
+ // 0 as a universal identity (`flexShrink` defaults to 1 on the web, and RN's
738
+ // own default differs by axis). They are still 0 here, because the style-scan
739
+ // in the resting pass reads the real value off the static `style` whenever it
740
+ // is declared — and a consumer animating flex without declaring it is asking
741
+ // for the from-0 growth, which is the readable interpretation.
742
+ borderTopLeftRadius: 0,
743
+ borderTopRightRadius: 0,
744
+ borderBottomLeftRadius: 0,
745
+ borderBottomRightRadius: 0,
746
+ borderWidth: 0,
747
+ borderTopWidth: 0,
748
+ borderRightWidth: 0,
749
+ borderBottomWidth: 0,
750
+ borderLeftWidth: 0,
751
+ top: 0,
752
+ right: 0,
753
+ bottom: 0,
754
+ left: 0,
755
+ padding: 0,
756
+ paddingTop: 0,
757
+ paddingRight: 0,
758
+ paddingBottom: 0,
759
+ paddingLeft: 0,
760
+ paddingHorizontal: 0,
761
+ paddingVertical: 0,
762
+ margin: 0,
763
+ marginTop: 0,
764
+ marginRight: 0,
765
+ marginBottom: 0,
766
+ marginLeft: 0,
767
+ marginHorizontal: 0,
768
+ marginVertical: 0,
769
+ flex: 0,
770
+ flexGrow: 0,
771
+ flexShrink: 0,
772
+ fontSize: 0,
773
+ letterSpacing: 0,
774
+ lineHeight: 0,
775
+ zIndex: 0,
776
+ gap: 0,
777
+ rowGap: 0,
778
+ columnGap: 0,
409
779
  // 'transparent' is the only safe universal default for colors: it works as
410
780
  // an initial seed for any color animation (no jarring opaque flash on mount
411
781
  // when `initial` is omitted) and rgba(0,0,0,0) interpolates cleanly into
@@ -416,19 +786,20 @@ var DEFAULT_RESTING = {
416
786
  tintColor: "transparent",
417
787
  shadowColor: "transparent",
418
788
  shadowOffsetWidth: 0,
419
- shadowOffsetHeight: 0
789
+ shadowOffsetHeight: 0,
790
+ boxShadow: NO_BOX_SHADOW
420
791
  };
421
792
  function transitionFor(prop, transition) {
422
793
  if (!transition) return void 0;
423
794
  if (typeof transition === "string") return void 0;
424
- if (chunkPTRF47DA_js.isTopLevelTransition(transition)) return transition;
795
+ if (chunkPM6CVGXJ_js.isTopLevelTransition(transition)) return transition;
425
796
  if (GESTURE_LAYER_NAME_SET.has(prop)) return void 0;
426
797
  return transition[prop];
427
798
  }
428
799
  function gestureLayerTransitionFor(layer, transition) {
429
800
  if (!transition) return void 0;
430
801
  if (typeof transition === "string") return void 0;
431
- if (chunkPTRF47DA_js.isTopLevelTransition(transition)) return transition;
802
+ if (chunkPM6CVGXJ_js.isTopLevelTransition(transition)) return transition;
432
803
  return transition[layer];
433
804
  }
434
805
  function createMotionComponent(Component) {
@@ -478,12 +849,12 @@ function createMotionComponent(Component) {
478
849
  onLayout: userOnLayout,
479
850
  ...rest
480
851
  } = props;
481
- const namedTransitions = chunk7AOERN53_js.useNamedTransitions();
482
- const transition = chunk7AOERN53_js.resolveNamedTransitionProp(
852
+ const namedTransitions = chunkOBRGJAST_js.useNamedTransitions();
853
+ const transition = chunkOBRGJAST_js.resolveNamedTransitionProp(
483
854
  transitionProp,
484
855
  namedTransitions
485
856
  );
486
- const layout = typeof layoutProp === "string" ? chunk7AOERN53_js.lookupNamedTransition(layoutProp, namedTransitions) : layoutProp;
857
+ const layout = typeof layoutProp === "string" ? chunkOBRGJAST_js.lookupNamedTransition(layoutProp, namedTransitions) : layoutProp;
487
858
  if (__DEV__ && typeof style === "function") {
488
859
  throw new Error(
489
860
  "[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."
@@ -491,7 +862,7 @@ function createMotionComponent(Component) {
491
862
  }
492
863
  const presence = usePresence();
493
864
  const isExiting = presence !== null && presence.isPresent === false;
494
- const shouldReduceMotion = chunk7AOERN53_js.useShouldReduceMotion();
865
+ const shouldReduceMotion = chunkOBRGJAST_js.useShouldReduceMotion();
495
866
  const onAnimationEndRef = react.useRef(onAnimationEnd);
496
867
  onAnimationEndRef.current = onAnimationEnd;
497
868
  const variantKey = useControllerKey(controller);
@@ -507,6 +878,16 @@ function createMotionComponent(Component) {
507
878
  const [focused, setFocused] = react.useState(false);
508
879
  const [focusVisible, setFocusVisible] = react.useState(false);
509
880
  const [hovered, setHovered] = react.useState(false);
881
+ const hasLayoutId = layoutId !== void 0;
882
+ let flatStyle;
883
+ let flatStyleRead = false;
884
+ const getFlatStyle = () => {
885
+ if (!flatStyleRead) {
886
+ flatStyleRead = true;
887
+ flatStyle = reactNative.StyleSheet.flatten(style);
888
+ }
889
+ return flatStyle;
890
+ };
510
891
  const touched = /* @__PURE__ */ new Set();
511
892
  collectTouchedKeys(touched, animateRecord);
512
893
  if (initialRecord) collectTouchedKeys(touched, initialRecord);
@@ -528,9 +909,19 @@ function createMotionComponent(Component) {
528
909
  }
529
910
  }
530
911
  if (exitRecord) collectTouchedKeys(touched, exitRecord);
912
+ if (hasLayoutId) {
913
+ const flat = getFlatStyle();
914
+ if (flat) {
915
+ for (const key of SHARED_STYLE_KEYS) {
916
+ if (touched.has(key)) continue;
917
+ if (styleValueFor(flat, key) !== void 0) touched.add(key);
918
+ }
919
+ }
920
+ }
531
921
  const activeKeysRef = react.useRef(null);
532
922
  const hasTransformRef = react.useRef(false);
533
923
  const hasShadowOffsetRef = react.useRef(false);
924
+ const hasBoxShadowRef = react.useRef(false);
534
925
  const prevActive = activeKeysRef.current;
535
926
  let grew = prevActive === null;
536
927
  if (!grew && prevActive) {
@@ -551,6 +942,15 @@ function createMotionComponent(Component) {
551
942
  hasShadowOffsetRef.current = activeKeysRef.current.some(
552
943
  (k) => SHADOW_OFFSET_KEY_SET.has(k)
553
944
  );
945
+ hasBoxShadowRef.current = activeKeysRef.current.includes("boxShadow");
946
+ if (__DEV__ && hasBoxShadowRef.current && activeKeysRef.current.some(
947
+ (k) => k !== "boxShadow" && k.startsWith("shadow")
948
+ )) {
949
+ chunkPM6CVGXJ_js.warnOnce(
950
+ "boxShadow-with-native-shadow",
951
+ "[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."
952
+ );
953
+ }
554
954
  }
555
955
  const drivenNow = /* @__PURE__ */ new Set();
556
956
  collectTouchedKeys(drivenNow, animateRecord);
@@ -561,17 +961,35 @@ function createMotionComponent(Component) {
561
961
  const activeKeys = activeKeysRef.current;
562
962
  const everDriven = everDrivenRef.current;
563
963
  const styleResting = {};
964
+ let styleRestingShadow = null;
564
965
  if (activeKeys.some((k) => !everDriven.has(k))) {
565
- const flat = reactNative.StyleSheet.flatten(style);
966
+ const flat = getFlatStyle();
566
967
  if (flat) {
567
968
  for (const key of activeKeys) {
568
969
  if (everDriven.has(key)) continue;
970
+ if (key === "boxShadow") {
971
+ const raw = flat.boxShadow;
972
+ if (raw !== void 0) {
973
+ styleRestingShadow = normalizeBoxShadow(raw);
974
+ styleResting.boxShadow = styleRestingShadow.layers;
975
+ }
976
+ continue;
977
+ }
569
978
  const v = styleValueFor(flat, key);
570
979
  if (v !== void 0) styleResting[key] = v;
571
980
  }
572
981
  }
573
982
  }
983
+ const boxShadowSeedRef = react.useRef(null);
984
+ if (boxShadowSeedRef.current === null) {
985
+ const source = initial === false ? animateRecord.boxShadow : initialRecord?.boxShadow ?? animateRecord.boxShadow;
986
+ boxShadowSeedRef.current = source !== void 0 ? normalizeBoxShadow(source) : styleRestingShadow ?? {
987
+ layers: [...NO_BOX_SHADOW],
988
+ insets: null
989
+ };
990
+ }
574
991
  const sharedValues = useAnimatableSharedValues((key) => {
992
+ if (key === "boxShadow") return boxShadowSeedRef.current.layers;
575
993
  if (SHADOW_OFFSET_KEY_SET.has(key)) {
576
994
  const axis = shadowOffsetAxisFor(key);
577
995
  if (initial === false) {
@@ -588,11 +1006,17 @@ function createMotionComponent(Component) {
588
1006
  }
589
1007
  return initialRecord?.[key] ?? restValue(animateRecord[key]) ?? styleResting[key] ?? DEFAULT_RESTING[key];
590
1008
  });
591
- const styleRestingSig = chunkPTRF47DA_js.stableSig(styleResting);
1009
+ const boxShadowInsets = Animated.useSharedValue(
1010
+ boxShadowSeedRef.current.insets
1011
+ );
1012
+ const styleRestingSig = chunkPM6CVGXJ_js.stableSig(styleResting);
592
1013
  react.useEffect(() => {
593
1014
  for (const key of activeKeysRef.current) {
594
1015
  if (everDrivenRef.current.has(key)) continue;
595
1016
  sharedValues[key].value = styleResting[key] ?? DEFAULT_RESTING[key];
1017
+ if (key === "boxShadow") {
1018
+ boxShadowInsets.value = styleRestingShadow?.insets ?? null;
1019
+ }
596
1020
  }
597
1021
  }, [styleRestingSig]);
598
1022
  const pressedProgress = Animated.useSharedValue(0);
@@ -613,13 +1037,13 @@ function createMotionComponent(Component) {
613
1037
  const gestureSV = Animated.useSharedValue(
614
1038
  resolveGestureLayers(gesture)
615
1039
  );
616
- const gestureTargetsSig = chunkPTRF47DA_js.stableSig(gesture);
1040
+ const gestureTargetsSig = chunkPM6CVGXJ_js.stableSig(gesture);
617
1041
  react.useEffect(() => {
618
1042
  gestureSV.value = resolveGestureLayers(gesture);
619
1043
  }, [gestureTargetsSig]);
620
1044
  const baseRecord = isExiting && exitRecord ? { ...animateRecord, ...exitRecord } : animateRecord;
621
- const baseSig = chunkPTRF47DA_js.stableSig(baseRecord) + (isExiting ? "|exit" : "") + (shouldReduceMotion ? "|rm" : "");
622
- const transitionSig = chunkPTRF47DA_js.stableSig(transition);
1045
+ const baseSig = chunkPM6CVGXJ_js.stableSig(baseRecord) + (isExiting ? "|exit" : "") + (shouldReduceMotion ? "|rm" : "");
1046
+ const transitionSig = chunkPM6CVGXJ_js.stableSig(transition);
623
1047
  const safeToRemoveRef = react.useRef(void 0);
624
1048
  safeToRemoveRef.current = presence?.safeToRemove;
625
1049
  react.useEffect(() => {
@@ -649,6 +1073,30 @@ function createMotionComponent(Component) {
649
1073
  }
650
1074
  const transformGroup = transformPending > 0 ? { remaining: transformPending } : void 0;
651
1075
  for (const key of ALL_KEYS) {
1076
+ if (key === "boxShadow") {
1077
+ const shadowTarget = baseRecord.boxShadow;
1078
+ if (shadowTarget === void 0) continue;
1079
+ const cfg2 = configFor("boxShadow");
1080
+ if (isExiting && reachesTerminalPhase(cfg2)) pending++;
1081
+ driveBoxShadow(
1082
+ sharedValues.boxShadow,
1083
+ boxShadowInsets,
1084
+ shadowTarget,
1085
+ cfg2,
1086
+ makeKeyCallbackFactory(
1087
+ "boxShadow",
1088
+ sharedValues.boxShadow,
1089
+ // The declared target, not the padded one — the padding is an
1090
+ // implementation detail of getting Reanimated to interpolate.
1091
+ shadowTarget,
1092
+ onAnimationEndRef,
1093
+ { stepCount: 1, totalIterations: totalIterationsOf(cfg2) },
1094
+ isExiting ? onSettle : void 0,
1095
+ void 0
1096
+ )
1097
+ );
1098
+ continue;
1099
+ }
652
1100
  const target = SHADOW_OFFSET_KEY_SET.has(key) ? shadowOffsetAxisValue(
653
1101
  baseRecord.shadowOffset,
654
1102
  shadowOffsetAxisFor(key)
@@ -668,7 +1116,7 @@ function createMotionComponent(Component) {
668
1116
  isExiting ? onSettle : void 0,
669
1117
  TRANSFORM_KEY_SET.has(key) ? transformGroup : void 0
670
1118
  );
671
- sharedValues[key].value = chunkPTRF47DA_js.resolveAnimatableValue(
1119
+ sharedValues[key].value = chunkPM6CVGXJ_js.resolveAnimatableValue(
672
1120
  target,
673
1121
  cfg,
674
1122
  factory
@@ -714,19 +1162,34 @@ function createMotionComponent(Component) {
714
1162
  isExiting,
715
1163
  shouldReduceMotion
716
1164
  );
1165
+ const readSharedStyles = () => {
1166
+ if (!hasLayoutId) return void 0;
1167
+ const out = {};
1168
+ let any = false;
1169
+ for (const key of activeKeysRef.current) {
1170
+ if (!SHARED_STYLE_KEY_SET.has(key)) continue;
1171
+ const v = sharedValues[key].value;
1172
+ if (typeof v !== "number" && typeof v !== "string") continue;
1173
+ out[key] = v;
1174
+ any = true;
1175
+ }
1176
+ return any ? out : void 0;
1177
+ };
717
1178
  const sharedLayout = useSharedLayout({
718
1179
  layoutId,
719
1180
  userRef: ref,
720
- transition: chunkPTRF47DA_js.isTopLevelTransition(transition) ? transition : void 0,
1181
+ transition: chunkPM6CVGXJ_js.isTopLevelTransition(transition) ? transition : void 0,
721
1182
  shouldReduceMotion,
722
- userOnLayout
1183
+ userOnLayout,
1184
+ readStyles: readSharedStyles
723
1185
  });
724
1186
  const flip = sharedLayout.flip;
725
- const hasLayoutId = layoutId !== void 0;
1187
+ const carry = sharedLayout.carry;
726
1188
  const animatedStyle = Animated.useAnimatedStyle(() => {
727
1189
  const activeKeys2 = activeKeysRef.current;
728
1190
  const hasTransform = hasTransformRef.current;
729
1191
  const hasShadowOffset = hasShadowOffsetRef.current;
1192
+ const hasBoxShadow = hasBoxShadowRef.current;
730
1193
  const out = {};
731
1194
  const transform = [];
732
1195
  let shadowOffsetW = 0;
@@ -735,12 +1198,15 @@ function createMotionComponent(Component) {
735
1198
  const pf = focusedProgress.value;
736
1199
  const pfv = focusVisibleProgress.value;
737
1200
  const pp = pressedProgress.value;
1201
+ const carried = carry.snapshot.value;
1202
+ const pc = carry.progress.value;
738
1203
  const layers = gestureSV.value;
739
1204
  const hoveredLayer = layers ? layers.hovered : null;
740
1205
  const focusedLayer = layers ? layers.focused : null;
741
1206
  const focusVisibleLayer = layers ? layers.focusVisible : null;
742
1207
  const pressedLayer = layers ? layers.pressed : null;
743
1208
  for (const key of activeKeys2) {
1209
+ if (key === "boxShadow") continue;
744
1210
  let v = sharedValues[key].value;
745
1211
  const isColor = COLOR_KEY_SET.has(key);
746
1212
  if (hoveredLayer && ph > 0 && hoveredLayer[key] !== void 0) {
@@ -759,6 +1225,12 @@ function createMotionComponent(Component) {
759
1225
  const t = pressedLayer[key];
760
1226
  v = isColor ? Animated.interpolateColor(pp, [0, 1], [v, t]) : v + (t - v) * pp;
761
1227
  }
1228
+ if (carried !== null && pc > 0) {
1229
+ const s = carried[key];
1230
+ if (s !== void 0) {
1231
+ v = isColor ? Animated.interpolateColor(pc, [0, 1], [v, s]) : v + (s - v) * pc;
1232
+ }
1233
+ }
762
1234
  if (TRANSFORM_KEY_SET.has(key)) {
763
1235
  transform.push(
764
1236
  ROTATION_KEYS.has(key) ? { [key]: `${v}deg` } : { [key]: v }
@@ -781,6 +1253,19 @@ function createMotionComponent(Component) {
781
1253
  if (hasShadowOffset) {
782
1254
  out.shadowOffset = { width: shadowOffsetW, height: shadowOffsetH };
783
1255
  }
1256
+ if (hasBoxShadow) {
1257
+ const layers2 = sharedValues.boxShadow.value;
1258
+ const insets = boxShadowInsets.value;
1259
+ if (insets === null) {
1260
+ out.boxShadow = layers2;
1261
+ } else {
1262
+ const withInset = [];
1263
+ for (let i = 0; i < layers2.length; i++) {
1264
+ withInset.push({ ...layers2[i], inset: insets[i] });
1265
+ }
1266
+ out.boxShadow = withInset;
1267
+ }
1268
+ }
784
1269
  return out;
785
1270
  });
786
1271
  const mergedStyle = react.useMemo(
@@ -795,7 +1280,7 @@ function createMotionComponent(Component) {
795
1280
  setFocusVisible,
796
1281
  setHovered
797
1282
  );
798
- const layoutSig = chunkPTRF47DA_js.stableSig(layout);
1283
+ const layoutSig = chunkPM6CVGXJ_js.stableSig(layout);
799
1284
  const layoutTransition = react.useMemo(
800
1285
  () => shouldReduceMotion ? void 0 : resolveLayoutTransition(layout),
801
1286
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -843,60 +1328,15 @@ function hasMotionProps(props) {
843
1328
  return false;
844
1329
  }
845
1330
  function useAnimatableSharedValues(init) {
846
- const translateX = Animated.useSharedValue(init("translateX"));
847
- const translateY = Animated.useSharedValue(init("translateY"));
848
- const scale = Animated.useSharedValue(init("scale"));
849
- const scaleX = Animated.useSharedValue(init("scaleX"));
850
- const scaleY = Animated.useSharedValue(init("scaleY"));
851
- const rotate = Animated.useSharedValue(init("rotate"));
852
- const rotateX = Animated.useSharedValue(init("rotateX"));
853
- const rotateY = Animated.useSharedValue(init("rotateY"));
854
- const opacity = Animated.useSharedValue(init("opacity"));
855
- const width = Animated.useSharedValue(init("width"));
856
- const height = Animated.useSharedValue(init("height"));
857
- const borderRadius = Animated.useSharedValue(init("borderRadius"));
858
- const shadowOpacity = Animated.useSharedValue(init("shadowOpacity"));
859
- const shadowRadius = Animated.useSharedValue(init("shadowRadius"));
860
- const elevation = Animated.useSharedValue(init("elevation"));
861
- const backgroundColor = Animated.useSharedValue(
862
- init("backgroundColor")
863
- );
864
- const borderColor = Animated.useSharedValue(init("borderColor"));
865
- const color = Animated.useSharedValue(init("color"));
866
- const tintColor = Animated.useSharedValue(init("tintColor"));
867
- const shadowColor = Animated.useSharedValue(init("shadowColor"));
868
- const shadowOffsetWidth = Animated.useSharedValue(
869
- init("shadowOffsetWidth")
870
- );
871
- const shadowOffsetHeight = Animated.useSharedValue(
872
- init("shadowOffsetHeight")
873
- );
1331
+ const entries = [];
1332
+ for (const key of ALL_KEYS) {
1333
+ entries.push([key, Animated.useSharedValue(init(key))]);
1334
+ }
874
1335
  const ref = react.useRef(null);
875
1336
  if (ref.current === null) {
876
- ref.current = {
877
- translateX,
878
- translateY,
879
- scale,
880
- scaleX,
881
- scaleY,
882
- rotate,
883
- rotateX,
884
- rotateY,
885
- opacity,
886
- width,
887
- height,
888
- borderRadius,
889
- shadowOpacity,
890
- shadowRadius,
891
- elevation,
892
- backgroundColor,
893
- borderColor,
894
- color,
895
- tintColor,
896
- shadowColor,
897
- shadowOffsetWidth,
898
- shadowOffsetHeight
899
- };
1337
+ const map2 = {};
1338
+ for (const [key, sv] of entries) map2[key] = sv;
1339
+ ref.current = map2;
900
1340
  }
901
1341
  const map = ref.current;
902
1342
  react.useEffect(
@@ -980,6 +1420,20 @@ function shadowOffsetAxisFor(key) {
980
1420
  function shadowOffsetAxisValue(source, axis) {
981
1421
  return source?.[axis];
982
1422
  }
1423
+ function driveBoxShadow(slot, insetSlot, target, cfg, factory) {
1424
+ const currentLayers = Array.isArray(slot.value) ? slot.value : NO_BOX_SHADOW;
1425
+ const { from, to, insets } = prepareBoxShadowAnimation(
1426
+ { layers: [...currentLayers], insets: insetSlot.value },
1427
+ target
1428
+ );
1429
+ insetSlot.value = insets;
1430
+ if (from.length !== currentLayers.length) slot.value = from;
1431
+ slot.value = chunkPM6CVGXJ_js.resolveTransition(
1432
+ cfg,
1433
+ to,
1434
+ factory?.("animation", void 0)
1435
+ );
1436
+ }
983
1437
  function styleValueFor(flat, key) {
984
1438
  if (SHADOW_OFFSET_KEY_SET.has(key)) {
985
1439
  return shadowOffsetAxisValue(
@@ -1096,6 +1550,15 @@ function resolveGestureLayers(gesture) {
1096
1550
  if (!subState) continue;
1097
1551
  const resolved = {};
1098
1552
  for (const key of ALL_KEYS) {
1553
+ if (STRUCTURED_KEY_SET.has(key)) {
1554
+ if (__DEV__ && subState[key] !== void 0) {
1555
+ chunkPM6CVGXJ_js.warnOnce(
1556
+ `gesture-structured-${layer}-${key}`,
1557
+ `[inertia] \`${key}\` is not supported inside \`gesture.${layer}\` and will be ignored. Drive it from \`animate\` (optionally via a variant keyed off the same state), or interpolate it yourself with \`useShadow\`.`
1558
+ );
1559
+ }
1560
+ continue;
1561
+ }
1099
1562
  if (SHADOW_OFFSET_KEY_SET.has(key)) {
1100
1563
  const axis = shadowOffsetAxisFor(key);
1101
1564
  const so = subState.shadowOffset;
@@ -1113,7 +1576,7 @@ function resolveGestureLayers(gesture) {
1113
1576
  return out;
1114
1577
  }
1115
1578
  function useGestureLayerProgress(progress, active, declared, layer, transition, isExiting, shouldReduceMotion) {
1116
- const layerCfgSig = chunkPTRF47DA_js.stableSig(gestureLayerTransitionFor(layer, transition));
1579
+ const layerCfgSig = chunkPM6CVGXJ_js.stableSig(gestureLayerTransitionFor(layer, transition));
1117
1580
  react.useEffect(() => {
1118
1581
  if (!declared) return;
1119
1582
  if (isExiting) {
@@ -1122,7 +1585,7 @@ function useGestureLayerProgress(progress, active, declared, layer, transition,
1122
1585
  }
1123
1586
  const target = active ? 1 : 0;
1124
1587
  const cfg = shouldReduceMotion ? { type: "no-animation" } : gestureLayerTransitionFor(layer, transition) ?? { type: "spring" };
1125
- progress.value = chunkPTRF47DA_js.resolveTransition(cfg, target);
1588
+ progress.value = chunkPM6CVGXJ_js.resolveTransition(cfg, target);
1126
1589
  }, [active, declared, isExiting, shouldReduceMotion, layerCfgSig]);
1127
1590
  }
1128
1591
  function useGestureHandlers(gesture, rest, setPressed, setFocused, setFocusVisible, setHovered) {
@@ -1146,7 +1609,7 @@ function useGestureHandlers(gesture, rest, setPressed, setFocused, setFocusVisib
1146
1609
  if (gesture.focused || gesture.focusVisible) {
1147
1610
  handlers.onFocus = compose(rest.onFocus, () => {
1148
1611
  if (gesture.focused) setFocused(true);
1149
- if (gesture.focusVisible && chunk7AOERN53_js.isFocusVisible()) setFocusVisible(true);
1612
+ if (gesture.focusVisible && chunkOBRGJAST_js.isFocusVisible()) setFocusVisible(true);
1150
1613
  });
1151
1614
  handlers.onBlur = compose(rest.onBlur, () => {
1152
1615
  if (gesture.focused) setFocused(false);
@@ -1187,4 +1650,6 @@ function compose(user, ours) {
1187
1650
 
1188
1651
  exports.Presence = Presence;
1189
1652
  exports.createMotionComponent = createMotionComponent;
1653
+ exports.pairBoxShadowLayers = pairBoxShadowLayers;
1654
+ exports.resolveBoxShadowInput = resolveBoxShadowInput;
1190
1655
  exports.usePresence = usePresence;