@onlynative/inertia 0.0.1-alpha.0

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 (63) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/LICENSE +21 -0
  3. package/README.md +90 -0
  4. package/dist/index.d.mts +185 -0
  5. package/dist/index.d.ts +185 -0
  6. package/dist/index.js +817 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/index.mjs +796 -0
  9. package/dist/index.mjs.map +1 -0
  10. package/dist/motion/Image.d.mts +12 -0
  11. package/dist/motion/Image.d.ts +12 -0
  12. package/dist/motion/Image.js +656 -0
  13. package/dist/motion/Image.js.map +1 -0
  14. package/dist/motion/Image.mjs +650 -0
  15. package/dist/motion/Image.mjs.map +1 -0
  16. package/dist/motion/Pressable.d.mts +15 -0
  17. package/dist/motion/Pressable.d.ts +15 -0
  18. package/dist/motion/Pressable.js +656 -0
  19. package/dist/motion/Pressable.js.map +1 -0
  20. package/dist/motion/Pressable.mjs +650 -0
  21. package/dist/motion/Pressable.mjs.map +1 -0
  22. package/dist/motion/ScrollView.d.mts +12 -0
  23. package/dist/motion/ScrollView.d.ts +12 -0
  24. package/dist/motion/ScrollView.js +656 -0
  25. package/dist/motion/ScrollView.js.map +1 -0
  26. package/dist/motion/ScrollView.mjs +650 -0
  27. package/dist/motion/ScrollView.mjs.map +1 -0
  28. package/dist/motion/Text.d.mts +11 -0
  29. package/dist/motion/Text.d.ts +11 -0
  30. package/dist/motion/Text.js +656 -0
  31. package/dist/motion/Text.js.map +1 -0
  32. package/dist/motion/Text.mjs +650 -0
  33. package/dist/motion/Text.mjs.map +1 -0
  34. package/dist/motion/View.d.mts +11 -0
  35. package/dist/motion/View.d.ts +11 -0
  36. package/dist/motion/View.js +656 -0
  37. package/dist/motion/View.js.map +1 -0
  38. package/dist/motion/View.mjs +650 -0
  39. package/dist/motion/View.mjs.map +1 -0
  40. package/dist/types-CmbXx-G3.d.mts +185 -0
  41. package/dist/types-CmbXx-G3.d.ts +185 -0
  42. package/llms.txt +78 -0
  43. package/package.json +120 -0
  44. package/src/config/MotionConfig.tsx +30 -0
  45. package/src/config/MotionConfigContext.ts +53 -0
  46. package/src/config/index.ts +9 -0
  47. package/src/index.ts +49 -0
  48. package/src/motion/Image.tsx +9 -0
  49. package/src/motion/Pressable.tsx +12 -0
  50. package/src/motion/ScrollView.tsx +9 -0
  51. package/src/motion/Text.tsx +8 -0
  52. package/src/motion/View.tsx +8 -0
  53. package/src/motion/createMotionComponent.tsx +850 -0
  54. package/src/motion/index.ts +26 -0
  55. package/src/presence/Presence.tsx +165 -0
  56. package/src/presence/PresenceContext.ts +28 -0
  57. package/src/presence/index.ts +6 -0
  58. package/src/transitions/easing.ts +29 -0
  59. package/src/transitions/index.ts +2 -0
  60. package/src/transitions/resolve.ts +265 -0
  61. package/src/types.ts +207 -0
  62. package/src/values/index.ts +1 -0
  63. package/src/values/useVariants.ts +60 -0
