@rootnative/inertia 0.0.0-alpha.7 → 0.0.2

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