@onlynative/inertia 0.0.1-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/LICENSE +21 -0
  3. package/README.md +90 -0
  4. package/dist/index.d.mts +185 -0
  5. package/dist/index.d.ts +185 -0
  6. package/dist/index.js +817 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/index.mjs +796 -0
  9. package/dist/index.mjs.map +1 -0
  10. package/dist/motion/Image.d.mts +12 -0
  11. package/dist/motion/Image.d.ts +12 -0
  12. package/dist/motion/Image.js +656 -0
  13. package/dist/motion/Image.js.map +1 -0
  14. package/dist/motion/Image.mjs +650 -0
  15. package/dist/motion/Image.mjs.map +1 -0
  16. package/dist/motion/Pressable.d.mts +15 -0
  17. package/dist/motion/Pressable.d.ts +15 -0
  18. package/dist/motion/Pressable.js +656 -0
  19. package/dist/motion/Pressable.js.map +1 -0
  20. package/dist/motion/Pressable.mjs +650 -0
  21. package/dist/motion/Pressable.mjs.map +1 -0
  22. package/dist/motion/ScrollView.d.mts +12 -0
  23. package/dist/motion/ScrollView.d.ts +12 -0
  24. package/dist/motion/ScrollView.js +656 -0
  25. package/dist/motion/ScrollView.js.map +1 -0
  26. package/dist/motion/ScrollView.mjs +650 -0
  27. package/dist/motion/ScrollView.mjs.map +1 -0
  28. package/dist/motion/Text.d.mts +11 -0
  29. package/dist/motion/Text.d.ts +11 -0
  30. package/dist/motion/Text.js +656 -0
  31. package/dist/motion/Text.js.map +1 -0
  32. package/dist/motion/Text.mjs +650 -0
  33. package/dist/motion/Text.mjs.map +1 -0
  34. package/dist/motion/View.d.mts +11 -0
  35. package/dist/motion/View.d.ts +11 -0
  36. package/dist/motion/View.js +656 -0
  37. package/dist/motion/View.js.map +1 -0
  38. package/dist/motion/View.mjs +650 -0
  39. package/dist/motion/View.mjs.map +1 -0
  40. package/dist/types-CmbXx-G3.d.mts +185 -0
  41. package/dist/types-CmbXx-G3.d.ts +185 -0
  42. package/llms.txt +78 -0
  43. package/package.json +120 -0
  44. package/src/config/MotionConfig.tsx +30 -0
  45. package/src/config/MotionConfigContext.ts +53 -0
  46. package/src/config/index.ts +9 -0
  47. package/src/index.ts +49 -0
  48. package/src/motion/Image.tsx +9 -0
  49. package/src/motion/Pressable.tsx +12 -0
  50. package/src/motion/ScrollView.tsx +9 -0
  51. package/src/motion/Text.tsx +8 -0
  52. package/src/motion/View.tsx +8 -0
  53. package/src/motion/createMotionComponent.tsx +850 -0
  54. package/src/motion/index.ts +26 -0
  55. package/src/presence/Presence.tsx +165 -0
  56. package/src/presence/PresenceContext.ts +28 -0
  57. package/src/presence/index.ts +6 -0
  58. package/src/transitions/easing.ts +29 -0
  59. package/src/transitions/index.ts +2 -0
  60. package/src/transitions/resolve.ts +265 -0
  61. package/src/types.ts +207 -0
  62. package/src/values/index.ts +1 -0
  63. package/src/values/useVariants.ts +60 -0
