@rootnative/inertia 0.0.1 → 0.0.3

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 (44) hide show
  1. package/CHANGELOG.md +36 -2
  2. package/dist/{chunk-TDSO63CJ.js → chunk-3XTVY34H.js} +2 -2
  3. package/dist/{chunk-NXDJZD6A.mjs → chunk-46P57VMY.mjs} +1 -1
  4. package/dist/{chunk-7UDYEFBU.js → chunk-BP3Y2SHQ.js} +477 -298
  5. package/dist/{chunk-6SMPIOIC.mjs → chunk-BQQTHG2V.mjs} +1 -1
  6. package/dist/{chunk-DWCLIBYO.mjs → chunk-CSODMRJ7.mjs} +478 -299
  7. package/dist/chunk-FNVFV4EY.js +8 -0
  8. package/dist/chunk-FWQOXA43.js +8 -0
  9. package/dist/chunk-KBP4LR75.js +8 -0
  10. package/dist/{chunk-ALRHDFZE.mjs → chunk-O22NXXCZ.mjs} +1 -1
  11. package/dist/{chunk-CWLFUYIY.mjs → chunk-OQV66TBQ.mjs} +1 -1
  12. package/dist/{chunk-JVBXPF2G.mjs → chunk-SGUHE5CX.mjs} +1 -1
  13. package/dist/{chunk-2HYD2ZBK.js → chunk-W5MC3P4N.js} +2 -2
  14. package/dist/index.d.mts +231 -43
  15. package/dist/index.d.ts +231 -43
  16. package/dist/index.js +212 -23
  17. package/dist/index.mjs +204 -18
  18. package/dist/motion/Image.js +3 -3
  19. package/dist/motion/Image.mjs +2 -2
  20. package/dist/motion/Pressable.js +3 -3
  21. package/dist/motion/Pressable.mjs +2 -2
  22. package/dist/motion/ScrollView.js +3 -3
  23. package/dist/motion/ScrollView.mjs +2 -2
  24. package/dist/motion/Text.js +3 -3
  25. package/dist/motion/Text.mjs +2 -2
  26. package/dist/motion/View.js +3 -3
  27. package/dist/motion/View.mjs +2 -2
  28. package/llms.txt +5 -0
  29. package/package.json +1 -1
  30. package/src/index.ts +10 -0
  31. package/src/layout/index.ts +1 -0
  32. package/src/layout/sharedRegistry.ts +51 -2
  33. package/src/motion/createMotionComponent.tsx +781 -502
  34. package/src/presence/Presence.tsx +73 -10
  35. package/src/values/index.ts +13 -0
  36. package/src/values/useAnimation.ts +15 -1
  37. package/src/values/useAnimator.ts +83 -0
  38. package/src/values/useColorCascade.ts +125 -0
  39. package/src/values/useInterpolatedStyle.ts +319 -0
  40. package/src/values/useMotionValue.ts +20 -2
  41. package/src/values/useSpring.ts +12 -0
  42. package/dist/chunk-3UTJJ4A3.js +0 -8
  43. package/dist/chunk-4QGXK6TF.js +0 -8
  44. package/dist/chunk-Z7HIOFKQ.js +0 -8
@@ -0,0 +1,8 @@
1
+ 'use strict';
2
+
3
+ var chunkBP3Y2SHQ_js = require('./chunk-BP3Y2SHQ.js');
4
+ var reactNative = require('react-native');
5
+
6
+ var MotionView = chunkBP3Y2SHQ_js.createMotionComponent(reactNative.View);
7
+
8
+ exports.MotionView = MotionView;
@@ -0,0 +1,8 @@
1
+ 'use strict';
2
+
3
+ var chunkBP3Y2SHQ_js = require('./chunk-BP3Y2SHQ.js');
4
+ var reactNative = require('react-native');
5
+
6
+ var MotionText = chunkBP3Y2SHQ_js.createMotionComponent(reactNative.Text);
7
+
8
+ exports.MotionText = MotionText;
@@ -0,0 +1,8 @@
1
+ 'use strict';
2
+
3
+ var chunkBP3Y2SHQ_js = require('./chunk-BP3Y2SHQ.js');
4
+ var reactNative = require('react-native');
5
+
6
+ var MotionImage = chunkBP3Y2SHQ_js.createMotionComponent(reactNative.Image);
7
+
8
+ exports.MotionImage = MotionImage;
@@ -1,4 +1,4 @@
1
- import { createMotionComponent } from './chunk-DWCLIBYO.mjs';
1
+ import { createMotionComponent } from './chunk-CSODMRJ7.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-DWCLIBYO.mjs';
1
+ import { createMotionComponent } from './chunk-CSODMRJ7.mjs';
2
2
  import { ScrollView } from 'react-native';
