@octane-xplat/motion 0.9.0 → 0.11.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/README.md +31 -2
- package/UPSTREAM.md +284 -16
- package/dist/native/index.js +980 -112
- package/dist/native/octane-client-build.json +1 -1
- package/dist/web/index.js +1104 -166
- package/dist/web/octane-client-build.json +1 -1
- package/package.json +8 -3
- package/src/clock.ts +13 -1
- package/src/components.mobile.test.tsrx +58 -0
- package/src/components.tsrx +185 -39
- package/src/components.web.test.tsrx +234 -1
- package/src/controller.ts +122 -10
- package/src/delegation.test.ts +269 -0
- package/src/delegation.ts +29 -0
- package/src/delegation.web.test.ts +270 -0
- package/src/drag.mobile.test.ts +81 -0
- package/src/drag.test.ts +167 -0
- package/src/drag.ts +157 -0
- package/src/driver.ts +249 -0
- package/src/driver.web.ts +180 -0
- package/src/engine.test.ts +86 -0
- package/src/engine.ts +137 -15
- package/src/hooks.tsrx +53 -2
- package/src/host-types.ts +44 -1
- package/src/host.ts +39 -2
- package/src/host.web.ts +51 -10
- package/src/index.ts +18 -4
- package/src/index.web.ts +18 -4
- package/src/pan.ts +92 -0
- package/src/pan.web.ts +116 -0
- package/src/presence.tsrx +6 -7
- package/src/reduced-motion.ts +23 -4
- package/src/types.ts +99 -10
- package/src/value.ts +15 -5
- package/src/variants.test.ts +197 -0
- package/src/variants.ts +226 -0
- package/types/engine.d.ts +7 -1
- package/types/index.d.ts +22 -1
- package/types/types.d.ts +93 -10
- package/types/value.d.ts +4 -1
package/src/variants.ts
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { validateTarget } from './controller'
|
|
2
|
+
import { isOrchestrated, validateTransitionInput } from './engine'
|
|
3
|
+
import type { AnimationResult } from './engine'
|
|
4
|
+
import type {
|
|
5
|
+
AnimationDefinition,
|
|
6
|
+
MotionKey,
|
|
7
|
+
Target,
|
|
8
|
+
TransitionInput,
|
|
9
|
+
Variants,
|
|
10
|
+
VariantLabels,
|
|
11
|
+
} from './types'
|
|
12
|
+
|
|
13
|
+
export function isLabels(value: unknown): value is VariantLabels {
|
|
14
|
+
return (
|
|
15
|
+
typeof value === 'string' ||
|
|
16
|
+
(Array.isArray(value) && value.every((label) => typeof label === 'string'))
|
|
17
|
+
)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function resolveVariant(
|
|
21
|
+
definition: AnimationDefinition | false | undefined,
|
|
22
|
+
variants?: Variants,
|
|
23
|
+
custom?: any,
|
|
24
|
+
) {
|
|
25
|
+
const target: Target = {}
|
|
26
|
+
let transition: TransitionInput | undefined
|
|
27
|
+
if (definition === undefined || definition === false) {
|
|
28
|
+
return { target, transition }
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const entries = isLabels(definition)
|
|
32
|
+
? (typeof definition === 'string' ? [definition] : definition).map((label) =>
|
|
33
|
+
Object.hasOwn(variants ?? {}, label) ? variants![label] : undefined,
|
|
34
|
+
)
|
|
35
|
+
: [definition]
|
|
36
|
+
|
|
37
|
+
for (const entry of entries) {
|
|
38
|
+
const resolved = typeof entry === 'function' ? entry(custom) : entry
|
|
39
|
+
if (!resolved) {
|
|
40
|
+
continue
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const { transition: override, ...values } = resolved as Target & {
|
|
44
|
+
transition?: TransitionInput
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
validateTarget(values)
|
|
48
|
+
Object.assign(target, values)
|
|
49
|
+
if (override !== undefined) {
|
|
50
|
+
validateTransitionInput(override)
|
|
51
|
+
transition = override
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return { target, transition }
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Keep tree timing out of Controller and add inherited delay to every channel. */
|
|
59
|
+
export function playbackTransition(input: TransitionInput, delay = 0): TransitionInput {
|
|
60
|
+
if (isOrchestrated(input)) {
|
|
61
|
+
const {
|
|
62
|
+
staggerChildren: _staggerChildren,
|
|
63
|
+
delayChildren: _delayChildren,
|
|
64
|
+
when: _when,
|
|
65
|
+
...timing
|
|
66
|
+
} = input
|
|
67
|
+
|
|
68
|
+
const result: TransitionInput = {
|
|
69
|
+
default: { ...timing.default, delay: (timing.default?.delay ?? 0) + delay },
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
for (const [key, value] of Object.entries(timing)) {
|
|
73
|
+
if (key !== 'default' && value) {
|
|
74
|
+
result[key as MotionKey] = {
|
|
75
|
+
...value,
|
|
76
|
+
delay: (value.delay ?? timing.default?.delay ?? 0) + delay,
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return result
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const {
|
|
85
|
+
staggerChildren: _staggerChildren,
|
|
86
|
+
delayChildren: _delayChildren,
|
|
87
|
+
when: _when,
|
|
88
|
+
...timing
|
|
89
|
+
} = input
|
|
90
|
+
|
|
91
|
+
return { ...timing, delay: (timing.delay ?? 0) + delay }
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** Root-local tree of inherited runs. Generations prevent queued work after replacement/disposal. */
|
|
95
|
+
export class VariantNode {
|
|
96
|
+
readonly children = new Set<VariantNode>()
|
|
97
|
+
private generation = 0
|
|
98
|
+
private active?: {
|
|
99
|
+
definition: AnimationDefinition
|
|
100
|
+
finished: Promise<AnimationResult>
|
|
101
|
+
generation: number
|
|
102
|
+
}
|
|
103
|
+
initial?: VariantLabels | false
|
|
104
|
+
animate?: VariantLabels
|
|
105
|
+
resolve!: (definition: AnimationDefinition) => { target: Target; transition: TransitionInput }
|
|
106
|
+
play!: (
|
|
107
|
+
definition: AnimationDefinition,
|
|
108
|
+
target: Target,
|
|
109
|
+
transition: TransitionInput,
|
|
110
|
+
) => Promise<AnimationResult>
|
|
111
|
+
stopOwn!: () => void
|
|
112
|
+
|
|
113
|
+
register(child: VariantNode) {
|
|
114
|
+
this.children.add(child)
|
|
115
|
+
const active = this.active
|
|
116
|
+
if (active && isLabels(active.definition)) {
|
|
117
|
+
void active.finished.then((result) => {
|
|
118
|
+
if (
|
|
119
|
+
result !== 'finished' ||
|
|
120
|
+
active.generation !== this.generation ||
|
|
121
|
+
!this.children.has(child)
|
|
122
|
+
) {
|
|
123
|
+
return
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const { transition } = this.resolve(active.definition)
|
|
127
|
+
void child.run(
|
|
128
|
+
active.definition,
|
|
129
|
+
(transition.delayChildren ?? 0) +
|
|
130
|
+
[...this.children].indexOf(child) * (transition.staggerChildren ?? 0),
|
|
131
|
+
)
|
|
132
|
+
})
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return () => {
|
|
136
|
+
this.children.delete(child)
|
|
137
|
+
child.stop()
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/** Invalidate queued phases without stopping independently registered Presence exits. */
|
|
142
|
+
cancelPending() {
|
|
143
|
+
this.generation++
|
|
144
|
+
for (const child of this.children) {
|
|
145
|
+
child.cancelPending()
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
stop() {
|
|
150
|
+
this.generation++
|
|
151
|
+
this.stopOwn?.()
|
|
152
|
+
for (const child of this.children) {
|
|
153
|
+
child.stop()
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
run(definition: AnimationDefinition, delay = 0): Promise<AnimationResult> {
|
|
158
|
+
this.animate = isLabels(definition) ? definition : undefined
|
|
159
|
+
this.stop()
|
|
160
|
+
const generation = this.generation
|
|
161
|
+
const finished = this.runTree(definition, delay, generation)
|
|
162
|
+
this.active = { definition, finished, generation }
|
|
163
|
+
return finished
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
private async runTree(
|
|
167
|
+
definition: AnimationDefinition,
|
|
168
|
+
delay: number,
|
|
169
|
+
generation: number,
|
|
170
|
+
): Promise<AnimationResult> {
|
|
171
|
+
const { target, transition } = this.resolve(definition)
|
|
172
|
+
const participants = [...this.children]
|
|
173
|
+
const own = () =>
|
|
174
|
+
this.play(
|
|
175
|
+
definition,
|
|
176
|
+
target,
|
|
177
|
+
playbackTransition(
|
|
178
|
+
transition,
|
|
179
|
+
transition.when === 'afterChildren' && participants.length && isLabels(definition)
|
|
180
|
+
? 0
|
|
181
|
+
: delay,
|
|
182
|
+
),
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
const children = () =>
|
|
186
|
+
Promise.all(
|
|
187
|
+
isLabels(definition)
|
|
188
|
+
? participants
|
|
189
|
+
.filter((child) => this.children.has(child))
|
|
190
|
+
.map((child, index) =>
|
|
191
|
+
child.run(
|
|
192
|
+
definition,
|
|
193
|
+
(transition.when === 'beforeChildren' ? 0 : delay) +
|
|
194
|
+
(transition.delayChildren ?? 0) +
|
|
195
|
+
index * (transition.staggerChildren ?? 0),
|
|
196
|
+
),
|
|
197
|
+
)
|
|
198
|
+
: [],
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
let results: AnimationResult[]
|
|
202
|
+
if (transition.when === 'beforeChildren') {
|
|
203
|
+
const result = await own()
|
|
204
|
+
if (generation !== this.generation || result !== 'finished') {
|
|
205
|
+
return 'cancelled'
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
results = [result, ...(await children())]
|
|
209
|
+
} else if (transition.when === 'afterChildren') {
|
|
210
|
+
results = await children()
|
|
211
|
+
if (generation !== this.generation || results.some((result) => result !== 'finished')) {
|
|
212
|
+
return 'cancelled'
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
results.push(await own())
|
|
216
|
+
} else {
|
|
217
|
+
const parent = own()
|
|
218
|
+
const descendants = children()
|
|
219
|
+
results = [await parent, ...(await descendants)]
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return generation === this.generation && results.every((result) => result === 'finished')
|
|
223
|
+
? 'finished'
|
|
224
|
+
: 'cancelled'
|
|
225
|
+
}
|
|
226
|
+
}
|
package/types/engine.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Clock } from './clock-types.js';
|
|
2
|
-
import type { Transition } from './types.js';
|
|
2
|
+
import type { Transition, TransitionInput, TransitionOrchestration, MotionKey } from './types.js';
|
|
3
3
|
/** Terminal status; cancellation never masquerades as completion. */
|
|
4
4
|
export type AnimationResult = 'finished' | 'cancelled' | 'replaced';
|
|
5
5
|
/** A cancellable animation whose finished promise always settles. */
|
|
@@ -7,5 +7,11 @@ export interface AnimationControls {
|
|
|
7
7
|
finished: Promise<AnimationResult>;
|
|
8
8
|
stop(reason?: Exclude<AnimationResult, 'finished'>): void;
|
|
9
9
|
}
|
|
10
|
+
export declare function isBezierEase(ease: Transition['ease']): boolean;
|
|
11
|
+
/** CSS cubic-bezier control points for a delegatable ease; tuples pass through. */
|
|
12
|
+
export declare function bezierPoints(ease: Transition['ease']): [number, number, number, number];
|
|
13
|
+
export declare function isOrchestrated(t: TransitionInput | undefined): t is TransitionOrchestration;
|
|
14
|
+
export declare function resolveTransition(t: TransitionInput, key: MotionKey): Transition;
|
|
10
15
|
export declare function validateTransition(t: Transition): void;
|
|
16
|
+
export declare function validateTransitionInput(t: TransitionInput): void;
|
|
11
17
|
export declare function runAnimation(clock: Clock, from: number, to: number, transition: Transition, update: (value: number) => void, complete?: () => void): AnimationControls;
|
package/types/index.d.ts
CHANGED
|
@@ -1,18 +1,27 @@
|
|
|
1
1
|
import type { UniversalComponent } from 'octane/universal'
|
|
2
2
|
import type {
|
|
3
|
+
MotionProps,
|
|
3
4
|
MotionViewProps,
|
|
4
5
|
MotionRowProps,
|
|
5
6
|
MotionPressableProps,
|
|
6
7
|
MotionConfigProps,
|
|
8
|
+
Target,
|
|
7
9
|
Transition,
|
|
10
|
+
TransitionInput,
|
|
8
11
|
} from './types.js'
|
|
9
12
|
|
|
10
13
|
import type { MotionValue, MotionValueEvents } from './value.js'
|
|
11
|
-
|
|
14
|
+
import type { AnimationControls, AnimationResult } from './engine.js'
|
|
15
|
+
/** Bounded motion hosts for shared xplat UI primitives; `motion.create` wraps
|
|
16
|
+
* any component that accepts `ref`/`style`/`children`. All hosts support
|
|
17
|
+
* numeric variants and root-local initial/animate label inheritance. */
|
|
12
18
|
export declare const motion: {
|
|
13
19
|
View: UniversalComponent<MotionViewProps>
|
|
14
20
|
Row: UniversalComponent<MotionRowProps>
|
|
15
21
|
Pressable: UniversalComponent<MotionPressableProps>
|
|
22
|
+
create: <P extends Record<string, unknown>>(
|
|
23
|
+
component: (props: P) => any,
|
|
24
|
+
) => UniversalComponent<P & MotionProps>
|
|
16
25
|
}
|
|
17
26
|
|
|
18
27
|
/** Inherit transition and reduced-motion defaults within this root. */
|
|
@@ -52,8 +61,20 @@ export declare function useSpring(
|
|
|
52
61
|
options?: Omit<Transition, 'type' | 'duration' | 'ease' | 'delay'>,
|
|
53
62
|
): MotionValue
|
|
54
63
|
|
|
64
|
+
/** Scoped imperative animation: `const [scope, animate] = useAnimate()` then
|
|
65
|
+
* `ref={scope}` on a motion host. */
|
|
66
|
+
export declare function useAnimate(): [
|
|
67
|
+
{ current: any },
|
|
68
|
+
(
|
|
69
|
+
target: Target | MotionValue | object,
|
|
70
|
+
transitionOrTo?: TransitionInput | number,
|
|
71
|
+
transition?: Transition,
|
|
72
|
+
) => Promise<AnimationResult> | AnimationControls,
|
|
73
|
+
]
|
|
74
|
+
|
|
55
75
|
export type { MotionValue, MotionValueEvents }
|
|
56
76
|
export type { AnimationControls, AnimationResult } from './engine.js'
|
|
77
|
+
/** Includes bounded drag props and DragInfo callback payloads on both targets. */
|
|
57
78
|
export type * from './types.js'
|
|
58
79
|
|
|
59
80
|
/** Retain live children through exit; removing the boundary disposes immediately. */
|
package/types/types.d.ts
CHANGED
|
@@ -1,20 +1,36 @@
|
|
|
1
|
-
import type { View,
|
|
1
|
+
import type { View, HStack, Pressable } from '@octane-xplat/ui';
|
|
2
2
|
import type { MotionValue } from './value.js';
|
|
3
3
|
type ViewProps = Parameters<typeof View>[0];
|
|
4
|
-
type
|
|
4
|
+
type HStackProps = Parameters<typeof HStack>[0];
|
|
5
5
|
type PressableProps = Parameters<typeof Pressable>[0];
|
|
6
6
|
/** Supported channels. Translation is CSS pixels/DIP; rotation is degrees. */
|
|
7
7
|
export type MotionKey = 'opacity' | 'x' | 'y' | 'scale' | 'scaleX' | 'scaleY' | 'rotate';
|
|
8
8
|
/** Absolute numeric destinations; omitted channels retain their current values. */
|
|
9
9
|
export type Target = Partial<Record<MotionKey, number>>;
|
|
10
10
|
/** Tween easing, including a CSS-compatible cubic Bezier tuple. */
|
|
11
|
-
export type Ease = 'linear' | 'easeIn' | 'easeOut' | 'easeInOut' | [number, number, number, number];
|
|
11
|
+
export type Ease = 'linear' | 'easeIn' | 'easeOut' | 'easeInOut' | 'circIn' | 'circOut' | 'circInOut' | 'backIn' | 'backOut' | 'backInOut' | 'anticipate' | [number, number, number, number];
|
|
12
|
+
/** How repeated legs play: restart, alternate direction, or alternate
|
|
13
|
+
* direction with inverted easing (identical to reverse for two keyframes). */
|
|
14
|
+
export type RepeatType = 'loop' | 'reverse' | 'mirror';
|
|
15
|
+
/** Numeric tree timing in seconds, applied to inherited animate labels. */
|
|
16
|
+
export interface ChildOrchestration {
|
|
17
|
+
staggerChildren?: number;
|
|
18
|
+
delayChildren?: number;
|
|
19
|
+
when?: 'beforeChildren' | 'afterChildren';
|
|
20
|
+
}
|
|
12
21
|
/** Timing is seconds. Spring velocity is units per second. */
|
|
13
|
-
export interface Transition {
|
|
22
|
+
export interface Transition extends ChildOrchestration {
|
|
14
23
|
type?: 'tween' | 'spring';
|
|
24
|
+
/** Tween duration; on springs this is the visual duration (combine with bounce). */
|
|
15
25
|
duration?: number;
|
|
16
26
|
delay?: number;
|
|
17
27
|
ease?: Ease;
|
|
28
|
+
/** Additional iterations after the first leg; Infinity loops forever. */
|
|
29
|
+
repeat?: number;
|
|
30
|
+
repeatType?: RepeatType;
|
|
31
|
+
repeatDelay?: number;
|
|
32
|
+
/** Spring bounciness 0–1; pairs with duration instead of stiffness/damping. */
|
|
33
|
+
bounce?: number;
|
|
18
34
|
stiffness?: number;
|
|
19
35
|
damping?: number;
|
|
20
36
|
mass?: number;
|
|
@@ -22,27 +38,94 @@ export interface Transition {
|
|
|
22
38
|
restSpeed?: number;
|
|
23
39
|
restDelta?: number;
|
|
24
40
|
}
|
|
41
|
+
/** Per-channel transition overrides, upstream form: `{x: {…}, default: {…}}`. */
|
|
42
|
+
export type TransitionOrchestration = ChildOrchestration & {
|
|
43
|
+
default?: Transition;
|
|
44
|
+
} & Partial<Record<MotionKey, Transition>>;
|
|
45
|
+
/** A flat transition or per-channel overrides. */
|
|
46
|
+
export type TransitionInput = Transition | TransitionOrchestration;
|
|
47
|
+
/** Labels resolve against this host's variants, in array order. */
|
|
48
|
+
export type VariantLabels = string | string[];
|
|
49
|
+
/** An inline numeric target or labels resolved by the host. */
|
|
50
|
+
export type AnimationDefinition = Target | VariantLabels;
|
|
51
|
+
/** A numeric variant destination with an optional run transition override. */
|
|
52
|
+
export type VariantTarget = Target & {
|
|
53
|
+
transition?: TransitionInput;
|
|
54
|
+
};
|
|
55
|
+
/** Host-local definitions; pure resolvers receive this host's custom value. */
|
|
56
|
+
export type Variants = Record<string, VariantTarget | ((custom: any) => VariantTarget)>;
|
|
25
57
|
/** Static platform styles plus numeric motion-value bindings. */
|
|
26
58
|
export type MotionStyle = Record<string, unknown> & Partial<Record<MotionKey, number | MotionValue>>;
|
|
59
|
+
/** Translation limits in CSS pixels/DIP. Omitted edges are unbounded. */
|
|
60
|
+
export interface DragConstraints {
|
|
61
|
+
left?: number;
|
|
62
|
+
right?: number;
|
|
63
|
+
top?: number;
|
|
64
|
+
bottom?: number;
|
|
65
|
+
}
|
|
66
|
+
export interface DragInfo {
|
|
67
|
+
point: {
|
|
68
|
+
x: number;
|
|
69
|
+
y: number;
|
|
70
|
+
};
|
|
71
|
+
delta: {
|
|
72
|
+
x: number;
|
|
73
|
+
y: number;
|
|
74
|
+
};
|
|
75
|
+
offset: {
|
|
76
|
+
x: number;
|
|
77
|
+
y: number;
|
|
78
|
+
};
|
|
79
|
+
/** CSS pixels/DIP per second. */
|
|
80
|
+
velocity: {
|
|
81
|
+
x: number;
|
|
82
|
+
y: number;
|
|
83
|
+
};
|
|
84
|
+
cancelled: boolean;
|
|
85
|
+
}
|
|
86
|
+
export type DragCallback = (event: any, info: DragInfo) => void;
|
|
27
87
|
/** Supported declarative motion controls. */
|
|
28
88
|
export interface MotionProps {
|
|
29
|
-
|
|
89
|
+
drag?: boolean | 'x' | 'y';
|
|
90
|
+
/** Numeric translation bounds; measured ref constraints are deferred. */
|
|
91
|
+
dragConstraints?: DragConstraints;
|
|
92
|
+
/** Project release velocity into a spring destination (default true). */
|
|
93
|
+
dragMomentum?: boolean;
|
|
94
|
+
/** Resistance beyond bounds, 0–1 (default 0.35); false = 0, true = 0.35. */
|
|
95
|
+
dragElastic?: boolean | number;
|
|
96
|
+
onDragStart?: DragCallback;
|
|
97
|
+
onDrag?: DragCallback;
|
|
98
|
+
onDragEnd?: DragCallback;
|
|
99
|
+
/** Named numeric targets; array labels merge left to right. */
|
|
100
|
+
variants?: Variants;
|
|
101
|
+
/** Passed to this host's variant resolvers; not inherited. */
|
|
102
|
+
custom?: any;
|
|
103
|
+
initial?: AnimationDefinition | false;
|
|
30
104
|
/** Destination while the nearest Presence boundary retains this host for exit. */
|
|
31
|
-
exit?:
|
|
32
|
-
animate?:
|
|
33
|
-
transition?:
|
|
105
|
+
exit?: AnimationDefinition;
|
|
106
|
+
animate?: AnimationDefinition;
|
|
107
|
+
transition?: TransitionInput;
|
|
34
108
|
style?: MotionStyle;
|
|
109
|
+
/** Target while the pointer is down (web: pointerdown; native: touch down). */
|
|
110
|
+
whileTap?: AnimationDefinition;
|
|
111
|
+
whileTapTransition?: Transition;
|
|
112
|
+
/** Target while the host holds focus. */
|
|
113
|
+
whileFocus?: AnimationDefinition;
|
|
114
|
+
whileFocusTransition?: Transition;
|
|
115
|
+
onAnimationStart?: (definition: AnimationDefinition) => void;
|
|
35
116
|
onAnimationComplete?: () => void;
|
|
117
|
+
/** Per-frame snapshot while any channel animates. */
|
|
118
|
+
onUpdate?: (latest: Target) => void;
|
|
36
119
|
}
|
|
37
120
|
/** View layout and accessibility props with motion controls. */
|
|
38
121
|
export type MotionViewProps = Omit<ViewProps, 'style'> & MotionProps;
|
|
39
122
|
/** Row layout and accessibility props with motion controls. */
|
|
40
|
-
export type MotionRowProps = Omit<
|
|
123
|
+
export type MotionRowProps = Omit<HStackProps, 'style'> & MotionProps;
|
|
41
124
|
/** Pressable interaction props with motion controls. */
|
|
42
125
|
export type MotionPressableProps = Omit<PressableProps, 'style'> & MotionProps;
|
|
43
126
|
/** Inherited defaults; `user` observes the live system preference. */
|
|
44
127
|
export interface MotionConfigProps {
|
|
45
|
-
transition?:
|
|
128
|
+
transition?: TransitionInput;
|
|
46
129
|
reducedMotion?: 'always' | 'never' | 'user';
|
|
47
130
|
children?: any;
|
|
48
131
|
}
|
package/types/value.d.ts
CHANGED
|
@@ -37,8 +37,11 @@ export declare class MotionValue {
|
|
|
37
37
|
on<K extends keyof MotionValueEvents>(event: K, callback: MotionValueEvents[K]): () => void;
|
|
38
38
|
private emit;
|
|
39
39
|
private write;
|
|
40
|
+
/** Update position bookkeeping without emitting — platform-delegated runs
|
|
41
|
+
* track presentation state so interruption reads fresh value/velocity. */
|
|
42
|
+
track(value: number): void;
|
|
40
43
|
/** Animate to a destination. New playback replaces old playback. */
|
|
41
|
-
animate(target: number, transition?: Transition): AnimationControls;
|
|
44
|
+
animate(target: number, transition?: Transition, clampSample?: (value: number) => number): AnimationControls;
|
|
42
45
|
/** Stop playback at its current value. */
|
|
43
46
|
stop(reason?: 'cancelled' | 'replaced'): void;
|
|
44
47
|
/** Release playback and listeners when the owning component unmounts. */
|