package/src/types.ts ADDED
@@ -0,0 +1,207 @@
1
+ import { type ComponentType } from 'react'
2
+ import { type StyleProp } from 'react-native'
3
+
4
+ /**
5
+ * A single animation step's destination, optionally overriding the transition
6
+ * for that step.
7
+ */
8
+ export type SequenceStep<V> = V | ({ to: V; delay?: number } & TransitionConfig)
9
+
10
+ /**
11
+ * A target value for an animatable property: a single value, a sequence of
12
+ * steps (keyframes), or a single step object.
13
+ */
14
+ export type AnimatableValue<V> =
15
+ | V
16
+ | SequenceStep<V>
17
+ | ReadonlyArray<SequenceStep<V>>
18
+
19
+ /**
20
+ * Spring transition — public surface uses react-spring vocabulary
21
+ * (`tension` / `friction` / `mass`), not Reanimated's raw stiffness/damping.
22
+ */
23
+ export interface SpringTransition {
24
+ type?: 'spring'
25
+ tension?: number
26
+ friction?: number
27
+ mass?: number
28
+ velocity?: number
29
+ restSpeedThreshold?: number
30
+ restDisplacementThreshold?: number
31
+ delay?: number
32
+ repeat?: RepeatConfig
33
+ }
34
+
35
+ export interface TimingTransition {
36
+ type: 'timing'
37
+ duration?: number
38
+ easing?: (t: number) => number
39
+ delay?: number
40
+ repeat?: RepeatConfig
41
+ }
42
+
43
+ export interface DecayTransition {
44
+ type: 'decay'
45
+ velocity?: number
46
+ deceleration?: number
47
+ clamp?: [number, number]
48
+ delay?: number
49
+ }
50
+
51
+ export interface NoAnimationTransition {
52
+ type: 'no-animation'
53
+ }
54
+
55
+ export type TransitionConfig =
56
+ | SpringTransition
57
+ | TimingTransition
58
+ | DecayTransition
59
+ | NoAnimationTransition
60
+
61
+ /**
62
+ * Repeat config — one shape, not three flags. Default `alternate: true`.
63
+ */
64
+ export type RepeatConfig =
65
+ | number
66
+ | 'infinite'
67
+ | { count: number | 'infinite'; alternate?: boolean }
68
+
69
+ /**
70
+ * Per-property transition map. Keys must match keys present on `animate`.
71
+ * Top-level entries on `transition` apply to all properties unless overridden
72
+ * here.
73
+ */
74
+ export type PerPropertyTransition<S> = {
75
+ [K in keyof S]?: TransitionConfig
76
+ }
77
+
78
+ export type Transition<S> = TransitionConfig | PerPropertyTransition<S>
79
+
80
+ /**
81
+ * The animation state shape inferred from the underlying component's style
82
+ * prop. We narrow to the value side of `style` so consumers see ViewStyle on
83
+ * `Motion.View`, TextStyle on `Motion.Text`, etc. — no shared union.
84
+ */
85
+ export type AnimateStyle<C> = C extends { style?: StyleProp<infer S> }
86
+ ? { [K in keyof S]?: AnimatableValue<S[K]> }
87
+ : never
88
+
89
+ export interface AnimationCallbackInfo<S> {
90
+ /**
91
+ * The animatable key that just settled — typically a `keyof S` (e.g.
92
+ * `'opacity'`, `'translateX'`). The sentinel `'transform'` is emitted in
93
+ * lieu of any specific transform axis (`translateX`/`Y`, `scale`/`X`/`Y`,
94
+ * `rotate`) when the terminal `'animation'` phase fires for a transform
95
+ * group, so a multi-axis translate produces one callback rather than two.
96
+ */
97
+ key: keyof S | 'transform'
98
+ finished: boolean
99
+ value: unknown
100
+ target: unknown
101
+ phase: 'step' | 'sequence' | 'repeat' | 'animation'
102
+ step: number | undefined
103
+ iteration: number
104
+ }
105
+
106
+ /**
107
+ * A variants map: string state names → animate target objects.
108
+ */
109
+ export type VariantsMap<C> = Record<string, AnimateStyle<C>>
110
+
111
+ /**
112
+ * Gesture sub-states accepted by the `gesture` prop on every Motion primitive.
113
+ *
114
+ * - `pressed` — active while the user is touching the component (touch start
115
+ * to touch end / cancel).
116
+ * - `focused` — active while a focusable component owns keyboard focus
117
+ * (no-op for non-focusable underlying components).
118
+ * - `hovered` — web-only. Typed for cross-platform call sites; the runtime is
119
+ * a no-op on native.
120
+ *
121
+ * When a sub-state is active, its values override the base `animate` target
122
+ * per-property. Priority on overlap: `pressed` > `focused` > `hovered`.
123
+ */
124
+ export interface GestureSubStates<C> {
125
+ pressed?: AnimateStyle<C>
126
+ focused?: AnimateStyle<C>
127
+ hovered?: AnimateStyle<C>
128
+ }
129
+
130
+ /**
131
+ * Controller returned by `useVariants`. The `current` shared state is read
132
+ * via `controller` prop on a Motion primitive; `transitionTo` drives the
133
+ * controller from JS code (event handlers, async chains, etc.).
134
+ */
135
+ export interface VariantController<K extends string = string> {
136
+ current: K
137
+ // Method-shorthand on purpose: TS treats parameters as bivariant so a
138
+ // `VariantController<'open' | 'closed'>` is assignable to the wider
139
+ // `VariantController<string>` that the `controller` prop is typed against.
140
+ transitionTo(next: K): void
141
+ /** @internal — subscription used by Motion primitives to re-render. */
142
+ subscribe(listener: (next: K) => void): () => void
143
+ }
144
+
145
+ /**
146
+ * Props injected onto every Motion primitive.
147
+ */
148
+ export interface MotionProps<C> {
149
+ /**
150
+ * Initial values applied on mount. Read once on mount and intentionally
151
+ * non-reactive — to reset after a state change, change the component `key`,
152
+ * remount via `<Presence>`, or drive the value through a controller.
153
+ *
154
+ * Pass `false` to skip the initial-mount animation entirely.
155
+ */
156
+ initial?: AnimateStyle<C> | false
157
+ /**
158
+ * The animation target. A style object, a variant key (when `variants` is
159
+ * supplied), or an array of sequence steps. Variant keys autocomplete when
160
+ * `variants` is annotated `as const`.
161
+ */
162
+ animate?: AnimateStyle<C> | string
163
+ /**
164
+ * Values applied while the component exits via `<Presence>`.
165
+ */
166
+ exit?: AnimateStyle<C>
167
+ /**
168
+ * Named animation states. With `variants` set, `animate` accepts a key from
169
+ * this map.
170
+ */
171
+ variants?: VariantsMap<C>
172
+ /**
173
+ * Imperative controller from `useVariants(...)`. When supplied, `animate`
174
+ * is read from `controller.current` and re-applied whenever the controller
175
+ * transitions. `animate` and `controller` should not both be set.
176
+ */
177
+ controller?: VariantController
178
+ /**
179
+ * Gesture-driven sub-states (`pressed`, `focused`, `hovered`). When omitted,
180
+ * no handlers are mounted on the underlying component. Sub-state values
181
+ * merge over `animate` per-property while the corresponding gesture is
182
+ * active.
183
+ */
184
+ gesture?: GestureSubStates<C>
185
+ /**
186
+ * Per-property or top-level transition config. Per-property entries take
187
+ * precedence over the top-level transition.
188
+ */
189
+ transition?: Transition<AnimateStyle<C>>
190
+ /**
191
+ * Fired once per logical animation completion. See `AnimationCallbackInfo`
192
+ * for the payload shape — transform parents fire once, not per axis.
193
+ */
194
+ onAnimationEnd?: (info: AnimationCallbackInfo<AnimateStyle<C>>) => void
195
+ }
196
+
197
+ /**
198
+ * The component type produced by `createMotionComponent`. Combines the
199
+ * underlying component's props (minus `style`, which we replace with an
200
+ * animated style) with the Motion-specific props above.
201
+ */
202
+ export type MotionComponent<C extends ComponentType<any>> = ComponentType<
203
+ Omit<React.ComponentProps<C>, 'style'> &
204
+ MotionProps<React.ComponentProps<C>> & {
205
+ style?: React.ComponentProps<C>['style']
206
+ }
207
+ >
@@ -0,0 +1 @@
1
+ export { useVariants } from './useVariants'
@@ -0,0 +1,60 @@
1
+ import { useMemo, useRef } from 'react'
2
+ import { type VariantController } from '../types'
3
+
4
+ /**
5
+ * Build a controller for a variants map. The controller is the imperative
6
+ * escape hatch — pass it to a Motion primitive via `controller={...}` and
7
+ * call `controller.transitionTo('open')` from event handlers, async chains,
8
+ * etc. The hook name mirrors the prop name (`variants`) so the relationship
9
+ * is obvious.
10
+ *
11
+ * The controller is identity-stable across renders. State changes are
12
+ * delivered to subscribers via `subscribe` — Motion primitives subscribe
13
+ * internally and re-resolve `animate` on each transition.
14
+ */
15
+ export function useVariants<V extends Readonly<Record<string, object>>>(
16
+ variants: V,
17
+ initial?: keyof V & string,
18
+ ): VariantController<keyof V & string> {
19
+ // Pin the variants object reference for the lifetime of the controller.
20
+ // Consumers shouldn't recreate the map on every render anyway, but if they
21
+ // do, the controller still works against the first definition's keys.
22
+ const variantsRef = useRef(variants)
23
+
24
+ return useMemo(() => {
25
+ const listeners = new Set<(next: keyof V & string) => void>()
26
+ let current =
27
+ initial ??
28
+ ((Object.keys(variantsRef.current)[0] ?? '') as keyof V & string)
29
+
30
+ const controller: VariantController<keyof V & string> = {
31
+ get current() {
32
+ return current
33
+ },
34
+ transitionTo(next) {
35
+ if (next === current) return
36
+ if (!(next in variantsRef.current)) {
37
+ if (__DEV__) {
38
+ console.warn(
39
+ `[inertia] useVariants: unknown variant "${String(next)}". Known keys: ${Object.keys(variantsRef.current).join(', ')}`,
40
+ )
41
+ }
42
+ return
43
+ }
44
+ current = next
45
+ for (const fn of listeners) fn(next)
46
+ },
47
+ subscribe(listener) {
48
+ listeners.add(listener)
49
+ return () => {
50
+ listeners.delete(listener)
51
+ }
52
+ },
53
+ }
54
+ return controller
55
+ // Identity-stable controller — only build once.
56
+ // eslint-disable-next-line react-hooks/exhaustive-deps
57
+ }, [])
58
+ }
59
+
60
+ declare const __DEV__: boolean