@rootnative/inertia 0.0.0-alpha.0 → 0.0.0-alpha.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.
- package/CHANGELOG.md +10 -0
- package/README.md +2 -0
- package/dist/gestureLayer/index.d.mts +48 -7
- package/dist/gestureLayer/index.d.ts +48 -7
- package/dist/gestureLayer/index.js +107 -30
- package/dist/gestureLayer/index.mjs +107 -30
- package/dist/index.d.mts +127 -16
- package/dist/index.d.ts +127 -16
- package/dist/index.js +177 -62
- package/dist/index.mjs +175 -63
- package/dist/motion/Image.d.mts +1 -1
- package/dist/motion/Image.d.ts +1 -1
- package/dist/motion/Image.js +90 -50
- package/dist/motion/Image.mjs +90 -50
- package/dist/motion/Pressable.d.mts +1 -1
- package/dist/motion/Pressable.d.ts +1 -1
- package/dist/motion/Pressable.js +90 -50
- package/dist/motion/Pressable.mjs +90 -50
- package/dist/motion/ScrollView.d.mts +1 -1
- package/dist/motion/ScrollView.d.ts +1 -1
- package/dist/motion/ScrollView.js +90 -50
- package/dist/motion/ScrollView.mjs +90 -50
- package/dist/motion/Text.d.mts +1 -1
- package/dist/motion/Text.d.ts +1 -1
- package/dist/motion/Text.js +90 -50
- package/dist/motion/Text.mjs +90 -50
- package/dist/motion/View.d.mts +1 -1
- package/dist/motion/View.d.ts +1 -1
- package/dist/motion/View.js +90 -50
- package/dist/motion/View.mjs +90 -50
- package/dist/testing/index.js +0 -2
- package/dist/testing/index.mjs +0 -2
- package/dist/touch/index.d.mts +1 -1
- package/dist/touch/index.d.ts +1 -1
- package/dist/touch/index.js +0 -2
- package/dist/touch/index.mjs +0 -2
- package/dist/{types-cU43dEmH.d.mts → types-BzEgiUdJ.d.mts} +58 -9
- package/dist/{types-cU43dEmH.d.ts → types-BzEgiUdJ.d.ts} +58 -9
- package/dist/{useGesture-BnY65PlQ.d.ts → useGesture-BRLgiNOC.d.ts} +6 -4
- package/dist/{useGesture-DxtXdz-K.d.mts → useGesture-C0GBS7d2.d.mts} +6 -4
- package/llms.txt +9 -5
- package/package.json +2 -1
- package/src/config/MotionConfig.tsx +55 -9
- package/src/config/MotionConfigContext.ts +21 -1
- package/src/config/index.ts +7 -1
- package/src/config/namedTransitions.ts +80 -0
- package/src/gestureLayer/index.ts +1 -0
- package/src/gestureLayer/useGestureLayer.ts +92 -8
- package/src/index.ts +20 -2
- package/src/motion/createMotionComponent.tsx +36 -6
- package/src/transitions/cubicBezier.ts +126 -0
- package/src/transitions/index.ts +1 -0
- package/src/types.ts +63 -8
- package/src/values/useAnimation.ts +12 -6
- package/src/values/useBooleanSpring.ts +5 -3
- package/src/values/useGesture.ts +25 -7
- package/src/values/useMotionValue.ts +11 -0
- package/src/values/useScroll.ts +8 -1
- package/src/values/useSpring.ts +46 -9
- package/dist/gestureLayer/index.js.map +0 -1
- package/dist/gestureLayer/index.mjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/dist/motion/Image.js.map +0 -1
- package/dist/motion/Image.mjs.map +0 -1
- package/dist/motion/Pressable.js.map +0 -1
- package/dist/motion/Pressable.mjs.map +0 -1
- package/dist/motion/ScrollView.js.map +0 -1
- package/dist/motion/ScrollView.mjs.map +0 -1
- package/dist/motion/Text.js.map +0 -1
- package/dist/motion/Text.mjs.map +0 -1
- package/dist/motion/View.js.map +0 -1
- package/dist/motion/View.mjs.map +0 -1
- package/dist/testing/index.js.map +0 -1
- package/dist/testing/index.mjs.map +0 -1
- package/dist/touch/index.js.map +0 -1
- package/dist/touch/index.mjs.map +0 -1
- package/src/__type-tests__/animate.test-d.tsx +0 -88
- package/src/__type-tests__/variants.test-d.tsx +0 -67
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,16 @@ All notable changes to `@rootnative/inertia` are documented here. The format fol
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **Named transition registry** — `<MotionConfig transitions={{ name: TransitionConfig }}>` registers named transitions for the subtree; the name is accepted everywhere a `TransitionConfig` is: the `transition` prop (top-level, per-property, per gesture layer), the `layout` prop, and `useAnimation` / `useSpring` / `useBooleanSpring` / `useGesture` / `useGestureLayer`. Names resolve at the nearest provider; nested providers merge with child-overrides-per-name; unknown names warn in dev and fall back to the default spring. No presets ship — names are consumer vocabulary. New exports: `useNamedTransitions()`, `resolveNamedTransition()`, and the `TransitionName` / `TransitionInput` / `NamedTransitions` / `RegisteredTransitions` types (`RegisteredTransitions` is the augmentation point for compile-time-typed names).
|
|
10
|
+
|
|
11
|
+
- **`cubicBezier()` easing helper** — builds a `timing.easing` value from cubic-bezier control points as four numbers, as a W3C CSS `cubic-bezier(x1, y1, x2, y2)` string, or as a CSS keyword (`'linear'` / `'ease'` / `'ease-in'` / `'ease-out'` / `'ease-in-out'`). Makes CSS-format design-token easings directly consumable (pair with the named-transition registry). Invalid input throws: `x1` / `x2` must be finite and within `[0, 1]`; `step-*` keywords and the CSS `linear(...)` function are unsupported. The `EasingFunction` / `EasingFunctionFactory` / `EasingInput` types are now exported from the root barrel.
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- **Nested `<MotionConfig>` now inherits `reducedMotion`** from its ancestor when the prop is omitted (previously an inner provider silently reset the subtree to the `'user'` default). A transitions-only inner provider no longer clobbers an outer `reducedMotion="never"` / `"always"`.
|
|
16
|
+
|
|
7
17
|
## [0.0.0-alpha.0]
|
|
8
18
|
|
|
9
19
|
Initial alpha publish. The full v0.1 surface is in place; APIs are still subject to change before `0.1.0`.
|
package/README.md
CHANGED
|
@@ -126,6 +126,8 @@ Full docs, every primitive's example screen, and an `llms-full.txt` reference li
|
|
|
126
126
|
- [llms.txt](https://rootnative.github.io/inertia/llms.txt) — concise overview
|
|
127
127
|
- [llms-full.txt](https://rootnative.github.io/inertia/llms-full.txt) — full API reference
|
|
128
128
|
|
|
129
|
+
AI agents: this package ships its own copy of the reference — read `node_modules/@rootnative/inertia/llms.txt` for the full API, no network needed.
|
|
130
|
+
|
|
129
131
|
## License
|
|
130
132
|
|
|
131
133
|
[MIT](./LICENSE) © RootNative
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { AnimatedStyle } from 'react-native-reanimated';
|
|
2
|
-
import { U as UseGestureHandlers } from '../useGesture-
|
|
3
|
-
import { T as
|
|
1
|
+
import { SharedValue, AnimatedStyle } from 'react-native-reanimated';
|
|
2
|
+
import { U as UseGestureHandlers } from '../useGesture-C0GBS7d2.mjs';
|
|
3
|
+
import { T as TransitionInput, n as GestureLayerTransitions } from '../types-BzEgiUdJ.mjs';
|
|
4
4
|
import 'react';
|
|
5
5
|
import 'react-native';
|
|
6
6
|
|
|
@@ -49,10 +49,31 @@ interface UseGestureLayerOptions {
|
|
|
49
49
|
/**
|
|
50
50
|
* Transition forwarded to the underlying `useGesture` hook. Either a single
|
|
51
51
|
* `TransitionConfig` for every gesture layer, or a `GestureLayerTransitions`
|
|
52
|
-
* map for per-layer fades.
|
|
53
|
-
*
|
|
52
|
+
* map for per-layer fades. A `TransitionName` registered on the nearest
|
|
53
|
+
* `<MotionConfig transitions>` is accepted in both positions. Reduced
|
|
54
|
+
* motion collapses every transition to `no-animation`.
|
|
54
55
|
*/
|
|
55
|
-
transition?:
|
|
56
|
+
transition?: TransitionInput | GestureLayerTransitions;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* The per-state 0↔1 progress shared values behind a `useGestureLayer` call.
|
|
60
|
+
* The gesture entries are the same shared values `useGesture` owns; `disabled`
|
|
61
|
+
* is driven by `options.disabled`. All five are stable across renders — feed
|
|
62
|
+
* them into any `useAnimatedStyle` / `useDerivedValue` (or hooks like
|
|
63
|
+
* `useShadow({ progress })`) to derive extra styles from the same gesture
|
|
64
|
+
* wiring without a second `useGesture` call.
|
|
65
|
+
*/
|
|
66
|
+
interface GestureLayerProgress {
|
|
67
|
+
/** 0↔1 progress for the hovered layer (web only — stays at 0 on native). */
|
|
68
|
+
hovered: SharedValue<number>;
|
|
69
|
+
/** 0↔1 progress for the focused layer (any focus modality). */
|
|
70
|
+
focused: SharedValue<number>;
|
|
71
|
+
/** 0↔1 progress for the focusVisible layer (keyboard focus only). */
|
|
72
|
+
focusVisible: SharedValue<number>;
|
|
73
|
+
/** 0↔1 progress for the pressed layer. */
|
|
74
|
+
pressed: SharedValue<number>;
|
|
75
|
+
/** 0↔1 progress for the disabled override (driven by `options.disabled`). */
|
|
76
|
+
disabled: SharedValue<number>;
|
|
56
77
|
}
|
|
57
78
|
interface UseGestureLayerResult {
|
|
58
79
|
/**
|
|
@@ -62,6 +83,12 @@ interface UseGestureLayerResult {
|
|
|
62
83
|
style: AnimatedStyle<Record<string, unknown>>;
|
|
63
84
|
/** Handlers to spread on the receiving `Pressable`. */
|
|
64
85
|
handlers: UseGestureHandlers;
|
|
86
|
+
/**
|
|
87
|
+
* Per-state progress shared values — the inputs the composed `style` is
|
|
88
|
+
* derived from. Read-only by convention: writing to them fights the
|
|
89
|
+
* handlers.
|
|
90
|
+
*/
|
|
91
|
+
states: GestureLayerProgress;
|
|
65
92
|
}
|
|
66
93
|
/**
|
|
67
94
|
* A "strongest active layer wins" interactive-feedback primitive. Sits one
|
|
@@ -84,6 +111,13 @@ interface UseGestureLayerResult {
|
|
|
84
111
|
* keys — when active, it lerps the composed value toward the `disabled`
|
|
85
112
|
* target.
|
|
86
113
|
*
|
|
114
|
+
* Alongside `style` and `handlers`, the hook returns `states` — the per-state
|
|
115
|
+
* 0↔1 progress shared values the style is derived from (the four gesture
|
|
116
|
+
* layers plus the disabled override). Feed them into other progress-driven
|
|
117
|
+
* hooks (`useShadow`, `useColorTransition`) or a custom `useAnimatedStyle`
|
|
118
|
+
* to derive extra styles from the same gesture wiring — no second
|
|
119
|
+
* `useGesture` call, no duplicated handlers.
|
|
120
|
+
*
|
|
87
121
|
* Reach for this when you want MD3 / iOS-translucent state-layer overlays
|
|
88
122
|
* without rewriting the worklet by hand for every consumer; reach for plain
|
|
89
123
|
* `useGesture()` when you need a composition model this hook doesn't
|
|
@@ -113,7 +147,14 @@ interface UseGestureLayerResult {
|
|
|
113
147
|
* )
|
|
114
148
|
* }
|
|
115
149
|
* ```
|
|
150
|
+
*
|
|
151
|
+
* @example Elevation crossfade driven by the hover progress
|
|
152
|
+
* ```tsx
|
|
153
|
+
* const { style, handlers, states } = useGestureLayer(layers, options)
|
|
154
|
+
* const shadow = useShadow({ from: restShadow, to: raisedShadow, progress: states.hovered })
|
|
155
|
+
* // <Animated.View style={[style, shadow]} />
|
|
156
|
+
* ```
|
|
116
157
|
*/
|
|
117
158
|
declare function useGestureLayer(states: GestureLayerStates, options?: UseGestureLayerOptions): UseGestureLayerResult;
|
|
118
159
|
|
|
119
|
-
export { type GestureLayerStates, type GestureLayerStyle, type UseGestureLayerOptions, type UseGestureLayerResult, useGestureLayer };
|
|
160
|
+
export { type GestureLayerProgress, type GestureLayerStates, type GestureLayerStyle, type UseGestureLayerOptions, type UseGestureLayerResult, useGestureLayer };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { AnimatedStyle } from 'react-native-reanimated';
|
|
2
|
-
import { U as UseGestureHandlers } from '../useGesture-
|
|
3
|
-
import { T as
|
|
1
|
+
import { SharedValue, AnimatedStyle } from 'react-native-reanimated';
|
|
2
|
+
import { U as UseGestureHandlers } from '../useGesture-BRLgiNOC.js';
|
|
3
|
+
import { T as TransitionInput, n as GestureLayerTransitions } from '../types-BzEgiUdJ.js';
|
|
4
4
|
import 'react';
|
|
5
5
|
import 'react-native';
|
|
6
6
|
|
|
@@ -49,10 +49,31 @@ interface UseGestureLayerOptions {
|
|
|
49
49
|
/**
|
|
50
50
|
* Transition forwarded to the underlying `useGesture` hook. Either a single
|
|
51
51
|
* `TransitionConfig` for every gesture layer, or a `GestureLayerTransitions`
|
|
52
|
-
* map for per-layer fades.
|
|
53
|
-
*
|
|
52
|
+
* map for per-layer fades. A `TransitionName` registered on the nearest
|
|
53
|
+
* `<MotionConfig transitions>` is accepted in both positions. Reduced
|
|
54
|
+
* motion collapses every transition to `no-animation`.
|
|
54
55
|
*/
|
|
55
|
-
transition?:
|
|
56
|
+
transition?: TransitionInput | GestureLayerTransitions;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* The per-state 0↔1 progress shared values behind a `useGestureLayer` call.
|
|
60
|
+
* The gesture entries are the same shared values `useGesture` owns; `disabled`
|
|
61
|
+
* is driven by `options.disabled`. All five are stable across renders — feed
|
|
62
|
+
* them into any `useAnimatedStyle` / `useDerivedValue` (or hooks like
|
|
63
|
+
* `useShadow({ progress })`) to derive extra styles from the same gesture
|
|
64
|
+
* wiring without a second `useGesture` call.
|
|
65
|
+
*/
|
|
66
|
+
interface GestureLayerProgress {
|
|
67
|
+
/** 0↔1 progress for the hovered layer (web only — stays at 0 on native). */
|
|
68
|
+
hovered: SharedValue<number>;
|
|
69
|
+
/** 0↔1 progress for the focused layer (any focus modality). */
|
|
70
|
+
focused: SharedValue<number>;
|
|
71
|
+
/** 0↔1 progress for the focusVisible layer (keyboard focus only). */
|
|
72
|
+
focusVisible: SharedValue<number>;
|
|
73
|
+
/** 0↔1 progress for the pressed layer. */
|
|
74
|
+
pressed: SharedValue<number>;
|
|
75
|
+
/** 0↔1 progress for the disabled override (driven by `options.disabled`). */
|
|
76
|
+
disabled: SharedValue<number>;
|
|
56
77
|
}
|
|
57
78
|
interface UseGestureLayerResult {
|
|
58
79
|
/**
|
|
@@ -62,6 +83,12 @@ interface UseGestureLayerResult {
|
|
|
62
83
|
style: AnimatedStyle<Record<string, unknown>>;
|
|
63
84
|
/** Handlers to spread on the receiving `Pressable`. */
|
|
64
85
|
handlers: UseGestureHandlers;
|
|
86
|
+
/**
|
|
87
|
+
* Per-state progress shared values — the inputs the composed `style` is
|
|
88
|
+
* derived from. Read-only by convention: writing to them fights the
|
|
89
|
+
* handlers.
|
|
90
|
+
*/
|
|
91
|
+
states: GestureLayerProgress;
|
|
65
92
|
}
|
|
66
93
|
/**
|
|
67
94
|
* A "strongest active layer wins" interactive-feedback primitive. Sits one
|
|
@@ -84,6 +111,13 @@ interface UseGestureLayerResult {
|
|
|
84
111
|
* keys — when active, it lerps the composed value toward the `disabled`
|
|
85
112
|
* target.
|
|
86
113
|
*
|
|
114
|
+
* Alongside `style` and `handlers`, the hook returns `states` — the per-state
|
|
115
|
+
* 0↔1 progress shared values the style is derived from (the four gesture
|
|
116
|
+
* layers plus the disabled override). Feed them into other progress-driven
|
|
117
|
+
* hooks (`useShadow`, `useColorTransition`) or a custom `useAnimatedStyle`
|
|
118
|
+
* to derive extra styles from the same gesture wiring — no second
|
|
119
|
+
* `useGesture` call, no duplicated handlers.
|
|
120
|
+
*
|
|
87
121
|
* Reach for this when you want MD3 / iOS-translucent state-layer overlays
|
|
88
122
|
* without rewriting the worklet by hand for every consumer; reach for plain
|
|
89
123
|
* `useGesture()` when you need a composition model this hook doesn't
|
|
@@ -113,7 +147,14 @@ interface UseGestureLayerResult {
|
|
|
113
147
|
* )
|
|
114
148
|
* }
|
|
115
149
|
* ```
|
|
150
|
+
*
|
|
151
|
+
* @example Elevation crossfade driven by the hover progress
|
|
152
|
+
* ```tsx
|
|
153
|
+
* const { style, handlers, states } = useGestureLayer(layers, options)
|
|
154
|
+
* const shadow = useShadow({ from: restShadow, to: raisedShadow, progress: states.hovered })
|
|
155
|
+
* // <Animated.View style={[style, shadow]} />
|
|
156
|
+
* ```
|
|
116
157
|
*/
|
|
117
158
|
declare function useGestureLayer(states: GestureLayerStates, options?: UseGestureLayerOptions): UseGestureLayerResult;
|
|
118
159
|
|
|
119
|
-
export { type GestureLayerStates, type GestureLayerStyle, type UseGestureLayerOptions, type UseGestureLayerResult, useGestureLayer };
|
|
160
|
+
export { type GestureLayerProgress, type GestureLayerStates, type GestureLayerStyle, type UseGestureLayerOptions, type UseGestureLayerResult, useGestureLayer };
|
|
@@ -6,8 +6,31 @@ var reactNativeWorklets = require('react-native-worklets');
|
|
|
6
6
|
var reactNative = require('react-native');
|
|
7
7
|
|
|
8
8
|
// src/gestureLayer/useGestureLayer.ts
|
|
9
|
+
|
|
10
|
+
// src/transitions/sig.ts
|
|
11
|
+
function stableSig(value) {
|
|
12
|
+
if (value === void 0) return "";
|
|
13
|
+
try {
|
|
14
|
+
return stableStringify(value);
|
|
15
|
+
} catch {
|
|
16
|
+
return String(value);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function stableStringify(v) {
|
|
20
|
+
if (v === null || typeof v !== "object") {
|
|
21
|
+
if (typeof v === "function" || v === void 0) return "null";
|
|
22
|
+
return JSON.stringify(v);
|
|
23
|
+
}
|
|
24
|
+
if (Array.isArray(v)) {
|
|
25
|
+
return "[" + v.map(stableStringify).join(",") + "]";
|
|
26
|
+
}
|
|
27
|
+
const obj = v;
|
|
28
|
+
const keys = Object.keys(obj).sort();
|
|
29
|
+
return "{" + keys.map((k) => JSON.stringify(k) + ":" + stableStringify(obj[k])).join(",") + "}";
|
|
30
|
+
}
|
|
9
31
|
var DEFAULT_MOTION_CONFIG = {
|
|
10
|
-
reducedMotion: "user"
|
|
32
|
+
reducedMotion: "user",
|
|
33
|
+
transitions: {}
|
|
11
34
|
};
|
|
12
35
|
var MotionConfigContext = react.createContext(
|
|
13
36
|
DEFAULT_MOTION_CONFIG
|
|
@@ -15,6 +38,9 @@ var MotionConfigContext = react.createContext(
|
|
|
15
38
|
function useMotionConfig() {
|
|
16
39
|
return react.useContext(MotionConfigContext);
|
|
17
40
|
}
|
|
41
|
+
function useNamedTransitions() {
|
|
42
|
+
return useMotionConfig().transitions;
|
|
43
|
+
}
|
|
18
44
|
function useShouldReduceMotion() {
|
|
19
45
|
const { reducedMotion } = useMotionConfig();
|
|
20
46
|
const osReduced = reactNativeReanimated.useReducedMotion();
|
|
@@ -22,6 +48,59 @@ function useShouldReduceMotion() {
|
|
|
22
48
|
if (reducedMotion === "always") return true;
|
|
23
49
|
return osReduced;
|
|
24
50
|
}
|
|
51
|
+
|
|
52
|
+
// src/transitions/keys.ts
|
|
53
|
+
var TRANSITION_CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
54
|
+
"type",
|
|
55
|
+
"tension",
|
|
56
|
+
"friction",
|
|
57
|
+
"mass",
|
|
58
|
+
"velocity",
|
|
59
|
+
"restSpeedThreshold",
|
|
60
|
+
"restDisplacementThreshold",
|
|
61
|
+
"duration",
|
|
62
|
+
"easing",
|
|
63
|
+
"delay",
|
|
64
|
+
"repeat",
|
|
65
|
+
"deceleration",
|
|
66
|
+
"clamp"
|
|
67
|
+
]);
|
|
68
|
+
function isTopLevelTransition(t) {
|
|
69
|
+
if (t === null || typeof t !== "object") return false;
|
|
70
|
+
const keys = Object.keys(t);
|
|
71
|
+
if (keys.length === 0) return false;
|
|
72
|
+
return keys.every((k) => TRANSITION_CONFIG_KEYS.has(k));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// src/config/namedTransitions.ts
|
|
76
|
+
var UNKNOWN_NAME_FALLBACK = { type: "spring" };
|
|
77
|
+
function lookupNamedTransition(name, registry) {
|
|
78
|
+
const cfg = registry[name];
|
|
79
|
+
if (cfg) return cfg;
|
|
80
|
+
if (__DEV__) {
|
|
81
|
+
console.warn(
|
|
82
|
+
`[inertia] Unknown transition name "${name}" \u2014 falling back to the default spring. Register it on a provider: <MotionConfig transitions={{ '${name}': { ... } }}>.`
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
return UNKNOWN_NAME_FALLBACK;
|
|
86
|
+
}
|
|
87
|
+
function resolveNamedTransitionProp(transition, registry) {
|
|
88
|
+
if (transition === void 0) return void 0;
|
|
89
|
+
if (typeof transition === "string") {
|
|
90
|
+
return lookupNamedTransition(transition, registry);
|
|
91
|
+
}
|
|
92
|
+
if (isTopLevelTransition(transition)) return transition;
|
|
93
|
+
const map = transition;
|
|
94
|
+
let out = null;
|
|
95
|
+
for (const key in map) {
|
|
96
|
+
const value = map[key];
|
|
97
|
+
if (typeof value === "string") {
|
|
98
|
+
if (out === null) out = { ...map };
|
|
99
|
+
out[key] = lookupNamedTransition(value, registry);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return out ?? transition;
|
|
103
|
+
}
|
|
25
104
|
function ensureWorkletEasing(easing) {
|
|
26
105
|
if (!easing) return void 0;
|
|
27
106
|
const fn = isEasingFactory(easing) ? easing.factory() : easing;
|
|
@@ -117,29 +196,6 @@ function delayOf(cfg) {
|
|
|
117
196
|
if (cfg.type === "no-animation") return void 0;
|
|
118
197
|
return cfg.delay;
|
|
119
198
|
}
|
|
120
|
-
|
|
121
|
-
// src/transitions/keys.ts
|
|
122
|
-
var TRANSITION_CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
123
|
-
"type",
|
|
124
|
-
"tension",
|
|
125
|
-
"friction",
|
|
126
|
-
"mass",
|
|
127
|
-
"velocity",
|
|
128
|
-
"restSpeedThreshold",
|
|
129
|
-
"restDisplacementThreshold",
|
|
130
|
-
"duration",
|
|
131
|
-
"easing",
|
|
132
|
-
"delay",
|
|
133
|
-
"repeat",
|
|
134
|
-
"deceleration",
|
|
135
|
-
"clamp"
|
|
136
|
-
]);
|
|
137
|
-
function isTopLevelTransition(t) {
|
|
138
|
-
if (t === null || typeof t !== "object") return false;
|
|
139
|
-
const keys = Object.keys(t);
|
|
140
|
-
if (keys.length === 0) return false;
|
|
141
|
-
return keys.every((k) => TRANSITION_CONFIG_KEYS.has(k));
|
|
142
|
-
}
|
|
143
199
|
var modality = "keyboard";
|
|
144
200
|
var installed = false;
|
|
145
201
|
function setKeyboard() {
|
|
@@ -171,9 +227,10 @@ function useGesture(transition) {
|
|
|
171
227
|
const focusVisible = reactNativeReanimated.useSharedValue(0);
|
|
172
228
|
const hovered = reactNativeReanimated.useSharedValue(0);
|
|
173
229
|
const shouldReduceMotion = useShouldReduceMotion();
|
|
230
|
+
const resolved = resolveNamedTransitionProp(transition, useNamedTransitions());
|
|
174
231
|
const setLayer = react.useCallback(
|
|
175
232
|
(sv, layer, target) => {
|
|
176
|
-
const cfg = shouldReduceMotion ? { type: "no-animation" } : layerTransition(layer,
|
|
233
|
+
const cfg = shouldReduceMotion ? { type: "no-animation" } : layerTransition(layer, resolved) ?? { type: "spring" };
|
|
177
234
|
sv.value = resolveTransition(cfg, target);
|
|
178
235
|
},
|
|
179
236
|
// The transition is intentionally read on every call rather than cooked
|
|
@@ -212,15 +269,20 @@ function layerTransition(layer, transition) {
|
|
|
212
269
|
|
|
213
270
|
// src/gestureLayer/useGestureLayer.ts
|
|
214
271
|
function useGestureLayer(states, options = {}) {
|
|
215
|
-
const { disabled: isDisabled = false, transition } = options;
|
|
272
|
+
const { disabled: isDisabled = false, transition: transitionInput } = options;
|
|
216
273
|
const shouldReduceMotion = useShouldReduceMotion();
|
|
274
|
+
const transition = resolveNamedTransitionProp(
|
|
275
|
+
transitionInput,
|
|
276
|
+
useNamedTransitions()
|
|
277
|
+
);
|
|
217
278
|
const gesture = useGesture(transition);
|
|
218
279
|
const disabledProgress = reactNativeReanimated.useSharedValue(0);
|
|
280
|
+
const transitionSig = stableSig(transition);
|
|
219
281
|
react.useEffect(() => {
|
|
220
282
|
const target = isDisabled ? 1 : 0;
|
|
221
283
|
const cfg = shouldReduceMotion ? { type: "no-animation" } : disabledTransition(transition) ?? { type: "spring" };
|
|
222
284
|
disabledProgress.value = resolveTransition(cfg, target);
|
|
223
|
-
}, [isDisabled, shouldReduceMotion,
|
|
285
|
+
}, [isDisabled, shouldReduceMotion, transitionSig, disabledProgress]);
|
|
224
286
|
const meta = react.useMemo(() => {
|
|
225
287
|
const layers = {
|
|
226
288
|
rest: states.rest,
|
|
@@ -330,9 +392,26 @@ function useGestureLayer(states, options = {}) {
|
|
|
330
392
|
}
|
|
331
393
|
return out;
|
|
332
394
|
});
|
|
395
|
+
const progress = react.useMemo(
|
|
396
|
+
() => ({
|
|
397
|
+
hovered: gesture.hovered,
|
|
398
|
+
focused: gesture.focused,
|
|
399
|
+
focusVisible: gesture.focusVisible,
|
|
400
|
+
pressed: gesture.pressed,
|
|
401
|
+
disabled: disabledProgress
|
|
402
|
+
}),
|
|
403
|
+
[
|
|
404
|
+
gesture.hovered,
|
|
405
|
+
gesture.focused,
|
|
406
|
+
gesture.focusVisible,
|
|
407
|
+
gesture.pressed,
|
|
408
|
+
disabledProgress
|
|
409
|
+
]
|
|
410
|
+
);
|
|
333
411
|
return {
|
|
334
412
|
style,
|
|
335
|
-
handlers: gesture.handlers
|
|
413
|
+
handlers: gesture.handlers,
|
|
414
|
+
states: progress
|
|
336
415
|
};
|
|
337
416
|
}
|
|
338
417
|
function disabledTransition(transition) {
|
|
@@ -342,5 +421,3 @@ function disabledTransition(transition) {
|
|
|
342
421
|
}
|
|
343
422
|
|
|
344
423
|
exports.useGestureLayer = useGestureLayer;
|
|
345
|
-
//# sourceMappingURL=index.js.map
|
|
346
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -4,8 +4,31 @@ import { isWorkletFunction } from 'react-native-worklets';
|
|
|
4
4
|
import { Platform } from 'react-native';
|
|
5
5
|
|
|
6
6
|
// src/gestureLayer/useGestureLayer.ts
|
|
7
|
+
|
|
8
|
+
// src/transitions/sig.ts
|
|
9
|
+
function stableSig(value) {
|
|
10
|
+
if (value === void 0) return "";
|
|
11
|
+
try {
|
|
12
|
+
return stableStringify(value);
|
|
13
|
+
} catch {
|
|
14
|
+
return String(value);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function stableStringify(v) {
|
|
18
|
+
if (v === null || typeof v !== "object") {
|
|
19
|
+
if (typeof v === "function" || v === void 0) return "null";
|
|
20
|
+
return JSON.stringify(v);
|
|
21
|
+
}
|
|
22
|
+
if (Array.isArray(v)) {
|
|
23
|
+
return "[" + v.map(stableStringify).join(",") + "]";
|
|
24
|
+
}
|
|
25
|
+
const obj = v;
|
|
26
|
+
const keys = Object.keys(obj).sort();
|
|
27
|
+
return "{" + keys.map((k) => JSON.stringify(k) + ":" + stableStringify(obj[k])).join(",") + "}";
|
|
28
|
+
}
|
|
7
29
|
var DEFAULT_MOTION_CONFIG = {
|
|
8
|
-
reducedMotion: "user"
|
|
30
|
+
reducedMotion: "user",
|
|
31
|
+
transitions: {}
|
|
9
32
|
};
|
|
10
33
|
var MotionConfigContext = createContext(
|
|
11
34
|
DEFAULT_MOTION_CONFIG
|
|
@@ -13,6 +36,9 @@ var MotionConfigContext = createContext(
|
|
|
13
36
|
function useMotionConfig() {
|
|
14
37
|
return useContext(MotionConfigContext);
|
|
15
38
|
}
|
|
39
|
+
function useNamedTransitions() {
|
|
40
|
+
return useMotionConfig().transitions;
|
|
41
|
+
}
|
|
16
42
|
function useShouldReduceMotion() {
|
|
17
43
|
const { reducedMotion } = useMotionConfig();
|
|
18
44
|
const osReduced = useReducedMotion();
|
|
@@ -20,6 +46,59 @@ function useShouldReduceMotion() {
|
|
|
20
46
|
if (reducedMotion === "always") return true;
|
|
21
47
|
return osReduced;
|
|
22
48
|
}
|
|
49
|
+
|
|
50
|
+
// src/transitions/keys.ts
|
|
51
|
+
var TRANSITION_CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
52
|
+
"type",
|
|
53
|
+
"tension",
|
|
54
|
+
"friction",
|
|
55
|
+
"mass",
|
|
56
|
+
"velocity",
|
|
57
|
+
"restSpeedThreshold",
|
|
58
|
+
"restDisplacementThreshold",
|
|
59
|
+
"duration",
|
|
60
|
+
"easing",
|
|
61
|
+
"delay",
|
|
62
|
+
"repeat",
|
|
63
|
+
"deceleration",
|
|
64
|
+
"clamp"
|
|
65
|
+
]);
|
|
66
|
+
function isTopLevelTransition(t) {
|
|
67
|
+
if (t === null || typeof t !== "object") return false;
|
|
68
|
+
const keys = Object.keys(t);
|
|
69
|
+
if (keys.length === 0) return false;
|
|
70
|
+
return keys.every((k) => TRANSITION_CONFIG_KEYS.has(k));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// src/config/namedTransitions.ts
|
|
74
|
+
var UNKNOWN_NAME_FALLBACK = { type: "spring" };
|
|
75
|
+
function lookupNamedTransition(name, registry) {
|
|
76
|
+
const cfg = registry[name];
|
|
77
|
+
if (cfg) return cfg;
|
|
78
|
+
if (__DEV__) {
|
|
79
|
+
console.warn(
|
|
80
|
+
`[inertia] Unknown transition name "${name}" \u2014 falling back to the default spring. Register it on a provider: <MotionConfig transitions={{ '${name}': { ... } }}>.`
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
return UNKNOWN_NAME_FALLBACK;
|
|
84
|
+
}
|
|
85
|
+
function resolveNamedTransitionProp(transition, registry) {
|
|
86
|
+
if (transition === void 0) return void 0;
|
|
87
|
+
if (typeof transition === "string") {
|
|
88
|
+
return lookupNamedTransition(transition, registry);
|
|
89
|
+
}
|
|
90
|
+
if (isTopLevelTransition(transition)) return transition;
|
|
91
|
+
const map = transition;
|
|
92
|
+
let out = null;
|
|
93
|
+
for (const key in map) {
|
|
94
|
+
const value = map[key];
|
|
95
|
+
if (typeof value === "string") {
|
|
96
|
+
if (out === null) out = { ...map };
|
|
97
|
+
out[key] = lookupNamedTransition(value, registry);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return out ?? transition;
|
|
101
|
+
}
|
|
23
102
|
function ensureWorkletEasing(easing) {
|
|
24
103
|
if (!easing) return void 0;
|
|
25
104
|
const fn = isEasingFactory(easing) ? easing.factory() : easing;
|
|
@@ -115,29 +194,6 @@ function delayOf(cfg) {
|
|
|
115
194
|
if (cfg.type === "no-animation") return void 0;
|
|
116
195
|
return cfg.delay;
|
|
117
196
|
}
|
|
118
|
-
|
|
119
|
-
// src/transitions/keys.ts
|
|
120
|
-
var TRANSITION_CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
121
|
-
"type",
|
|
122
|
-
"tension",
|
|
123
|
-
"friction",
|
|
124
|
-
"mass",
|
|
125
|
-
"velocity",
|
|
126
|
-
"restSpeedThreshold",
|
|
127
|
-
"restDisplacementThreshold",
|
|
128
|
-
"duration",
|
|
129
|
-
"easing",
|
|
130
|
-
"delay",
|
|
131
|
-
"repeat",
|
|
132
|
-
"deceleration",
|
|
133
|
-
"clamp"
|
|
134
|
-
]);
|
|
135
|
-
function isTopLevelTransition(t) {
|
|
136
|
-
if (t === null || typeof t !== "object") return false;
|
|
137
|
-
const keys = Object.keys(t);
|
|
138
|
-
if (keys.length === 0) return false;
|
|
139
|
-
return keys.every((k) => TRANSITION_CONFIG_KEYS.has(k));
|
|
140
|
-
}
|
|
141
197
|
var modality = "keyboard";
|
|
142
198
|
var installed = false;
|
|
143
199
|
function setKeyboard() {
|
|
@@ -169,9 +225,10 @@ function useGesture(transition) {
|
|
|
169
225
|
const focusVisible = useSharedValue(0);
|
|
170
226
|
const hovered = useSharedValue(0);
|
|
171
227
|
const shouldReduceMotion = useShouldReduceMotion();
|
|
228
|
+
const resolved = resolveNamedTransitionProp(transition, useNamedTransitions());
|
|
172
229
|
const setLayer = useCallback(
|
|
173
230
|
(sv, layer, target) => {
|
|
174
|
-
const cfg = shouldReduceMotion ? { type: "no-animation" } : layerTransition(layer,
|
|
231
|
+
const cfg = shouldReduceMotion ? { type: "no-animation" } : layerTransition(layer, resolved) ?? { type: "spring" };
|
|
175
232
|
sv.value = resolveTransition(cfg, target);
|
|
176
233
|
},
|
|
177
234
|
// The transition is intentionally read on every call rather than cooked
|
|
@@ -210,15 +267,20 @@ function layerTransition(layer, transition) {
|
|
|
210
267
|
|
|
211
268
|
// src/gestureLayer/useGestureLayer.ts
|
|
212
269
|
function useGestureLayer(states, options = {}) {
|
|
213
|
-
const { disabled: isDisabled = false, transition } = options;
|
|
270
|
+
const { disabled: isDisabled = false, transition: transitionInput } = options;
|
|
214
271
|
const shouldReduceMotion = useShouldReduceMotion();
|
|
272
|
+
const transition = resolveNamedTransitionProp(
|
|
273
|
+
transitionInput,
|
|
274
|
+
useNamedTransitions()
|
|
275
|
+
);
|
|
215
276
|
const gesture = useGesture(transition);
|
|
216
277
|
const disabledProgress = useSharedValue(0);
|
|
278
|
+
const transitionSig = stableSig(transition);
|
|
217
279
|
useEffect(() => {
|
|
218
280
|
const target = isDisabled ? 1 : 0;
|
|
219
281
|
const cfg = shouldReduceMotion ? { type: "no-animation" } : disabledTransition(transition) ?? { type: "spring" };
|
|
220
282
|
disabledProgress.value = resolveTransition(cfg, target);
|
|
221
|
-
}, [isDisabled, shouldReduceMotion,
|
|
283
|
+
}, [isDisabled, shouldReduceMotion, transitionSig, disabledProgress]);
|
|
222
284
|
const meta = useMemo(() => {
|
|
223
285
|
const layers = {
|
|
224
286
|
rest: states.rest,
|
|
@@ -328,9 +390,26 @@ function useGestureLayer(states, options = {}) {
|
|
|
328
390
|
}
|
|
329
391
|
return out;
|
|
330
392
|
});
|
|
393
|
+
const progress = useMemo(
|
|
394
|
+
() => ({
|
|
395
|
+
hovered: gesture.hovered,
|
|
396
|
+
focused: gesture.focused,
|
|
397
|
+
focusVisible: gesture.focusVisible,
|
|
398
|
+
pressed: gesture.pressed,
|
|
399
|
+
disabled: disabledProgress
|
|
400
|
+
}),
|
|
401
|
+
[
|
|
402
|
+
gesture.hovered,
|
|
403
|
+
gesture.focused,
|
|
404
|
+
gesture.focusVisible,
|
|
405
|
+
gesture.pressed,
|
|
406
|
+
disabledProgress
|
|
407
|
+
]
|
|
408
|
+
);
|
|
331
409
|
return {
|
|
332
410
|
style,
|
|
333
|
-
handlers: gesture.handlers
|
|
411
|
+
handlers: gesture.handlers,
|
|
412
|
+
states: progress
|
|
334
413
|
};
|
|
335
414
|
}
|
|
336
415
|
function disabledTransition(transition) {
|
|
@@ -340,5 +419,3 @@ function disabledTransition(transition) {
|
|
|
340
419
|
}
|
|
341
420
|
|
|
342
421
|
export { useGestureLayer };
|
|
343
|
-
//# sourceMappingURL=index.mjs.map
|
|
344
|
-
//# sourceMappingURL=index.mjs.map
|