3
3
 
4
4
  var MotionScrollView = createMotionComponent(ScrollView);
@@ -1,4 +1,4 @@
1
- import { createMotionComponent } from './chunk-DWCLIBYO.mjs';
1
+ import { createMotionComponent } from './chunk-CSODMRJ7.mjs';
2
2
  import { Text } from 'react-native';
3
3
 
4
4
  var MotionText = createMotionComponent(Text);
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var chunk7UDYEFBU_js = require('./chunk-7UDYEFBU.js');
3
+ var chunkBP3Y2SHQ_js = require('./chunk-BP3Y2SHQ.js');
4
4
  var reactNative = require('react-native');
5
5
 
6
- var MotionScrollView = chunk7UDYEFBU_js.createMotionComponent(reactNative.ScrollView);
6
+ var MotionScrollView = chunkBP3Y2SHQ_js.createMotionComponent(reactNative.ScrollView);
7
7
 
8
8
  exports.MotionScrollView = MotionScrollView;
package/dist/index.d.mts CHANGED
@@ -339,6 +339,52 @@ declare function buildReleaseAnimation(transition: TransitionConfig, toValue: nu
339
339
  */
340
340
  declare function useAnimation(target: number, transition?: TransitionInput): SharedValue<number>;
341
341
 
342
+ /**
343
+ * Imperative setter that drives a `SharedValue<number>` toward `to`, resolving
344
+ * the transition through the **same context** the declarative surface uses. It
345
+ * is the imperative escape hatch that closes the two footguns of writing
346
+ * `value.value = resolveTransition(config, to)` by hand from an event handler:
347
+ *
348
+ * 1. **Named transitions resolve.** A `TransitionName` registered on the
349
+ * nearest `<MotionConfig transitions>` works here just as it does on the
350
+ * `transition` prop or in `useAnimation`. Raw `resolveTransition` can't
351
+ * reach the registry (names resolve via context), so imperative call sites
352
+ * otherwise rebuild configs the provider already owns.
353
+ * 2. **Reduced motion is respected.** Writes route through the same
354
+ * `no-animation` downgrade `useAnimation` applies under
355
+ * `<MotionConfig reducedMotion>`. Hand-rolled `resolveTransition` writes
356
+ * silently bypass that setting — a correctness bug this hook fixes.
357
+ *
358
+ * The returned callback is identity-stable for the lifetime of the component —
359
+ * it reads the registry and the reduced-motion flag out of refs at call time,
360
+ * so neither a new `<MotionConfig transitions>` map nor a reduced-motion change
361
+ * gives it a new identity. Drop it straight into memoized handlers or a
362
+ * `useCallback` dependency list without churning them.
363
+ *
364
+ * This is not a new animation API — it starts animations in Inertia's existing
365
+ * transition vocabulary, so it does not conflict with the "no imperative-only
366
+ * APIs that bypass the declarative surface" scope rule. It is the hooks-layer
367
+ * equivalent of `useMotionValue` + `resolveTransition`, minus the footguns.
368
+ *
369
+ * @example
370
+ * ```tsx
371
+ * const hovered = useMotionValue(0)
372
+ * const animate = useAnimator()
373
+ *
374
+ * const onHoverIn = () => animate(hovered, 1, 'state-hover')
375
+ * const onHoverOut = () => animate(hovered, 0, 'state-hover')
376
+ * ```
377
+ *
378
+ * @example
379
+ * ```tsx
380
+ * // Inline config works too; default is spring when omitted.
381
+ * animate(progress, 1, { type: 'timing', duration: 150 })
382
+ * animate(progress, 0) // spring
383
+ * ```
384
+ */
385
+ type Animator = (value: SharedValue<number>, to: number, transition?: TransitionInput) => void;
386
+ declare function useAnimator(): Animator;
387
+
342
388
  /**
343
389
  * Toggle a 0↔1 progress value with a spring whenever `active` flips.
344
390
  *
@@ -406,56 +452,64 @@ interface UseColorTransitionOptions {
406
452
  declare function useColorTransition(progress: SharedValue<number>, range: readonly [string, string], options?: UseColorTransitionOptions): ReturnType<typeof useAnimatedStyle>;
407
453
 
408
454
  /**
409
- * Create an animatable value owned by JS but readable from worklets.
410
- *
411
- * This is the escape-hatch primitive that the rest of the value-layer hooks
412
- * (`useSpring`, `useTransform`, `useScroll`) compose against. It is a thin
413
- * pass-through over Reanimated's `useSharedValue`: a `SharedValue<T>` with
414
- * `.value` for direct reads/writes (UI-thread reads in worklets, JS-thread
415
- * writes from event handlers / effects).
455
+ * One layer in a color cascade: its own `progress` shared value (0→1) and the
456
+ * color it blends toward as that progress rises. Layers are ordered lowest
457
+ * priority first; a later layer wins over an earlier one at equal progress.
458
+ */
459
+ interface ColorCascadeLayer {
460
+ /** 0→1 driver for this layer. Drive it upstream (spring / boolean / gesture). */
461
+ progress: SharedValue<number>;
462
+ /** The color this layer blends toward as `progress` moves 0→1. */
463
+ color: string;
464
+ }
465
+ interface UseColorCascadeOptions {
466
+ /**
467
+ * Which style slot the composited color is emitted under. Defaults to
468
+ * `backgroundColor` — identical to `useColorTransition`. Override for ring
469
+ * colors (`borderColor`), text (`color`), image tints (`tintColor`), etc.
470
+ */
471
+ key?: ColorStyleKey;
472
+ }
473
+ /**
474
+ * Priority-ordered layered color crossfade: each layer owns an independent
475
+ * `progress` value and blends the accumulated color below it toward its own
476
+ * color as that progress moves 0→1. Later layers win over earlier ones — the
477
+ * array is priority order, **lowest first** (matching the `gesture` prop's
478
+ * fixed-priority cascade, Decision 5).
416
479
  *
417
- * We intentionally do not introduce a `MotionValue` wrapper class around the
418
- * shared value. The simplest object that interops with `useAnimatedStyle`,
419
- * `useDerivedValue`, and every other Reanimated API _is_ the shared value
420
- * itself; adding a `{ get, set, value }` shell would force consumers to
421
- * unwrap it at every Reanimated boundary and break worklet capture.
480
+ * Equivalent to the hand-chained nested-`interpolateColor` shape
481
+ * `focus(error(hover(rest)))`, collapsed into one hook and one worklet:
422
482
  *
423
- * Worklet read:
424
- * ```ts
425
- * const x = useMotionValue(0)
426
- * useAnimatedStyle(() => ({ transform: [{ translateX: x.value }] }))
427
- * ```
483
+ * ```tsx
484
+ * const borderStyle = useColorCascade(
485
+ * colors.border,
486
+ * [
487
+ * { progress: hovered, color: colors.borderHover },
488
+ * { progress: errored, color: colors.borderError },
489
+ * { progress: focused, color: colors.borderFocus },
490
+ * ],
491
+ * { key: 'borderColor' },
492
+ * )
428
493
  *
429
- * JS write:
430
- * ```ts
431
- * onPress={() => { x.value = 100 }}
494
+ * return <Motion.View style={[styles.field, borderStyle]} />
432
495
  * ```
433
- */
434
- declare function useMotionValue(initial: number): SharedValue<number>;
435
- declare function useMotionValue(initial: string): SharedValue<string>;
436
- declare function useMotionValue<T extends number | string>(initial: T): SharedValue<T>;
437
-
438
- /**
439
- * Animate a shared value toward `target` with spring physics, using the
440
- * library's react-spring vocabulary (`tension` / `friction` / `mass`).
441
496
  *
442
- * `target` may be a plain number or a `SharedValue<number>`. The plain-number
443
- * path drives the spring from a JS `useEffect`, so the animation re-runs on
444
- * every render where `target` changes. The shared-value path drives the
445
- * spring from a Reanimated reaction on the UI thread, so values produced by
446
- * gestures, scroll handlers, or other worklets flow through without bouncing
447
- * back to JS.
497
+ * This is a pure interpolator it does not animate on its own. Drive each
498
+ * layer's `progress` upstream with a `useSpring`, `useBooleanSpring`, gesture
499
+ * progress, or anything else producing a 0→1 shared value.
448
500
  *
449
- * Both call sites end up at the same `withSpring` invocation; the split is
450
- * just about which thread observes the source change.
501
+ * For the single-layer case (`rest` one active color), reach for
502
+ * [`useColorTransition`](./useColorTransition) it is the fast path and this
503
+ * hook is not a replacement for it. For a mixed numeric + color cascade, or
504
+ * function-valued layers, drop to a hand-rolled `useAnimatedStyle`.
451
505
  *
452
- * `config` also accepts a `TransitionName` registered on the nearest
453
- * `<MotionConfig transitions>`. Because this hook is spring-only, the name
454
- * must resolve to a spring config — a name registered as timing / decay /
455
- * no-animation warns in dev and falls back to the default spring (reach for
456
- * `useAnimation` when the named transition's type should be honored).
506
+ * The layer chain is resolved once on the JS thread and kept identity-stable,
507
+ * so a fresh-but-equal `layers` array each render produces no new UI-thread
508
+ * closure (CLAUDE.md principle 8). Changing a colour, the `key`, the base
509
+ * `rest`, the layer count, or **which shared value drives a layer** all rewire
510
+ * the worklet as you'd expect.
457
511
  */
458
- declare function useSpring(target: number | SharedValue<number>, config?: SpringTransition | TransitionName): SharedValue<number>;
512
+ declare function useColorCascade(rest: string, layers: readonly ColorCascadeLayer[], options?: UseColorCascadeOptions): ReturnType<typeof useAnimatedStyle>;
459
513
 
460
514
  /**
461
515
  * Extrapolation behavior at the edges of the input range. Mirrors
@@ -509,6 +563,140 @@ declare function useTransform<T>(transformer: () => T): SharedValue<T>;
509
563
  declare function useTransform(value: SharedValue<number>, inputRange: readonly number[], outputRange: readonly number[], options?: UseTransformOptions): SharedValue<number>;
510
564
  declare function useTransform(value: SharedValue<number>, inputRange: readonly number[], outputRange: readonly string[], options?: UseTransformOptions): SharedValue<string>;
511
565
 
566
+ /**
567
+ * Numeric style keys `useInterpolatedStyle` can emit directly (not lifted into
568
+ * the transform array). Mirrors the flat numeric surface of the `animate`
569
+ * prop.
570
+ */
571
+ type NumericStyleKey = 'opacity' | 'width' | 'height' | 'borderRadius' | 'shadowOpacity' | 'shadowRadius' | 'elevation' | 'top' | 'left' | 'right' | 'bottom' | 'fontSize' | 'lineHeight' | 'letterSpacing' | 'borderWidth';
572
+ /**
573
+ * Transform keys, lifted into a `transform: [...]` array in the order they
574
+ * appear in the map — the same key-order convention the `animate` prop uses.
575
+ * `rotate` / `rotateX` / `rotateY` take numeric degrees and emit
576
+ * `'<n>deg'` strings.
577
+ */
578
+ type TransformKey = 'translateX' | 'translateY' | 'scale' | 'scaleX' | 'scaleY' | 'rotate' | 'rotateX' | 'rotateY';
579
+ /**
580
+ * Interpolation map: each entry maps `progress` onto an output range for one
581
+ * style or transform key. Numeric / transform keys take number stops; color
582
+ * keys take color-string stops. Mixing stop types per key is a compile error.
583
+ */
584
+ type InterpolatedStyleMap = {
585
+ [K in NumericStyleKey | TransformKey]?: readonly number[];
586
+ } & {
587
+ [K in ColorStyleKey]?: readonly string[];
588
+ };
589
+ interface UseInterpolatedStyleOptions {
590
+ /**
591
+ * Input range mapped onto every key's output range. Defaults to `[0, 1]`
592
+ * for 2-stop outputs, and to evenly-spaced stops across `[0, 1]` for
593
+ * longer outputs. When provided, it applies to all keys; a key whose
594
+ * output length differs from `inputRange.length` throws in dev.
595
+ */
596
+ inputRange?: readonly number[];
597
+ /**
598
+ * Edge behavior outside the input range. Defaults to `'clamp'`, matching
599
+ * `useColorTransition`. Applies to numeric keys; color interpolation
600
+ * always clamps (Reanimated's `interpolateColor` has no extrapolation
601
+ * option).
602
+ */
603
+ extrapolate?: ExtrapolationMode;
604
+ }
605
+ /**
606
+ * Map one `progress` shared value onto N style props via `interpolate` /
607
+ * `interpolateColor`, returning an animated style fragment that composes in a
608
+ * style array on any Reanimated-aware host (`Motion.*`, a hand-rolled
609
+ * `Animated.View`). The style-fragment counterpart to `useTransform`'s
610
+ * output-range form, in the same family as `useColorTransition` / `useShadow`.
611
+ *
612
+ * ```tsx
613
+ * const collapseStyle = useInterpolatedStyle(collapseProgress, {
614
+ * height: [expandedHeight, collapsedHeight],
615
+ * fontSize: [expanded.fontSize, collapsed.fontSize],
616
+ * })
617
+ *
618
+ * const labelStyle = useInterpolatedStyle(floatProgress, {
619
+ * translateY: [restingOffset, 0],
620
+ * scale: [restingScale, 1],
621
+ * })
622
+ *
623
+ * return <Motion.View style={[base, collapseStyle, labelStyle]} />
624
+ * ```
625
+ *
626
+ * This is a pure interpolator — it does not animate on its own. Drive
627
+ * `progress` upstream with a `useSpring`, `useBooleanSpring`, gesture
628
+ * progress, or scroll-derived `useTransform`.
629
+ *
630
+ * - Numeric / transform keys route through `interpolate`; color-string stops
631
+ * on a color key route through `interpolateColor` (a multi-stop
632
+ * `useColorTransition` without touching that hook).
633
+ * - Transform keys (`translateX`, `scale`, `rotate`, …) are lifted into a
634
+ * single `transform` array in the order they appear in the map. `rotate*`
635
+ * keys take numeric degrees and emit `'<n>deg'` strings, consistent with
636
+ * the `animate` surface.
637
+ * - `options.inputRange` defaults to `[0, 1]` for 2-stop outputs and to
638
+ * evenly-spaced stops otherwise. `options.extrapolate` defaults to
639
+ * `'clamp'`.
640
+ *
641
+ * For function-valued entries or multi-source composition, drop to a
642
+ * hand-rolled `useAnimatedStyle` (or `useTransform`'s worklet form) — this
643
+ * hook stays fully declarative and hashable so unchanged maps produce zero
644
+ * new UI-thread closures.
645
+ */
646
+ declare function useInterpolatedStyle(progress: SharedValue<number>, map: InterpolatedStyleMap, options?: UseInterpolatedStyleOptions): ReturnType<typeof useAnimatedStyle>;
647
+
648
+ /**
649
+ * Create an animatable value owned by JS but readable from worklets.
650
+ *
651
+ * This is the escape-hatch primitive that the rest of the value-layer hooks
652
+ * (`useSpring`, `useTransform`, `useScroll`) compose against. It is a thin
653
+ * pass-through over Reanimated's `useSharedValue`: a `SharedValue<T>` with
654
+ * `.value` for direct reads/writes (UI-thread reads in worklets, JS-thread
655
+ * writes from event handlers / effects).
656
+ *
657
+ * We intentionally do not introduce a `MotionValue` wrapper class around the
658
+ * shared value. The simplest object that interops with `useAnimatedStyle`,
659
+ * `useDerivedValue`, and every other Reanimated API _is_ the shared value
660
+ * itself; adding a `{ get, set, value }` shell would force consumers to
661
+ * unwrap it at every Reanimated boundary and break worklet capture.
662
+ *
663
+ * Worklet read:
664
+ * ```ts
665
+ * const x = useMotionValue(0)
666
+ * useAnimatedStyle(() => ({ transform: [{ translateX: x.value }] }))
667
+ * ```
668
+ *
669
+ * JS write:
670
+ * ```ts
671
+ * onPress={() => { x.value = 100 }}
672
+ * ```
673
+ */
674
+ declare function useMotionValue(initial: number): SharedValue<number>;
675
+ declare function useMotionValue(initial: string): SharedValue<string>;
676
+ declare function useMotionValue<T extends number | string>(initial: T): SharedValue<T>;
677
+
678
+ /**
679
+ * Animate a shared value toward `target` with spring physics, using the
680
+ * library's react-spring vocabulary (`tension` / `friction` / `mass`).
681
+ *
682
+ * `target` may be a plain number or a `SharedValue<number>`. The plain-number
683
+ * path drives the spring from a JS `useEffect`, so the animation re-runs on
684
+ * every render where `target` changes. The shared-value path drives the
685
+ * spring from a Reanimated reaction on the UI thread, so values produced by
686
+ * gestures, scroll handlers, or other worklets flow through without bouncing
687
+ * back to JS.
688
+ *
689
+ * Both call sites end up at the same `withSpring` invocation; the split is
690
+ * just about which thread observes the source change.
691
+ *
692
+ * `config` also accepts a `TransitionName` registered on the nearest
693
+ * `<MotionConfig transitions>`. Because this hook is spring-only, the name
694
+ * must resolve to a spring config — a name registered as timing / decay /
695
+ * no-animation warns in dev and falls back to the default spring (reach for
696
+ * `useAnimation` when the named transition's type should be honored).
697
+ */
698
+ declare function useSpring(target: number | SharedValue<number>, config?: SpringTransition | TransitionName): SharedValue<number>;
699
+
512
700
  interface UseScrollResult {
513
701
  /** Horizontal scroll offset in points. */
514
702
  scrollX: SharedValue<number>;
@@ -681,4 +869,4 @@ declare function useShadow({ from, to, progress, }: UseShadowOptions): ReturnTyp
681
869
  */
682
870
  declare function useVariants<V extends Readonly<Record<string, object>>>(variants: V, initial?: keyof V & string): VariantController<keyof V & string>;
683
871
 
684
- export { AnimatableValue, type BoxShadowLayer, type ColorStyleKey, EasingInput, type ExtrapolationMode, Motion, MotionComponent, MotionConfig, type MotionConfigProps, type MotionConfigValue, NamedTransitions, Presence, type PresenceContextValue, type ReducedMotion, type ShadowConfig, SpringTransition, TransitionConfig, TransitionInput, TransitionName, type UseColorTransitionOptions, type UseScrollResult, type UseShadowOptions, type UseTransformOptions, VariantController, buildReleaseAnimation, createMotionComponent, cubicBezier, ensureWorkletEasing, resolveAnimatableValue, resolveNamedTransition, resolveTransition, useAnimation, useBooleanSpring, useColorTransition, useMotionConfig, useMotionValue, useNamedTransitions, usePresence, useScroll, useShadow, useShouldReduceMotion, useSpring, useTransform, useVariants };
872
+ export { AnimatableValue, type Animator, type BoxShadowLayer, type ColorCascadeLayer, type ColorStyleKey, EasingInput, type ExtrapolationMode, type InterpolatedStyleMap, Motion, MotionComponent, MotionConfig, type MotionConfigProps, type MotionConfigValue, NamedTransitions, type NumericStyleKey, Presence, type PresenceContextValue, type ReducedMotion, type ShadowConfig, SpringTransition, type TransformKey, TransitionConfig, TransitionInput, TransitionName, type UseColorCascadeOptions, type UseColorTransitionOptions, type UseInterpolatedStyleOptions, type UseScrollResult, type UseShadowOptions, type UseTransformOptions, VariantController, buildReleaseAnimation, createMotionComponent, cubicBezier, ensureWorkletEasing, resolveAnimatableValue, resolveNamedTransition, resolveTransition, useAnimation, useAnimator, useBooleanSpring, useColorCascade, useColorTransition, useInterpolatedStyle, useMotionConfig, useMotionValue, useNamedTransitions, usePresence, useScroll, useShadow, useShouldReduceMotion, useSpring, useTransform, useVariants };