package/dist/index.mjs ADDED
@@ -0,0 +1,796 @@
1
+ import { Image, Pressable, ScrollView, Text, View } from 'react-native';
2
+ import { createContext, forwardRef, useRef, useState, useEffect, useMemo, useContext, Children, isValidElement, useCallback } from 'react';
3
+ import Animated, { useAnimatedStyle, useReducedMotion, useSharedValue, withSequence, runOnJS, withRepeat, withDelay, withDecay, withTiming, Easing, withSpring, isWorkletFunction } from 'react-native-reanimated';
4
+ import { jsx, Fragment } from 'react/jsx-runtime';
5
+
6
+ // src/motion/Image.tsx
7
+ var DEFAULT_MOTION_CONFIG = {
8
+ reducedMotion: "user"
9
+ };
10
+ var MotionConfigContext = createContext(
11
+ DEFAULT_MOTION_CONFIG
12
+ );
13
+ function useMotionConfig() {
14
+ return useContext(MotionConfigContext);
15
+ }
16
+ function useShouldReduceMotion() {
17
+ const { reducedMotion } = useMotionConfig();
18
+ const osReduced = useReducedMotion();
19
+ if (reducedMotion === "never") return false;
20
+ if (reducedMotion === "always") return true;
21
+ return osReduced;
22
+ }
23
+ function MotionConfig({
24
+ reducedMotion = "user",
25
+ children
26
+ }) {
27
+ const value = useMemo(
28
+ () => ({ reducedMotion }),
29
+ [reducedMotion]
30
+ );
31
+ return /* @__PURE__ */ jsx(MotionConfigContext.Provider, { value, children });
32
+ }
33
+ var PresenceContext = createContext(null);
34
+ function usePresence() {
35
+ return useContext(PresenceContext);
36
+ }
37
+ function Presence({ children }) {
38
+ const incoming = useMemo(() => {
39
+ const out = [];
40
+ Children.forEach(children, (child) => {
41
+ if (!isValidElement(child)) return;
42
+ if (child.key === null) {
43
+ if (__DEV__) {
44
+ console.warn(
45
+ "[inertia] <Presence> children must have a `key`. Skipping a keyless child."
46
+ );
47
+ }
48
+ return;
49
+ }
50
+ out.push(child);
51
+ });
52
+ return out;
53
+ }, [children]);
54
+ const [exiting, setExiting] = useState(
55
+ () => /* @__PURE__ */ new Map()
56
+ );
57
+ const prevIncomingRef = useRef(incoming);
58
+ if (prevIncomingRef.current !== incoming) {
59
+ const prev = prevIncomingRef.current;
60
+ prevIncomingRef.current = incoming;
61
+ const incomingKeys = new Set(incoming.map((el) => el.key));
62
+ let next = null;
63
+ const ensureMutable = () => {
64
+ if (!next) next = new Map(exiting);
65
+ return next;
66
+ };
67
+ for (const oldEl of prev) {
68
+ const key = oldEl.key;
69
+ if (!incomingKeys.has(key) && !exiting.has(key)) {
70
+ ensureMutable().set(key, oldEl);
71
+ }
72
+ }
73
+ for (const el of incoming) {
74
+ const key = el.key;
75
+ if (exiting.has(key)) {
76
+ ensureMutable().delete(key);
77
+ }
78
+ }
79
+ if (next) setExiting(next);
80
+ }
81
+ const handleRemove = useCallback((key) => {
82
+ setExiting((prev) => {
83
+ if (!prev.has(key)) return prev;
84
+ const next = new Map(prev);
85
+ next.delete(key);
86
+ return next;
87
+ });
88
+ }, []);
89
+ const renderList = [];
90
+ for (const el of incoming) {
91
+ renderList.push({
92
+ key: el.key,
93
+ element: el,
94
+ isPresent: true
95
+ });
96
+ }
97
+ for (const [key, el] of exiting) {
98
+ if (!renderList.some((entry) => entry.key === key)) {
99
+ renderList.push({ key, element: el, isPresent: false });
100
+ }
101
+ }
102
+ return /* @__PURE__ */ jsx(Fragment, { children: renderList.map(({ key, element, isPresent }) => /* @__PURE__ */ jsx(
103
+ PresenceItem,
104
+ {
105
+ itemKey: key,
106
+ isPresent,
107
+ onRemove: handleRemove,
108
+ children: element
109
+ },
110
+ key
111
+ )) });
112
+ }
113
+ function PresenceItem({
114
+ itemKey,
115
+ isPresent,
116
+ onRemove,
117
+ children
118
+ }) {
119
+ const value = useMemo(
120
+ () => ({
121
+ isPresent,
122
+ safeToRemove: () => onRemove(itemKey)
123
+ }),
124
+ [isPresent, itemKey, onRemove]
125
+ );
126
+ return /* @__PURE__ */ jsx(PresenceContext.Provider, { value, children });
127
+ }
128
+ function ensureWorkletEasing(easing) {
129
+ if (!easing) return void 0;
130
+ if (isWorkletFunction(easing)) return easing;
131
+ const wrapped = (t) => {
132
+ "worklet";
133
+ return easing(t);
134
+ };
135
+ return wrapped;
136
+ }
137
+
138
+ // src/transitions/resolve.ts
139
+ var DEFAULT_SPRING = {
140
+ tension: 170,
141
+ friction: 26,
142
+ mass: 1
143
+ };
144
+ var DEFAULT_TIMING_DURATION = 250;
145
+ function springToReanimated(t) {
146
+ return {
147
+ stiffness: t.tension ?? DEFAULT_SPRING.tension,
148
+ damping: t.friction ?? DEFAULT_SPRING.friction,
149
+ mass: t.mass ?? DEFAULT_SPRING.mass,
150
+ velocity: t.velocity,
151
+ restSpeedThreshold: t.restSpeedThreshold,
152
+ restDisplacementThreshold: t.restDisplacementThreshold
153
+ };
154
+ }
155
+ function buildSpring(cfg, toValue, cb) {
156
+ return withSpring(toValue, springToReanimated(cfg), cb);
157
+ }
158
+ function buildTiming(cfg, toValue, cb) {
159
+ return withTiming(
160
+ toValue,
161
+ {
162
+ duration: cfg.duration ?? DEFAULT_TIMING_DURATION,
163
+ easing: ensureWorkletEasing(cfg.easing) ?? Easing.inOut(Easing.ease)
164
+ },
165
+ cb
166
+ );
167
+ }
168
+ function buildDecay(cfg, cb) {
169
+ return withDecay(
170
+ {
171
+ velocity: cfg.velocity ?? 0,
172
+ deceleration: cfg.deceleration,
173
+ clamp: cfg.clamp
174
+ },
175
+ cb
176
+ );
177
+ }
178
+ function buildOne(cfg, toValue, cb) {
179
+ if (cfg.type === "no-animation") {
180
+ if (cb) cb(true, toValue);
181
+ return toValue;
182
+ }
183
+ if (cfg.type === "decay") return buildDecay(cfg, cb);
184
+ if (cfg.type === "timing") return buildTiming(cfg, toValue, cb);
185
+ return buildSpring(cfg, toValue, cb);
186
+ }
187
+ function applyRepeat(animation, repeat) {
188
+ if (repeat === void 0) return animation;
189
+ if (repeat === "infinite") {
190
+ return withRepeat(animation, -1, true);
191
+ }
192
+ if (typeof repeat === "number") {
193
+ return withRepeat(animation, repeat, true);
194
+ }
195
+ const count = repeat.count === "infinite" ? -1 : repeat.count;
196
+ const alternate = repeat.alternate ?? true;
197
+ return withRepeat(animation, count, alternate);
198
+ }
199
+ function applyDelay(animation, delay) {
200
+ if (!delay || delay <= 0) return animation;
201
+ return withDelay(delay, animation);
202
+ }
203
+ function resolveTransition(config, toValue, callback) {
204
+ const cfg = config ?? { type: "spring" };
205
+ const base = buildOne(cfg, toValue, callback);
206
+ const repeated = applyRepeat(base, repeatOf(cfg));
207
+ return applyDelay(repeated, delayOf(cfg));
208
+ }
209
+ function repeatOf(cfg) {
210
+ if (cfg.type === "no-animation" || cfg.type === "decay") return void 0;
211
+ return cfg.repeat;
212
+ }
213
+ function stripRepeat(cfg) {
214
+ if (!cfg) return cfg;
215
+ if (cfg.type === "no-animation" || cfg.type === "decay") return cfg;
216
+ if (cfg.repeat === void 0) return cfg;
217
+ const next = { ...cfg };
218
+ delete next.repeat;
219
+ return next;
220
+ }
221
+ function delayOf(cfg) {
222
+ if (cfg.type === "no-animation") return void 0;
223
+ return cfg.delay;
224
+ }
225
+ function isStepObject(v) {
226
+ return typeof v === "object" && v !== null && !Array.isArray(v) && "to" in v;
227
+ }
228
+ function resolveAnimatableValue(value, base, factory) {
229
+ if (Array.isArray(value)) {
230
+ const steps = value;
231
+ const stepBase = stripRepeat(base);
232
+ const animations = steps.map(
233
+ (step2, i) => resolveStep(step2, stepBase, factory?.("step", i))
234
+ );
235
+ const seq = withSequence(...animations);
236
+ return applyRepeat(seq, base ? repeatOf(base) : void 0);
237
+ }
238
+ const step = value;
239
+ const cb = factory?.("animation", void 0);
240
+ if (isStepObject(step)) {
241
+ return resolveStep(step, base, cb);
242
+ }
243
+ return resolveTransition(base, step, cb);
244
+ }
245
+ function resolveStep(step, base, cb) {
246
+ if (isStepObject(step)) {
247
+ const { to, ...override } = step;
248
+ const merged = mergeTransition(base, override);
249
+ return resolveTransition(merged, to, cb);
250
+ }
251
+ return resolveTransition(base, step, cb);
252
+ }
253
+ function mergeTransition(base, override) {
254
+ if (override.type && base && override.type !== base.type) {
255
+ return override;
256
+ }
257
+ return { ...base ?? { type: "spring" }, ...override };
258
+ }
259
+ var TRANSFORM_KEYS = [
260
+ "translateX",
261
+ "translateY",
262
+ "scale",
263
+ "scaleX",
264
+ "scaleY",
265
+ "rotate"
266
+ ];
267
+ var TOP_LEVEL_KEYS = ["opacity", "width", "height", "borderRadius"];
268
+ var ALL_KEYS = [...TRANSFORM_KEYS, ...TOP_LEVEL_KEYS];
269
+ var TRANSFORM_KEY_SET = new Set(TRANSFORM_KEYS);
270
+ var EXITING_POINTER_EVENTS_STYLE = { pointerEvents: "none" };
271
+ var DEFAULT_RESTING = {
272
+ translateX: 0,
273
+ translateY: 0,
274
+ scale: 1,
275
+ scaleX: 1,
276
+ scaleY: 1,
277
+ rotate: 0,
278
+ opacity: 1,
279
+ width: 0,
280
+ height: 0,
281
+ borderRadius: 0
282
+ };
283
+ var TRANSITION_KEYS = /* @__PURE__ */ new Set([
284
+ "type",
285
+ "tension",
286
+ "friction",
287
+ "mass",
288
+ "velocity",
289
+ "restSpeedThreshold",
290
+ "restDisplacementThreshold",
291
+ "duration",
292
+ "easing",
293
+ "delay",
294
+ "repeat",
295
+ "deceleration",
296
+ "clamp"
297
+ ]);
298
+ function isTopLevelTransition(t) {
299
+ if (t === null || typeof t !== "object") return false;
300
+ const keys = Object.keys(t);
301
+ if (keys.length === 0) return false;
302
+ return keys.every((k) => TRANSITION_KEYS.has(k));
303
+ }
304
+ function transitionFor(prop, transition) {
305
+ if (!transition) return void 0;
306
+ if (isTopLevelTransition(transition)) return transition;
307
+ return transition[prop];
308
+ }
309
+ function createMotionComponent(Component) {
310
+ const AnimatedComponent = Animated.createAnimatedComponent(
311
+ Component
312
+ );
313
+ const Motion2 = forwardRef(function Motion3(props, ref) {
314
+ const {
315
+ initial,
316
+ animate,
317
+ exit,
318
+ transition,
319
+ variants,
320
+ controller,
321
+ gesture,
322
+ onAnimationEnd,
323
+ style,
324
+ ...rest
325
+ } = props;
326
+ const presence = usePresence();
327
+ const isExiting = presence !== null && presence.isPresent === false;
328
+ const shouldReduceMotion = useShouldReduceMotion();
329
+ const onAnimationEndRef = useRef(onAnimationEnd);
330
+ onAnimationEndRef.current = onAnimationEnd;
331
+ const variantKey = useControllerKey(controller);
332
+ const resolvedAnimate = resolveAnimateInput(
333
+ animate,
334
+ variants,
335
+ variantKey
336
+ );
337
+ const animateRecord = resolvedAnimate ?? {};
338
+ const initialRecord = initial && initial !== false ? initial : void 0;
339
+ const exitRecord = exit ? exit : void 0;
340
+ const [pressed, setPressed] = useState(false);
341
+ const [focused, setFocused] = useState(false);
342
+ const [hovered, setHovered] = useState(false);
343
+ const activeKeysRef = useRef(null);
344
+ if (activeKeysRef.current === null) {
345
+ const touched = /* @__PURE__ */ new Set();
346
+ for (const k of ALL_KEYS) {
347
+ if (k in animateRecord) touched.add(k);
348
+ if (initialRecord && k in initialRecord) touched.add(k);
349
+ }
350
+ if (variants) {
351
+ for (const variant of Object.values(variants)) {
352
+ if (!variant) continue;
353
+ for (const k of ALL_KEYS) {
354
+ if (k in variant) touched.add(k);
355
+ }
356
+ }
357
+ }
358
+ if (gesture) {
359
+ for (const subState of [
360
+ gesture.pressed,
361
+ gesture.focused,
362
+ gesture.hovered
363
+ ]) {
364
+ if (!subState) continue;
365
+ for (const k of ALL_KEYS) {
366
+ if (k in subState) touched.add(k);
367
+ }
368
+ }
369
+ }
370
+ if (exitRecord) {
371
+ for (const k of ALL_KEYS) {
372
+ if (k in exitRecord) touched.add(k);
373
+ }
374
+ }
375
+ activeKeysRef.current = ALL_KEYS.filter((k) => touched.has(k));
376
+ }
377
+ const hasTransformRef = useRef(
378
+ activeKeysRef.current.some((k) => TRANSFORM_KEY_SET.has(k))
379
+ );
380
+ const sharedValues = useAnimatableSharedValues((key) => {
381
+ if (initial === false) {
382
+ const a = animateRecord[key];
383
+ return restValue(a) ?? DEFAULT_RESTING[key];
384
+ }
385
+ return initialRecord?.[key] ?? restValue(animateRecord[key]) ?? DEFAULT_RESTING[key];
386
+ });
387
+ const mergedRecord = isExiting && exitRecord ? { ...animateRecord, ...exitRecord } : mergeGestureTargets(animateRecord, gesture, {
388
+ pressed,
389
+ focused,
390
+ hovered
391
+ });
392
+ const mergedSig = stableSig(mergedRecord) + (isExiting ? "|exit" : "") + (shouldReduceMotion ? "|rm" : "");
393
+ const transitionSig = stableSig(transition);
394
+ const safeToRemoveRef = useRef(void 0);
395
+ safeToRemoveRef.current = presence?.safeToRemove;
396
+ useEffect(() => {
397
+ if (isExiting && (!exitRecord || Object.keys(exitRecord).length === 0)) {
398
+ safeToRemoveRef.current?.();
399
+ return;
400
+ }
401
+ let pending = 0;
402
+ let done = false;
403
+ const onSettle = () => {
404
+ if (done) return;
405
+ pending--;
406
+ if (pending <= 0) {
407
+ done = true;
408
+ if (isExiting) safeToRemoveRef.current?.();
409
+ }
410
+ };
411
+ let transformPending = 0;
412
+ for (const k of ALL_KEYS) {
413
+ if (TRANSFORM_KEY_SET.has(k) && mergedRecord[k] !== void 0) {
414
+ transformPending++;
415
+ }
416
+ }
417
+ const transformGroup = transformPending > 0 ? { remaining: transformPending } : void 0;
418
+ for (const key of ALL_KEYS) {
419
+ const target = mergedRecord[key];
420
+ if (target === void 0) continue;
421
+ const cfg = shouldReduceMotion ? { type: "no-animation" } : transitionFor(key, transition);
422
+ if (isExiting) pending++;
423
+ const factory = makeKeyCallbackFactory(
424
+ key,
425
+ sharedValues[key],
426
+ targetEndValue(target),
427
+ onAnimationEndRef,
428
+ {
429
+ stepCount: stepCountOf(target),
430
+ totalIterations: totalIterationsOf(cfg)
431
+ },
432
+ isExiting ? onSettle : void 0,
433
+ TRANSFORM_KEY_SET.has(key) ? transformGroup : void 0
434
+ );
435
+ sharedValues[key].value = resolveAnimatableValue(
436
+ target,
437
+ cfg,
438
+ factory
439
+ );
440
+ }
441
+ if (isExiting && pending === 0) {
442
+ safeToRemoveRef.current?.();
443
+ }
444
+ }, [mergedSig, transitionSig]);
445
+ const animatedStyle = useAnimatedStyle(() => {
446
+ const activeKeys = activeKeysRef.current;
447
+ const hasTransform = hasTransformRef.current;
448
+ const out = {};
449
+ const transform = [];
450
+ for (const key of activeKeys) {
451
+ const v = sharedValues[key].value;
452
+ if (TRANSFORM_KEY_SET.has(key)) {
453
+ transform.push(
454
+ key === "rotate" ? { rotate: `${v}deg` } : { [key]: v }
455
+ );
456
+ } else {
457
+ out[key] = v;
458
+ }
459
+ }
460
+ if (hasTransform) out.transform = transform;
461
+ return out;
462
+ });
463
+ const mergedStyle = useMemo(
464
+ () => isExiting ? [style, animatedStyle, EXITING_POINTER_EVENTS_STYLE] : [style, animatedStyle],
465
+ [style, animatedStyle, isExiting]
466
+ );
467
+ const gestureHandlers = useGestureHandlers(
468
+ gesture,
469
+ rest,
470
+ setPressed,
471
+ setFocused,
472
+ setHovered
473
+ );
474
+ return /* @__PURE__ */ jsx(
475
+ AnimatedComponent,
476
+ {
477
+ ref,
478
+ ...rest,
479
+ ...gestureHandlers,
480
+ style: mergedStyle
481
+ }
482
+ );
483
+ });
484
+ Motion2.displayName = `Motion(${Component.displayName ?? Component.name ?? "Component"})`;
485
+ return Motion2;
486
+ }
487
+ function useAnimatableSharedValues(init) {
488
+ const translateX = useSharedValue(init("translateX"));
489
+ const translateY = useSharedValue(init("translateY"));
490
+ const scale = useSharedValue(init("scale"));
491
+ const scaleX = useSharedValue(init("scaleX"));
492
+ const scaleY = useSharedValue(init("scaleY"));
493
+ const rotate = useSharedValue(init("rotate"));
494
+ const opacity = useSharedValue(init("opacity"));
495
+ const width = useSharedValue(init("width"));
496
+ const height = useSharedValue(init("height"));
497
+ const borderRadius = useSharedValue(init("borderRadius"));
498
+ const ref = useRef(null);
499
+ if (ref.current === null) {
500
+ ref.current = {
501
+ translateX,
502
+ translateY,
503
+ scale,
504
+ scaleX,
505
+ scaleY,
506
+ rotate,
507
+ opacity,
508
+ width,
509
+ height,
510
+ borderRadius
511
+ };
512
+ }
513
+ return ref.current;
514
+ }
515
+ function makeKeyCallbackFactory(key, sharedValue, target, onAnimationEndRef, meta, onSettle, transformGroup) {
516
+ if (!onAnimationEndRef.current && !onSettle) return void 0;
517
+ const state = { iteration: 0 };
518
+ const isTransformKey = TRANSFORM_KEY_SET.has(key);
519
+ const dispatch = (rawPhase, step, finished, value) => {
520
+ const isLastIteration = state.iteration >= meta.totalIterations - 1;
521
+ let phase;
522
+ let isTerminal = false;
523
+ if (rawPhase === "step") {
524
+ const isLastInPass = step !== void 0 && step === meta.stepCount - 1;
525
+ if (!isLastInPass) {
526
+ phase = "step";
527
+ } else if (isLastIteration) {
528
+ phase = "animation";
529
+ isTerminal = true;
530
+ } else {
531
+ phase = "sequence";
532
+ }
533
+ } else if (isLastIteration) {
534
+ phase = "animation";
535
+ isTerminal = true;
536
+ } else {
537
+ phase = "repeat";
538
+ }
539
+ const reportedIteration = state.iteration;
540
+ if (phase === "sequence" || phase === "repeat") state.iteration++;
541
+ const fn = onAnimationEndRef.current;
542
+ if (fn) {
543
+ if (isTransformKey && transformGroup && phase === "animation") {
544
+ transformGroup.remaining--;
545
+ if (transformGroup.remaining <= 0) {
546
+ fn({
547
+ key: "transform",
548
+ finished,
549
+ value,
550
+ target,
551
+ phase,
552
+ step,
553
+ iteration: reportedIteration
554
+ });
555
+ }
556
+ } else {
557
+ fn({
558
+ key,
559
+ finished,
560
+ value,
561
+ target,
562
+ phase,
563
+ step,
564
+ iteration: reportedIteration
565
+ });
566
+ }
567
+ }
568
+ if (onSettle && isTerminal) onSettle();
569
+ };
570
+ return (rawPhase, step) => {
571
+ const cb = (finished) => {
572
+ "worklet";
573
+ runOnJS(dispatch)(rawPhase, step, !!finished, sharedValue.value);
574
+ };
575
+ return cb;
576
+ };
577
+ }
578
+ function stepCountOf(v) {
579
+ if (Array.isArray(v)) return v.length;
580
+ return 1;
581
+ }
582
+ function totalIterationsOf(cfg) {
583
+ if (!cfg || cfg.type === "no-animation" || cfg.type === "decay") return 1;
584
+ const r = cfg.repeat;
585
+ if (r === void 0) return 1;
586
+ if (r === "infinite") return Number.POSITIVE_INFINITY;
587
+ if (typeof r === "number") return r;
588
+ if (r.count === "infinite") return Number.POSITIVE_INFINITY;
589
+ return r.count;
590
+ }
591
+ function targetEndValue(v) {
592
+ if (v === void 0) return void 0;
593
+ if (typeof v === "number" || typeof v === "string") return v;
594
+ if (Array.isArray(v)) {
595
+ return v.length > 0 ? targetEndValue(v[v.length - 1]) : void 0;
596
+ }
597
+ if (typeof v === "object" && v !== null && "to" in v) {
598
+ const to = v.to;
599
+ return typeof to === "number" || typeof to === "string" ? to : void 0;
600
+ }
601
+ return void 0;
602
+ }
603
+ function useControllerKey(controller) {
604
+ const [, setTick] = useState(0);
605
+ useEffect(() => {
606
+ if (!controller) return;
607
+ const unsub = controller.subscribe(() => setTick((n) => n + 1));
608
+ return unsub;
609
+ }, [controller]);
610
+ return controller?.current;
611
+ }
612
+ function resolveAnimateInput(animate, variants, controllerKey) {
613
+ if (controllerKey !== void 0 && variants && controllerKey in variants) {
614
+ return variants[controllerKey];
615
+ }
616
+ if (typeof animate === "string") {
617
+ if (variants && animate in variants) return variants[animate];
618
+ if (__DEV__) {
619
+ console.warn(
620
+ `[inertia] animate="${animate}" but no matching variant. Did you forget to pass \`variants\`?`
621
+ );
622
+ }
623
+ return void 0;
624
+ }
625
+ return animate;
626
+ }
627
+ function restValue(v) {
628
+ if (v === void 0) return void 0;
629
+ if (typeof v === "number") return v;
630
+ if (Array.isArray(v)) {
631
+ return v.length > 0 ? restValue(v[0]) : void 0;
632
+ }
633
+ if (typeof v === "object" && v !== null && "to" in v) {
634
+ const to = v.to;
635
+ return typeof to === "number" ? to : void 0;
636
+ }
637
+ return void 0;
638
+ }
639
+ function stableSig(value) {
640
+ if (value === void 0) return "";
641
+ try {
642
+ return stableStringify(value);
643
+ } catch {
644
+ return String(value);
645
+ }
646
+ }
647
+ function stableStringify(v) {
648
+ if (v === null || typeof v !== "object") {
649
+ if (typeof v === "function" || v === void 0) return "null";
650
+ return JSON.stringify(v);
651
+ }
652
+ if (Array.isArray(v)) {
653
+ return "[" + v.map(stableStringify).join(",") + "]";
654
+ }
655
+ const obj = v;
656
+ const keys = Object.keys(obj).sort();
657
+ return "{" + keys.map((k) => JSON.stringify(k) + ":" + stableStringify(obj[k])).join(",") + "}";
658
+ }
659
+ function mergeGestureTargets(base, gesture, active) {
660
+ if (!gesture) return base;
661
+ const merged = {
662
+ ...base
663
+ };
664
+ const subStates = [
665
+ gesture.hovered,
666
+ gesture.focused,
667
+ gesture.pressed
668
+ ];
669
+ for (const sub of subStates) {
670
+ if (!sub) continue;
671
+ for (const k of ALL_KEYS) {
672
+ if (k in sub && !(k in merged)) {
673
+ merged[k] = DEFAULT_RESTING[k];
674
+ }
675
+ }
676
+ }
677
+ if (active.hovered && gesture.hovered) {
678
+ Object.assign(
679
+ merged,
680
+ gesture.hovered
681
+ );
682
+ }
683
+ if (active.focused && gesture.focused) {
684
+ Object.assign(
685
+ merged,
686
+ gesture.focused
687
+ );
688
+ }
689
+ if (active.pressed && gesture.pressed) {
690
+ Object.assign(
691
+ merged,
692
+ gesture.pressed
693
+ );
694
+ }
695
+ return merged;
696
+ }
697
+ function useGestureHandlers(gesture, rest, setPressed, setFocused, setHovered) {
698
+ return useMemo(() => {
699
+ if (!gesture) return {};
700
+ const handlers = {};
701
+ if (gesture.pressed) {
702
+ handlers.onTouchStart = compose(rest.onTouchStart, () => setPressed(true));
703
+ handlers.onTouchEnd = compose(rest.onTouchEnd, () => setPressed(false));
704
+ handlers.onTouchCancel = compose(
705
+ rest.onTouchCancel,
706
+ () => setPressed(false)
707
+ );
708
+ handlers.onPressIn = compose(rest.onPressIn, () => setPressed(true));
709
+ handlers.onPressOut = compose(rest.onPressOut, () => setPressed(false));
710
+ }
711
+ if (gesture.focused) {
712
+ handlers.onFocus = compose(rest.onFocus, () => setFocused(true));
713
+ handlers.onBlur = compose(rest.onBlur, () => setFocused(false));
714
+ }
715
+ if (gesture.hovered) {
716
+ handlers.onMouseEnter = compose(rest.onMouseEnter, () => setHovered(true));
717
+ handlers.onMouseLeave = compose(
718
+ rest.onMouseLeave,
719
+ () => setHovered(false)
720
+ );
721
+ }
722
+ return handlers;
723
+ }, [
724
+ gesture?.pressed ? 1 : 0,
725
+ gesture?.focused ? 1 : 0,
726
+ gesture?.hovered ? 1 : 0,
727
+ rest.onTouchStart,
728
+ rest.onTouchEnd,
729
+ rest.onTouchCancel,
730
+ rest.onPressIn,
731
+ rest.onPressOut,
732
+ rest.onFocus,
733
+ rest.onBlur,
734
+ rest.onMouseEnter,
735
+ rest.onMouseLeave
736
+ ]);
737
+ }
738
+ function compose(user, ours) {
739
+ if (typeof user !== "function") return ours;
740
+ return (event) => {
741
+ user(event);
742
+ ours(event);
743
+ };
744
+ }
745
+
746
+ // src/motion/Image.tsx
747
+ var MotionImage = createMotionComponent(Image);
748
+ var MotionPressable = createMotionComponent(Pressable);
749
+ var MotionScrollView = createMotionComponent(ScrollView);
750
+ var MotionText = createMotionComponent(Text);
751
+ var MotionView = createMotionComponent(View);
752
+
753
+ // src/motion/index.ts
754
+ var Motion = {
755
+ View: MotionView,
756
+ Text: MotionText,
757
+ Image: MotionImage,
758
+ Pressable: MotionPressable,
759
+ ScrollView: MotionScrollView
760
+ };
761
+ function useVariants(variants, initial) {
762
+ const variantsRef = useRef(variants);
763
+ return useMemo(() => {
764
+ const listeners = /* @__PURE__ */ new Set();
765
+ let current = initial ?? (Object.keys(variantsRef.current)[0] ?? "");
766
+ const controller = {
767
+ get current() {
768
+ return current;
769
+ },
770
+ transitionTo(next) {
771
+ if (next === current) return;
772
+ if (!(next in variantsRef.current)) {
773
+ if (__DEV__) {
774
+ console.warn(
775
+ `[inertia] useVariants: unknown variant "${String(next)}". Known keys: ${Object.keys(variantsRef.current).join(", ")}`
776
+ );
777
+ }
778
+ return;
779
+ }
780
+ current = next;
781
+ for (const fn of listeners) fn(next);
782
+ },
783
+ subscribe(listener) {
784
+ listeners.add(listener);
785
+ return () => {
786
+ listeners.delete(listener);
787
+ };
788
+ }
789
+ };
790
+ return controller;
791
+ }, []);
792
+ }
793
+
794
+ export { Motion, MotionConfig, MotionImage, MotionPressable, MotionScrollView, MotionText, MotionView, Presence, createMotionComponent, ensureWorkletEasing, resolveAnimatableValue, resolveTransition, useMotionConfig, usePresence, useShouldReduceMotion, useVariants };
795
+ //# sourceMappingURL=index.mjs.map
796
+ //# sourceMappingURL=index.mjs.map