@rootnative/inertia 0.0.0-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.
- package/CHANGELOG.md +33 -0
- package/LICENSE +21 -0
- package/README.md +131 -0
- package/dist/gestureLayer/index.d.mts +119 -0
- package/dist/gestureLayer/index.d.ts +119 -0
- package/dist/gestureLayer/index.js +346 -0
- package/dist/gestureLayer/index.js.map +1 -0
- package/dist/gestureLayer/index.mjs +344 -0
- package/dist/gestureLayer/index.mjs.map +1 -0
- package/dist/index.d.mts +507 -0
- package/dist/index.d.ts +507 -0
- package/dist/index.js +1546 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1515 -0
- package/dist/index.mjs.map +1 -0
- package/dist/motion/Image.d.mts +12 -0
- package/dist/motion/Image.d.ts +12 -0
- package/dist/motion/Image.js +1138 -0
- package/dist/motion/Image.js.map +1 -0
- package/dist/motion/Image.mjs +1132 -0
- package/dist/motion/Image.mjs.map +1 -0
- package/dist/motion/Pressable.d.mts +15 -0
- package/dist/motion/Pressable.d.ts +15 -0
- package/dist/motion/Pressable.js +1138 -0
- package/dist/motion/Pressable.js.map +1 -0
- package/dist/motion/Pressable.mjs +1132 -0
- package/dist/motion/Pressable.mjs.map +1 -0
- package/dist/motion/ScrollView.d.mts +12 -0
- package/dist/motion/ScrollView.d.ts +12 -0
- package/dist/motion/ScrollView.js +1138 -0
- package/dist/motion/ScrollView.js.map +1 -0
- package/dist/motion/ScrollView.mjs +1132 -0
- package/dist/motion/ScrollView.mjs.map +1 -0
- package/dist/motion/Text.d.mts +11 -0
- package/dist/motion/Text.d.ts +11 -0
- package/dist/motion/Text.js +1138 -0
- package/dist/motion/Text.js.map +1 -0
- package/dist/motion/Text.mjs +1132 -0
- package/dist/motion/Text.mjs.map +1 -0
- package/dist/motion/View.d.mts +11 -0
- package/dist/motion/View.d.ts +11 -0
- package/dist/motion/View.js +1138 -0
- package/dist/motion/View.js.map +1 -0
- package/dist/motion/View.mjs +1132 -0
- package/dist/motion/View.mjs.map +1 -0
- package/dist/testing/index.d.mts +57 -0
- package/dist/testing/index.d.ts +57 -0
- package/dist/testing/index.js +19 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/index.mjs +16 -0
- package/dist/testing/index.mjs.map +1 -0
- package/dist/touch/index.d.mts +146 -0
- package/dist/touch/index.d.ts +146 -0
- package/dist/touch/index.js +166 -0
- package/dist/touch/index.js.map +1 -0
- package/dist/touch/index.mjs +164 -0
- package/dist/touch/index.mjs.map +1 -0
- package/dist/types-cU43dEmH.d.mts +339 -0
- package/dist/types-cU43dEmH.d.ts +339 -0
- package/dist/useGesture-BnY65PlQ.d.ts +84 -0
- package/dist/useGesture-DxtXdz-K.d.mts +84 -0
- package/jest-preset.js +33 -0
- package/jest-setup.js +213 -0
- package/llms.txt +142 -0
- package/package.json +151 -0
- package/src/__type-tests__/animate.test-d.tsx +88 -0
- package/src/__type-tests__/variants.test-d.tsx +67 -0
- package/src/config/MotionConfig.tsx +30 -0
- package/src/config/MotionConfigContext.ts +53 -0
- package/src/config/index.ts +9 -0
- package/src/gestureLayer/index.ts +21 -0
- package/src/gestureLayer/useGestureLayer.ts +285 -0
- package/src/gestures/focusVisibility.ts +61 -0
- package/src/gestures/index.ts +1 -0
- package/src/index.ts +72 -0
- package/src/layout/index.ts +16 -0
- package/src/layout/resolveLayout.ts +54 -0
- package/src/layout/sharedRegistry.ts +111 -0
- package/src/layout/useSharedLayout.ts +289 -0
- package/src/motion/Image.tsx +9 -0
- package/src/motion/Pressable.tsx +12 -0
- package/src/motion/ScrollView.tsx +9 -0
- package/src/motion/Text.tsx +8 -0
- package/src/motion/View.tsx +8 -0
- package/src/motion/createMotionComponent.tsx +1306 -0
- package/src/motion/index.ts +26 -0
- package/src/motion/installCheck.ts +65 -0
- package/src/presence/Presence.tsx +165 -0
- package/src/presence/PresenceContext.ts +28 -0
- package/src/presence/index.ts +6 -0
- package/src/testing/index.ts +78 -0
- package/src/touch/index.ts +18 -0
- package/src/touch/useTouchDrag.ts +289 -0
- package/src/transitions/easing.ts +53 -0
- package/src/transitions/index.ts +7 -0
- package/src/transitions/keys.ts +32 -0
- package/src/transitions/resolve.ts +169 -0
- package/src/transitions/resolveSequence.ts +87 -0
- package/src/transitions/runtime.ts +63 -0
- package/src/transitions/sig.ts +40 -0
- package/src/transitions/spring.ts +42 -0
- package/src/types.ts +383 -0
- package/src/values/index.ts +26 -0
- package/src/values/useAnimation.ts +69 -0
- package/src/values/useBooleanSpring.ts +33 -0
- package/src/values/useColorTransition.ts +72 -0
- package/src/values/useGesture.ts +144 -0
- package/src/values/useMotionValue.ts +33 -0
- package/src/values/useScroll.ts +72 -0
- package/src/values/useShadow.ts +116 -0
- package/src/values/useSpring.ts +98 -0
- package/src/values/useTransform.ts +132 -0
- package/src/values/useVariants.ts +60 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/transitions/spring.ts","../../src/transitions/runtime.ts","../../src/touch/useTouchDrag.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import { type SpringTransition } from '../types'\n\n/**\n * Default spring physics, expressed in react-spring vocabulary.\n *\n * `tension: 170` / `friction: 26` / `mass: 1` was picked over Reanimated's\n * raw `stiffness: 100` / `damping: 10` default because the raw default\n * overshoots noticeably for the small (~100px) translates that dominate\n * UI work — buttons, sheets, popovers. These numbers settle in ~350ms with\n * a single, almost-imperceptible overshoot, which matches the perceptual\n * target the rest of the library is tuned against.\n */\nexport const DEFAULT_SPRING: Required<\n Pick<SpringTransition, 'tension' | 'friction' | 'mass'>\n> = {\n tension: 170,\n friction: 26,\n mass: 1,\n}\n\n/**\n * Convert public react-spring vocabulary (`tension` / `friction` / `mass`)\n * to Reanimated's raw `stiffness` / `damping` / `mass`. This is the single\n * place the mapping lives; resolvers, value hooks, and any future surface\n * that needs a Reanimated spring config import from here.\n *\n * The mapping is identity (tension ≡ stiffness, friction ≡ damping) — the\n * names differ but the underlying physics constants are the same. We don't\n * surface the raw names publicly because the react-spring vocabulary is\n * what designers and prior-art consumers expect.\n */\nexport function springToReanimated(t: SpringTransition) {\n 'worklet'\n return {\n stiffness: t.tension ?? DEFAULT_SPRING.tension,\n damping: t.friction ?? DEFAULT_SPRING.friction,\n mass: t.mass ?? DEFAULT_SPRING.mass,\n velocity: t.velocity,\n restSpeedThreshold: t.restSpeedThreshold,\n restDisplacementThreshold: t.restDisplacementThreshold,\n }\n}\n","import {\n Easing,\n withDecay,\n withSpring,\n withTiming,\n} from 'react-native-reanimated'\nimport { springToReanimated } from './spring'\nimport { type TransitionConfig } from '../types'\n\nconst DEFAULT_TIMING_DURATION = 250\n\n/**\n * Worklet-safe single-step animation builder. Mirrors a subset of\n * `resolveTransition` for the UI-thread path where the transition config is\n * picked at gesture-release time, not at render time.\n *\n * Supported: spring / timing / decay / no-animation, single-step only.\n * Not supported: sequences, top-level repeat, easing-function\n * auto-worklet-wrapping (pass an already-worklet easing if you need a custom\n * one — most release transitions don't).\n *\n * Use this from gesture worklets (`useDrag` / `usePan` release callbacks, or\n * any custom `Gesture.Pan().onEnd(() => ...)` worklet) to animate a shared\n * value with an Inertia transition without the JS round-trip that would lose\n * the release velocity.\n *\n * For decay transitions, `toValue` is ignored — decay decelerates from the\n * SV's current position via its own physics. Pass `0` if you don't have one.\n */\nexport function buildReleaseAnimation(\n transition: TransitionConfig,\n toValue: number,\n): unknown {\n 'worklet'\n if (transition.type === 'no-animation') return toValue\n if (transition.type === 'decay') {\n const cfg: {\n velocity: number\n deceleration?: number\n clamp?: [number, number]\n } = { velocity: transition.velocity ?? 0 }\n if (transition.deceleration !== undefined) {\n cfg.deceleration = transition.deceleration\n }\n if (transition.clamp !== undefined) cfg.clamp = transition.clamp\n return withDecay(cfg)\n }\n if (transition.type === 'timing') {\n // Reanimated 4's `Easing.bezier(...)` returns an `EasingFunctionFactory`\n // rather than the function itself. Unwrap inline so consumers calling\n // `buildReleaseAnimation` from a gesture worklet don't have to.\n const e = transition.easing\n const easingFn =\n e && typeof e === 'object' && 'factory' in e\n ? e.factory()\n : (e ?? Easing.inOut(Easing.ease))\n return withTiming(toValue, {\n duration: transition.duration ?? DEFAULT_TIMING_DURATION,\n easing: easingFn,\n })\n }\n return withSpring(toValue, springToReanimated(transition))\n}\n","import { useMemo } from 'react'\nimport {\n PanResponder,\n type PanResponderGestureState,\n type PanResponderInstance,\n} from 'react-native'\nimport {\n useAnimatedStyle,\n useSharedValue,\n type SharedValue,\n} from 'react-native-reanimated'\nimport { buildReleaseAnimation } from '../transitions'\nimport type { TransitionConfig } from '../types'\n\n/**\n * Same drag-result shape as `useDrag` from `@rootnative/inertia-gestures`,\n * minus the `gesture` field (PanResponder spreads handlers, no\n * `<GestureDetector>` wrapper). The shared values + animatedStyle are\n * interchangeable across both hooks; consumers can swap implementations\n * without touching their `useAnimatedStyle` consumers.\n */\nexport interface UseTouchDragResult {\n /** Spread onto a `View` / `Pressable` to install the pan responder. */\n panHandlers: PanResponderInstance['panHandlers']\n /** Stable animated `transform` style. */\n animatedStyle: ReturnType<typeof useAnimatedStyle>\n /** Live x translation, persistent across gestures. */\n dragX: SharedValue<number>\n /** Live y translation, persistent across gestures. */\n dragY: SharedValue<number>\n /** True while the gesture is active. */\n isDragging: SharedValue<boolean>\n}\n\n/**\n * Release transition shape for PanResponder's JS-thread `onRelease`. Mirrors\n * the gesture-handler adapter's `ReleaseTransition` but with `to` typed as\n * required for spring/timing/no-animation (decay omits it).\n */\nexport type TouchReleaseTransition =\n | (TransitionConfig & { type: 'spring'; to: number })\n | (TransitionConfig & { type: 'timing'; to: number })\n | (TransitionConfig & { type: 'decay' })\n | (TransitionConfig & { type: 'no-animation'; to: number })\n\nexport interface TouchReleaseInfo {\n x: number\n y: number\n velocity: { x: number; y: number }\n}\n\nexport interface TouchReleaseResult {\n x?: TouchReleaseTransition\n y?: TouchReleaseTransition\n}\n\nexport interface UseTouchDragOptions {\n /**\n * Restrict the drag to one axis. Defaults to `'both'`. When `'x'` is set\n * the y-axis shared value never updates (and vice versa); velocity is\n * still reported on both for `onDragEnd`.\n */\n axis?: 'x' | 'y' | 'both'\n /**\n * Travel bounds (px from resting). Each side is independently optional.\n * Out-of-bounds values clamp to the limit unless `elastic > 0`.\n */\n constraints?: {\n left?: number\n right?: number\n top?: number\n bottom?: number\n }\n /**\n * Rubber-band coefficient applied to overshoot past `constraints`. `0`\n * (default) hard-clamps; `0.2`-`0.4` is a typical Framer-Motion feel.\n */\n elastic?: number\n /**\n * Fires when the user starts dragging. JS thread.\n */\n onDragStart?: () => void\n /**\n * Fires when the user releases or the gesture terminates. JS thread.\n *\n * Velocity is in px/sec to match the `@rootnative/inertia-gestures` API\n * (PanResponder's native `vx` / `vy` are px/ms; the hook normalizes).\n */\n onDragEnd?: (info: TouchReleaseInfo) => void\n /**\n * Optional release-animation callback. Return per-axis release transitions\n * to animate the SVs to a settled position via Inertia's transition\n * resolver — spring snap-to-tick, decay with bounds, timing settle.\n *\n * Unlike the gesture-handler version, this callback runs on the **JS\n * thread** (PanResponder is JS-only). The returned transitions still drive\n * UI-thread animations via Reanimated — only the decision logic is JS-side.\n */\n onRelease?: (info: TouchReleaseInfo) => TouchReleaseResult | void\n}\n\n/**\n * PanResponder-backed drag hook. Pointer-equivalent of `useDrag` from\n * `@rootnative/inertia-gestures`, with two differences:\n *\n * 1. No `react-native-gesture-handler` peer dep required — PanResponder is\n * built into React Native, so this lives in core.\n * 2. Returns `panHandlers` to spread on a `View` / `Pressable` instead of\n * a `gesture` to plug into `<GestureDetector>`.\n *\n * Use this when:\n * - You need keyboard a11y alongside drag (a slider with arrow-key step,\n * a scrollbar with `PageUp` / `PageDown`). PanResponder composes\n * cleanly with `onKeyDown`; gesture-handler doesn't surface keyboard.\n * - You don't want to take `react-native-gesture-handler` as a dependency\n * (smaller bundle, simpler install).\n *\n * Skip this when:\n * - You're already using `react-native-gesture-handler` elsewhere (use\n * `useDrag` from `@rootnative/inertia-gestures` for consistency and\n * better worklet-thread fidelity on release velocity).\n * - You need momentum semantics like the gesture-handler `usePan` —\n * PanResponder's release velocity is JS-thread and slightly less precise.\n *\n * @example\n * ```tsx\n * import { useTouchDrag } from '@rootnative/inertia/touch'\n *\n * function Slider({ ticks }: { ticks: number[] }) {\n * const drag = useTouchDrag({\n * axis: 'x',\n * constraints: { left: 0, right: 280 },\n * onRelease: (e) => {\n * const snap = nearestTick(e.x, ticks)\n * return { x: { type: 'spring', to: snap, velocity: e.velocity.x } }\n * },\n * })\n *\n * return (\n * <Motion.View\n * style={[styles.thumb, drag.animatedStyle]}\n * {...drag.panHandlers}\n * />\n * )\n * }\n * ```\n */\nexport function useTouchDrag(\n options: UseTouchDragOptions = {},\n): UseTouchDragResult {\n const { axis = 'both', constraints, elastic = 0 } = options\n\n const dragX = useSharedValue(0)\n const dragY = useSharedValue(0)\n const startX = useSharedValue(0)\n const startY = useSharedValue(0)\n const isDragging = useSharedValue(false)\n\n // Snapshot scalars into local consts so the responder callbacks close over\n // primitives, not the `options` literal — a fresh `options` each render\n // would otherwise force the PanResponder identity to change.\n const lockX = axis !== 'y'\n const lockY = axis !== 'x'\n const left = constraints?.left\n const right = constraints?.right\n const top = constraints?.top\n const bottom = constraints?.bottom\n const elasticCoef = elastic\n const { onDragStart, onDragEnd, onRelease } = options\n\n const responder = useMemo(\n () => buildResponder(),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n lockX,\n lockY,\n left,\n right,\n top,\n bottom,\n elasticCoef,\n onDragStart,\n onDragEnd,\n onRelease,\n ],\n )\n\n // Hoisted out of the inline `useMemo` factory to keep the dep list readable\n // and avoid re-declaring closure helpers each render.\n function buildResponder(): PanResponderInstance {\n const handleEnd = (g: PanResponderGestureState) => {\n isDragging.value = false\n const x = dragX.value\n const y = dragY.value\n // PanResponder velocity is px/ms; multiply to match the\n // `@rootnative/inertia-gestures` API (px/sec from gesture-handler).\n const vx = g.vx * 1000\n const vy = g.vy * 1000\n if (onRelease) {\n const result = onRelease({ x, y, velocity: { x: vx, y: vy } })\n if (result) {\n if (result.x && lockX) {\n const toX = 'to' in result.x ? result.x.to : x\n dragX.value = buildReleaseAnimation(\n result.x,\n toX,\n ) as unknown as number\n }\n if (result.y && lockY) {\n const toY = 'to' in result.y ? result.y.to : y\n dragY.value = buildReleaseAnimation(\n result.y,\n toY,\n ) as unknown as number\n }\n }\n }\n if (onDragEnd) onDragEnd({ x, y, velocity: { x: vx, y: vy } })\n }\n\n return PanResponder.create({\n // Always claim the start so taps that turn into drags don't slip\n // through to a parent ScrollView. Consumers can compose their own\n // capture predicates by wrapping the returned `panHandlers`.\n onStartShouldSetPanResponder: () => true,\n onMoveShouldSetPanResponder: () => true,\n onPanResponderGrant: () => {\n startX.value = dragX.value\n startY.value = dragY.value\n isDragging.value = true\n if (onDragStart) onDragStart()\n },\n onPanResponderMove: (_e, g) => {\n if (lockX) {\n dragX.value = applyBounds(\n startX.value + g.dx,\n left,\n right,\n elasticCoef,\n )\n }\n if (lockY) {\n dragY.value = applyBounds(\n startY.value + g.dy,\n top,\n bottom,\n elasticCoef,\n )\n }\n },\n onPanResponderRelease: (_e, g) => handleEnd(g),\n onPanResponderTerminate: (_e, g) => handleEnd(g),\n })\n }\n\n const animatedStyle = useAnimatedStyle(() => ({\n transform: [{ translateX: dragX.value }, { translateY: dragY.value }],\n }))\n\n return {\n panHandlers: responder.panHandlers,\n animatedStyle,\n dragX,\n dragY,\n isDragging,\n }\n}\n\n/**\n * Clamp `value` to `[min, max]`. When `elastic > 0` the overshoot past a\n * bound is scaled by `elastic`, giving a rubber-band feel. `min` / `max`\n * may be `undefined` to leave that side unbounded.\n *\n * JS-thread (PanResponder callbacks are JS, not worklets).\n */\nfunction applyBounds(\n value: number,\n min: number | undefined,\n max: number | undefined,\n elastic: number,\n): number {\n if (min !== undefined && value < min) {\n return elastic > 0 ? min + (value - min) * elastic : min\n }\n if (max !== undefined && value > max) {\n return elastic > 0 ? max + (value - max) * elastic : max\n }\n return value\n}\n"]}
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import { ComponentType, ComponentProps, Ref, ReactElement } from 'react';
|
|
2
|
+
import { StyleProp } from 'react-native';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A single animation step's destination, optionally overriding the transition
|
|
6
|
+
* for that step.
|
|
7
|
+
*/
|
|
8
|
+
type SequenceStep<V> = V | ({
|
|
9
|
+
to: V;
|
|
10
|
+
delay?: number;
|
|
11
|
+
} & TransitionConfig);
|
|
12
|
+
/**
|
|
13
|
+
* A target value for an animatable property: a single value, a sequence of
|
|
14
|
+
* steps (keyframes), or a single step object.
|
|
15
|
+
*/
|
|
16
|
+
type AnimatableValue<V> = V | SequenceStep<V> | ReadonlyArray<SequenceStep<V>>;
|
|
17
|
+
/**
|
|
18
|
+
* Spring transition — public surface uses react-spring vocabulary
|
|
19
|
+
* (`tension` / `friction` / `mass`), not Reanimated's raw stiffness/damping.
|
|
20
|
+
*/
|
|
21
|
+
interface SpringTransition {
|
|
22
|
+
type?: 'spring';
|
|
23
|
+
tension?: number;
|
|
24
|
+
friction?: number;
|
|
25
|
+
mass?: number;
|
|
26
|
+
velocity?: number;
|
|
27
|
+
restSpeedThreshold?: number;
|
|
28
|
+
restDisplacementThreshold?: number;
|
|
29
|
+
delay?: number;
|
|
30
|
+
repeat?: RepeatConfig;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Easing input accepted by `TimingTransition`. Either a plain easing function
|
|
34
|
+
* `(t: number) => number` (the pre-Reanimated-4 shape and the shape consumers
|
|
35
|
+
* author by hand) or an `EasingFunctionFactory` (the Reanimated 4 shape
|
|
36
|
+
* returned by `Easing.bezier(...)` and similar builders). The resolver
|
|
37
|
+
* unwraps the factory automatically — consumers don't have to call
|
|
38
|
+
* `.factory()` themselves.
|
|
39
|
+
*/
|
|
40
|
+
type EasingFunction = (t: number) => number;
|
|
41
|
+
interface EasingFunctionFactory {
|
|
42
|
+
factory: () => EasingFunction;
|
|
43
|
+
}
|
|
44
|
+
type EasingInput = EasingFunction | EasingFunctionFactory;
|
|
45
|
+
interface TimingTransition {
|
|
46
|
+
type: 'timing';
|
|
47
|
+
duration?: number;
|
|
48
|
+
easing?: EasingInput;
|
|
49
|
+
delay?: number;
|
|
50
|
+
repeat?: RepeatConfig;
|
|
51
|
+
}
|
|
52
|
+
interface DecayTransition {
|
|
53
|
+
type: 'decay';
|
|
54
|
+
velocity?: number;
|
|
55
|
+
deceleration?: number;
|
|
56
|
+
clamp?: [number, number];
|
|
57
|
+
delay?: number;
|
|
58
|
+
}
|
|
59
|
+
interface NoAnimationTransition {
|
|
60
|
+
type: 'no-animation';
|
|
61
|
+
}
|
|
62
|
+
type TransitionConfig = SpringTransition | TimingTransition | DecayTransition | NoAnimationTransition;
|
|
63
|
+
/**
|
|
64
|
+
* Repeat config — one shape, not three flags. Default `alternate: true`.
|
|
65
|
+
*/
|
|
66
|
+
type RepeatConfig = number | 'infinite' | {
|
|
67
|
+
count: number | 'infinite';
|
|
68
|
+
alternate?: boolean;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Per-property transition map. Keys must match keys present on `animate`.
|
|
72
|
+
* Top-level entries on `transition` apply to all properties unless overridden
|
|
73
|
+
* here.
|
|
74
|
+
*/
|
|
75
|
+
type PerPropertyTransition<S> = {
|
|
76
|
+
[K in keyof S]?: TransitionConfig;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Per-gesture-layer transition map. Each `gesture` sub-state animates a
|
|
80
|
+
* progress value 0↔1 with its own transition; the worklet composites the
|
|
81
|
+
* layers in priority order (`hovered → focused → focusVisible → pressed`).
|
|
82
|
+
*
|
|
83
|
+
* Keys live on the same `transition` object as `PerPropertyTransition` because
|
|
84
|
+
* the only other place they could go (nested inside `gesture` itself) would
|
|
85
|
+
* collide with the primitive's inferred style keys.
|
|
86
|
+
*/
|
|
87
|
+
interface GestureLayerTransitions {
|
|
88
|
+
pressed?: TransitionConfig;
|
|
89
|
+
focused?: TransitionConfig;
|
|
90
|
+
focusVisible?: TransitionConfig;
|
|
91
|
+
hovered?: TransitionConfig;
|
|
92
|
+
}
|
|
93
|
+
type Transition<S> = TransitionConfig | (PerPropertyTransition<S> & GestureLayerTransitions);
|
|
94
|
+
/**
|
|
95
|
+
* Transform shorthands that Inertia exposes on `animate` but that don't
|
|
96
|
+
* appear on RN's typed ViewStyle as top-level keys. RN keeps `scale`,
|
|
97
|
+
* `rotate`, `rotateX`, and `rotateY` inside the `transform` array; only
|
|
98
|
+
* `scaleX`/`scaleY` and `translateX`/`translateY` are surfaced as
|
|
99
|
+
* (deprecated) top-level shortcuts. Inertia's runtime treats these as
|
|
100
|
+
* transform-group keys (see `TRANSFORM_KEYS` in `createMotionComponent`),
|
|
101
|
+
* so they're documented as first-class animatables in `CLAUDE.md` and must
|
|
102
|
+
* be reachable from `animate` without dropping into the `transform: [...]`
|
|
103
|
+
* array form. Rotation values are degrees as numbers — the runtime appends
|
|
104
|
+
* `'deg'` before handing the transform to Reanimated.
|
|
105
|
+
*/
|
|
106
|
+
type AnimatableTransformExtras = {
|
|
107
|
+
scale?: AnimatableValue<number>;
|
|
108
|
+
rotate?: AnimatableValue<number>;
|
|
109
|
+
rotateX?: AnimatableValue<number>;
|
|
110
|
+
rotateY?: AnimatableValue<number>;
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* The animation state shape inferred from the underlying component's style
|
|
114
|
+
* prop. We narrow to the value side of `style` so consumers see ViewStyle on
|
|
115
|
+
* `Motion.View`, TextStyle on `Motion.Text`, etc. — no shared union.
|
|
116
|
+
*
|
|
117
|
+
* Some components (notably `Pressable`) type `style` as a union of
|
|
118
|
+
* `StyleProp<T>` and a callback `(state) => StyleProp<T>`. If we infer `S`
|
|
119
|
+
* directly from `StyleProp<infer S>`, the callback branch widens `S` to
|
|
120
|
+
* `unknown`, which collapses the animate map to `| {}` and silently
|
|
121
|
+
* accepts any key. Excluding functions first keeps inference tight.
|
|
122
|
+
*/
|
|
123
|
+
type _StyleValue<T> = Exclude<T, (...args: any[]) => any>;
|
|
124
|
+
type AnimateStyle<C> = C extends {
|
|
125
|
+
style?: infer Raw;
|
|
126
|
+
} ? _StyleValue<Raw> extends StyleProp<infer S> ? {
|
|
127
|
+
[K in keyof S]?: AnimatableValue<S[K]>;
|
|
128
|
+
} & AnimatableTransformExtras : never : never;
|
|
129
|
+
interface AnimationCallbackInfo<S> {
|
|
130
|
+
/**
|
|
131
|
+
* The animatable key that just settled — typically a `keyof S` (e.g.
|
|
132
|
+
* `'opacity'`, `'translateX'`). The sentinel `'transform'` is emitted in
|
|
133
|
+
* lieu of any specific transform axis (`translateX`/`Y`, `scale`/`X`/`Y`,
|
|
134
|
+
* `rotate`) when the terminal `'animation'` phase fires for a transform
|
|
135
|
+
* group, so a multi-axis translate produces one callback rather than two.
|
|
136
|
+
*/
|
|
137
|
+
key: keyof S | 'transform';
|
|
138
|
+
finished: boolean;
|
|
139
|
+
value: unknown;
|
|
140
|
+
target: unknown;
|
|
141
|
+
phase: 'step' | 'sequence' | 'repeat' | 'animation';
|
|
142
|
+
step: number | undefined;
|
|
143
|
+
iteration: number;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* A variants map: string state names → animate target objects.
|
|
147
|
+
*/
|
|
148
|
+
type VariantsMap<C> = Record<string, AnimateStyle<C>>;
|
|
149
|
+
/**
|
|
150
|
+
* Gesture sub-states accepted by the `gesture` prop on every Motion primitive.
|
|
151
|
+
*
|
|
152
|
+
* - `pressed` — active while the user is touching the component (touch start
|
|
153
|
+
* to touch end / cancel).
|
|
154
|
+
* - `focused` — active while a focusable component owns focus, regardless of
|
|
155
|
+
* how focus arrived (mouse, touch, or keyboard). No-op for non-focusable
|
|
156
|
+
* underlying components.
|
|
157
|
+
* - `focusVisible` — active only when focus arrived from the keyboard
|
|
158
|
+
* (W3C `:focus-visible` semantics). Use this for focus rings to avoid
|
|
159
|
+
* flashing them on click-focus on web. On native — where focus always
|
|
160
|
+
* arrives via D-pad, screen reader, or hardware keyboard — this behaves
|
|
161
|
+
* identically to `focused`.
|
|
162
|
+
* - `hovered` — web-only. Typed for cross-platform call sites; the runtime is
|
|
163
|
+
* a no-op on native.
|
|
164
|
+
*
|
|
165
|
+
* Sub-states layer additively. Each declared sub-state owns an independent
|
|
166
|
+
* progress value (0↔1) that animates in/out with its own transition; the
|
|
167
|
+
* worklet composites layers in priority order (lowest-to-highest):
|
|
168
|
+
* `hovered → focused → focusVisible → pressed`. Per-property the chain is
|
|
169
|
+
*
|
|
170
|
+
* v = base
|
|
171
|
+
* v = lerp(v, hovered.value, progressHovered) // if declared
|
|
172
|
+
* v = lerp(v, focused.value, progressFocused) // if declared
|
|
173
|
+
* v = lerp(v, focusVisible.value, progressFocusVisible) // if declared
|
|
174
|
+
* v = lerp(v, pressed.value, progressPressed) // if declared
|
|
175
|
+
*
|
|
176
|
+
* (Color-valued keys use `interpolateColor` instead of `lerp`.) When a single
|
|
177
|
+
* sub-state is active, this collapses to "the highest-priority declared layer
|
|
178
|
+
* wins". When multiple are mid-transition (e.g. release-while-still-hovered)
|
|
179
|
+
* each layer fades independently — a press layer fading out at 50ms while a
|
|
180
|
+
* hover layer holds at full opacity matches MD3 state-layer semantics.
|
|
181
|
+
*
|
|
182
|
+
* Configure per-layer fade timing via `transition.<stateName>` on the parent
|
|
183
|
+
* primitive (see `GestureLayerTransitions`); without it, layers default to
|
|
184
|
+
* the parent transition or the library default spring.
|
|
185
|
+
*
|
|
186
|
+
* **Priority cascade is the only composition mode on this prop.** Non-priority
|
|
187
|
+
* blends — clamped-max (`Math.max(hover*α, focus*β, press*γ)`, as used by MD3
|
|
188
|
+
* state-layer haloes), additive accumulation, or any per-key custom blend —
|
|
189
|
+
* are not expressible declaratively. Drop to `useGesture()` for those: it
|
|
190
|
+
* returns the four progress shared values and a handler bag, and you write
|
|
191
|
+
* a `useAnimatedStyle` block with whatever composition you need. The hook's
|
|
192
|
+
* JSDoc shows the clamped-max halo pattern in full.
|
|
193
|
+
*/
|
|
194
|
+
interface GestureSubStates<C> {
|
|
195
|
+
pressed?: AnimateStyle<C>;
|
|
196
|
+
focused?: AnimateStyle<C>;
|
|
197
|
+
focusVisible?: AnimateStyle<C>;
|
|
198
|
+
hovered?: AnimateStyle<C>;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Controller returned by `useVariants`. The `current` shared state is read
|
|
202
|
+
* via `controller` prop on a Motion primitive; `transitionTo` drives the
|
|
203
|
+
* controller from JS code (event handlers, async chains, etc.).
|
|
204
|
+
*/
|
|
205
|
+
interface VariantController<K extends string = string> {
|
|
206
|
+
current: K;
|
|
207
|
+
transitionTo(next: K): void;
|
|
208
|
+
/** @internal — subscription used by Motion primitives to re-render. */
|
|
209
|
+
subscribe(listener: (next: K) => void): () => void;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Props injected onto every Motion primitive.
|
|
213
|
+
*
|
|
214
|
+
* The second type parameter `V` is the concrete `variants` map. It is inferred
|
|
215
|
+
* from the `variants` prop at each JSX use (see `MotionComponent`), which is
|
|
216
|
+
* what lets `animate` narrow to the variant key union and reject typos. When
|
|
217
|
+
* no `variants` prop is passed, `V` falls back to `VariantsMap<C>` — whose key
|
|
218
|
+
* type is the open `string`, so `animate` still accepts any string and nothing
|
|
219
|
+
* regresses for the variant-less case.
|
|
220
|
+
*/
|
|
221
|
+
interface MotionProps<C, V extends VariantsMap<C> = VariantsMap<C>> {
|
|
222
|
+
/**
|
|
223
|
+
* Initial values applied on mount. Read once on mount and intentionally
|
|
224
|
+
* non-reactive — to reset after a state change, change the component `key`,
|
|
225
|
+
* remount via `<Presence>`, or drive the value through a controller.
|
|
226
|
+
*
|
|
227
|
+
* Pass `false` to skip the initial-mount animation entirely.
|
|
228
|
+
*/
|
|
229
|
+
initial?: AnimateStyle<C> | false;
|
|
230
|
+
/**
|
|
231
|
+
* The animation target. A style object, a variant key (when `variants` is
|
|
232
|
+
* supplied), or an array of sequence steps. When `variants` is set, the
|
|
233
|
+
* string form is narrowed to the map's keys, so a key typo is a compile
|
|
234
|
+
* error and the keys autocomplete — no `as const` required.
|
|
235
|
+
*/
|
|
236
|
+
animate?: AnimateStyle<C> | (keyof V & string);
|
|
237
|
+
/**
|
|
238
|
+
* Values applied while the component exits via `<Presence>`.
|
|
239
|
+
*/
|
|
240
|
+
exit?: AnimateStyle<C>;
|
|
241
|
+
/**
|
|
242
|
+
* Named animation states. With `variants` set, `animate` accepts a key from
|
|
243
|
+
* this map.
|
|
244
|
+
*/
|
|
245
|
+
variants?: V;
|
|
246
|
+
/**
|
|
247
|
+
* Imperative controller from `useVariants(...)`. When supplied, `animate`
|
|
248
|
+
* is read from `controller.current` and re-applied whenever the controller
|
|
249
|
+
* transitions. `animate` and `controller` should not both be set.
|
|
250
|
+
*/
|
|
251
|
+
controller?: VariantController<keyof V & string>;
|
|
252
|
+
/**
|
|
253
|
+
* Gesture-driven sub-states (`pressed`, `focused`, `focusVisible`,
|
|
254
|
+
* `hovered`). When omitted, no handlers are mounted on the underlying
|
|
255
|
+
* component. Each declared sub-state animates as an independent layer
|
|
256
|
+
* fading in/out over the base `animate` target — see `GestureSubStates`
|
|
257
|
+
* for the composition model and per-layer transition wiring.
|
|
258
|
+
*/
|
|
259
|
+
gesture?: GestureSubStates<C>;
|
|
260
|
+
/**
|
|
261
|
+
* Per-property or top-level transition config. Per-property entries take
|
|
262
|
+
* precedence over the top-level transition.
|
|
263
|
+
*/
|
|
264
|
+
transition?: Transition<AnimateStyle<C>>;
|
|
265
|
+
/**
|
|
266
|
+
* Auto-layout animation. When the component's position or size changes
|
|
267
|
+
* because of a parent layout change (a flex sibling growing, a list
|
|
268
|
+
* reordering, a column toggling its width), interpolate between the old
|
|
269
|
+
* and new layout instead of snapping.
|
|
270
|
+
*
|
|
271
|
+
* - `true` — animate with the library's default spring.
|
|
272
|
+
* - `TransitionConfig` — spring (react-spring vocab) or timing config; the
|
|
273
|
+
* resolver bridges to Reanimated's `LinearTransition` builder.
|
|
274
|
+
* - omitted / `false` — no layout animation (default).
|
|
275
|
+
*
|
|
276
|
+
* Only `'spring'` / `'timing'` / `'no-animation'` map to layout transitions
|
|
277
|
+
* — decay is downgraded to spring (no clear target). Reduced motion gates
|
|
278
|
+
* the prop the same way it gates `animate`.
|
|
279
|
+
*
|
|
280
|
+
* `layoutId` (below) is a related but distinct mechanism for shared
|
|
281
|
+
* element transitions across screens — `layout` animates this element's
|
|
282
|
+
* own layout changes, `layoutId` animates from a different element's
|
|
283
|
+
* last measured rect to this element's current rect.
|
|
284
|
+
*/
|
|
285
|
+
layout?: boolean | TransitionConfig;
|
|
286
|
+
/**
|
|
287
|
+
* Shared-element transition id. When a Motion primitive with `layoutId`
|
|
288
|
+
* unmounts, its last on-screen rect is recorded under that id; the next
|
|
289
|
+
* mount of any Motion primitive with the same id animates from the
|
|
290
|
+
* recorded rect to its natural position via a FLIP transform stack.
|
|
291
|
+
*
|
|
292
|
+
* Reanimated 4 removed the `sharedTransitionTag` API — `layoutId` is the
|
|
293
|
+
* Inertia-side measure-based replacement. Rects are recorded in
|
|
294
|
+
* parent-relative coordinates (from `onLayout`), which composes when the
|
|
295
|
+
* source and target screens share an outer content container (the common
|
|
296
|
+
* stack-navigator case); nested-parent layouts need the v2
|
|
297
|
+
* window-coordinate path.
|
|
298
|
+
*
|
|
299
|
+
* The same `transition` prop drives the FLIP animation (spring by
|
|
300
|
+
* default; `'timing'` honored; `'decay'` downgrades to spring; reduced
|
|
301
|
+
* motion skips the transition). Out of scope for the first iteration:
|
|
302
|
+
* style-prop interpolation (border radius, colors, etc.) — only the
|
|
303
|
+
* rect-to-rect transform is animated. Two simultaneously-mounted
|
|
304
|
+
* primitives sharing the same `layoutId` are undefined behavior; pick a
|
|
305
|
+
* primitive per id at a time.
|
|
306
|
+
*/
|
|
307
|
+
layoutId?: string;
|
|
308
|
+
/**
|
|
309
|
+
* Fired once per logical animation completion. See `AnimationCallbackInfo`
|
|
310
|
+
* for the payload shape — transform parents fire once, not per axis.
|
|
311
|
+
*/
|
|
312
|
+
onAnimationEnd?: (info: AnimationCallbackInfo<AnimateStyle<C>>) => void;
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Props of a Motion primitive for a given underlying component `C` and a
|
|
316
|
+
* concrete variants map `V`: the component's own props (minus `style`, which
|
|
317
|
+
* we replace with an animated style) intersected with the Motion props.
|
|
318
|
+
*/
|
|
319
|
+
type MotionComponentProps<C extends ComponentType<any>, V extends VariantsMap<ComponentProps<C>> = VariantsMap<ComponentProps<C>>> = Omit<ComponentProps<C>, 'style'> & MotionProps<ComponentProps<C>, V> & {
|
|
320
|
+
style?: ComponentProps<C>['style'];
|
|
321
|
+
ref?: Ref<unknown>;
|
|
322
|
+
};
|
|
323
|
+
/**
|
|
324
|
+
* The component type produced by `createMotionComponent`.
|
|
325
|
+
*
|
|
326
|
+
* It is a **generic call signature**, not a plain `ComponentType`: the variant
|
|
327
|
+
* map `V` is inferred from the `variants` prop at each JSX use. That inference
|
|
328
|
+
* is what narrows `animate`'s string form to the variant keys, so
|
|
329
|
+
* `<Motion.View variants={{ open, closed }} animate="opne" />` is a compile
|
|
330
|
+
* error and `open` / `closed` autocomplete. With no `variants` prop, `V` falls
|
|
331
|
+
* back to the open `VariantsMap`, so `animate` still accepts any string and the
|
|
332
|
+
* variant-less call site is unchanged.
|
|
333
|
+
*/
|
|
334
|
+
interface MotionComponent<C extends ComponentType<any>> {
|
|
335
|
+
<V extends VariantsMap<ComponentProps<C>> = VariantsMap<ComponentProps<C>>>(props: MotionComponentProps<C, V>): ReactElement | null;
|
|
336
|
+
displayName?: string;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
export type { AnimatableValue as A, DecayTransition as D, EasingInput as E, GestureSubStates as G, MotionComponent as M, NoAnimationTransition as N, PerPropertyTransition as P, RepeatConfig as R, SpringTransition as S, TransitionConfig as T, VariantController as V, AnimateStyle as a, AnimationCallbackInfo as b, MotionProps as c, SequenceStep as d, TimingTransition as e, Transition as f, VariantsMap as g, GestureLayerTransitions as h };
|