0
# React Components
1
2
React integration providing motion components, hooks, and utilities for creating animated user interfaces with declarative syntax and lifecycle management.
3
4
## Capabilities
5
6
### Motion Components
7
8
React components that can be animated using motion props. Available for all HTML and SVG elements.
9
10
```typescript { .api }
11
/**
12
* Motion component namespace providing animated versions of all HTML and SVG elements
13
*/
14
const motion: {
15
[K in keyof HTMLElementTagNameMap]: React.ForwardRefExoticComponent<
16
HTMLMotionProps<K>
17
>;
18
} & {
19
[K in keyof SVGElementTagNameMap]: React.ForwardRefExoticComponent<
20
SVGMotionProps<K>
21
>;
22
};
23
24
interface HTMLMotionProps<T extends keyof HTMLElementTagNameMap>
25
extends Omit<React.HTMLAttributes<HTMLElementTagNameMap[T]>, keyof MotionProps>,
26
MotionProps {}
27
28
interface SVGMotionProps<T extends keyof SVGElementTagNameMap>
29
extends Omit<React.SVGAttributes<SVGElementTagNameMap[T]>, keyof MotionProps>,
30
MotionProps {}
31
32
interface MotionProps {
33
/** Initial animation state */
34
initial?: Target | boolean | VariantLabels;
35
/** Animation to run on mount or when animate prop changes */
36
animate?: Target | VariantLabels | AnimationControls;
37
/** Animation to run on unmount */
38
exit?: Target | VariantLabels;
39
/** Transition configuration */
40
transition?: Transition;
41
/** Animation variants */
42
variants?: Variants;
43
/** Manual animation controls */
44
animate?: AnimationControls;
45
/** Whether component should animate on mount */
46
initial?: boolean | Target | VariantLabels;
47
/** Layout animation settings */
48
layout?: boolean | "position" | "size";
49
/** Layout ID for shared layout animations */
50
layoutId?: string;
51
/** Drag configuration */
52
drag?: boolean | "x" | "y";
53
/** Drag constraints */
54
dragConstraints?: Partial<Box> | React.RefObject<Element>;
55
/** Drag momentum settings */
56
dragMomentum?: boolean;
57
/** Drag elastic settings */
58
dragElastic?: boolean | number;
59
/** Whlie dragging animation */
60
whileDrag?: Target | VariantLabels;
61
/** While hovering animation */
62
whileHover?: Target | VariantLabels;
63
/** While tapping animation */
64
whileTap?: Target | VariantLabels;
65
/** While in view animation */
66
whileInView?: Target | VariantLabels;
67
}
68
69
type Target = {
70
[key: string]: string | number | MotionValue;
71
};
72
73
type VariantLabels = string | string[];
74
75
interface Variants {
76
[key: string]: Target | ((custom?: any, current?: Target) => Target);
77
}
78
```
79
80
**Usage Examples:**
81
82
```typescript
83
import { motion } from "motion/react";
84
85
// Basic animation
86
function AnimatedBox() {
87
return (
88
<motion.div
89
initial={{ opacity: 0, scale: 0.8 }}
90
animate={{ opacity: 1, scale: 1 }}
91
exit={{ opacity: 0, scale: 0.8 }}
92
transition={{ duration: 0.3 }}
93
>
94
Content
95
</motion.div>
96
);
97
}
98
99
// Hover and tap interactions
100
function InteractiveButton() {
101
return (
102
<motion.button
103
whileHover={{ scale: 1.05 }}
104
whileTap={{ scale: 0.95 }}
105
transition={{ type: "spring", stiffness: 300 }}
106
>
107
Click me
108
</motion.button>
109
);
110
}
111
112
// Drag interaction
113
function DraggableCard() {
114
return (
115
<motion.div
116
drag
117
dragConstraints={{ left: -100, right: 100, top: -100, bottom: 100 }}
118
dragElastic={0.1}
119
whileDrag={{ scale: 1.1 }}
120
>
121
Drag me around
122
</motion.div>
123
);
124
}
125
```
126
127
### Minimal Motion Components
128
129
Smaller bundle size alternative to motion components with essential animation features.
130
131
```typescript { .api }
132
/**
133
* Minimal motion component namespace for smaller bundle sizes
134
*/
135
const m: {
136
[K in keyof HTMLElementTagNameMap]: React.ForwardRefExoticComponent<
137
HTMLMotionProps<K>
138
>;
139
} & {
140
[K in keyof SVGElementTagNameMap]: React.ForwardRefExoticComponent<
141
SVGMotionProps<K>
142
>;
143
};
144
```
145
146
### AnimatePresence
147
148
Container component for animating components as they're added or removed from the React tree.
149
150
```typescript { .api }
151
/**
152
* Animate components entering and leaving the React tree
153
* @param props - AnimatePresence configuration
154
* @returns JSX element wrapping animated children
155
*/
156
function AnimatePresence(props: AnimatePresenceProps): JSX.Element;
157
158
interface AnimatePresenceProps {
159
/** Child components to animate */
160
children?: React.ReactNode;
161
/** Custom exit animations */
162
exitBeforeEnter?: boolean;
163
/** Whether to animate initial render */
164
initial?: boolean;
165
/** Callback when element finishes exiting */
166
onExitComplete?: () => void;
167
/** Animation mode */
168
mode?: "wait" | "sync" | "popLayout";
169
}
170
```
171
172
**Usage Examples:**
173
174
```typescript
175
import { AnimatePresence, motion } from "motion/react";
176
import { useState } from "react";
177
178
function ToggleExample() {
179
const [isVisible, setIsVisible] = useState(true);
180
181
return (
182
<div>
183
<button onClick={() => setIsVisible(!isVisible)}>
184
Toggle
185
</button>
186
<AnimatePresence>
187
{isVisible && (
188
<motion.div
189
initial={{ opacity: 0, height: 0 }}
190
animate={{ opacity: 1, height: "auto" }}
191
exit={{ opacity: 0, height: 0 }}
192
transition={{ duration: 0.3 }}
193
>
194
This content animates in and out
195
</motion.div>
196
)}
197
</AnimatePresence>
198
</div>
199
);
200
}
201
```
202
203
### MotionConfig
204
205
Global configuration component for setting default animation options across an app.
206
207
```typescript { .api }
208
/**
209
* Provide global motion configuration
210
* @param props - Configuration options
211
* @returns JSX element providing configuration context
212
*/
213
function MotionConfig(props: MotionConfigProps): JSX.Element;
214
215
interface MotionConfigProps {
216
/** Child components to apply configuration to */
217
children?: React.ReactNode;
218
/** Default transition for all animations */
219
transition?: Transition;
220
/** Whether to respect user's reduced motion preference */
221
reducedMotion?: "always" | "never" | "user";
222
/** Transform template for custom transforms */
223
transformTemplate?: (transform: TransformProperties, generated: string) => string;
224
/** Animation features to load */
225
features?: MotionFeature[];
226
}
227
```
228
229
### LazyMotion
230
231
Component for lazy loading animation features to reduce initial bundle size.
232
233
```typescript { .api }
234
/**
235
* Lazy load animation features
236
* @param props - Lazy loading configuration
237
* @returns JSX element providing lazy-loaded features
238
*/
239
function LazyMotion(props: LazyMotionProps): JSX.Element;
240
241
interface LazyMotionProps {
242
/** Child components */
243
children: React.ReactNode;
244
/** Animation features to load */
245
features: () => Promise<MotionFeature>;
246
/** Whether to load features strictly */
247
strict?: boolean;
248
}
249
250
// Pre-built feature sets
251
const domAnimation: () => Promise<MotionFeature>;
252
const domMax: () => Promise<MotionFeature>;
253
const domMin: () => Promise<MotionFeature>;
254
```
255
256
**Usage Examples:**
257
258
```typescript
259
import { LazyMotion, domAnimation, motion } from "motion/react";
260
261
function App() {
262
return (
263
<LazyMotion features={domAnimation}>
264
<motion.div animate={{ x: 100 }}>
265
Animations loaded lazily
266
</motion.div>
267
</LazyMotion>
268
);
269
}
270
```
271
272
## Animation Hooks
273
274
### useAnimate
275
276
Hook for imperative animations with a scoped animation function and element reference.
277
278
```typescript { .api }
279
/**
280
* Hook for imperative animations
281
* @returns Tuple of animation scope ref and animate function
282
*/
283
function useAnimate<T extends Element = any>(): [
284
React.RefObject<T>,
285
(
286
target: string,
287
keyframes: Keyframes,
288
options?: AnimationOptions
289
) => AnimationControls
290
];
291
292
type AnimationScope<T = any> = React.RefObject<T>;
293
type AnimateFunction = (
294
target: string,
295
keyframes: Keyframes,
296
options?: AnimationOptions
297
) => AnimationControls;
298
```
299
300
**Usage Examples:**
301
302
```typescript
303
import { useAnimate } from "motion/react";
304
305
function AnimatedComponent() {
306
const [scope, animate] = useAnimate();
307
308
const handleClick = async () => {
309
await animate(".title", { y: -10 }, { duration: 0.1 });
310
await animate(".title", { y: 0 }, { duration: 0.1 });
311
animate(".content", { opacity: 1, y: 0 }, { duration: 0.3 });
312
};
313
314
return (
315
<div ref={scope}>
316
<h2 className="title">Title</h2>
317
<p className="content" style={{ opacity: 0, transform: "translateY(20px)" }}>
318
Content
319
</p>
320
<button onClick={handleClick}>Animate</button>
321
</div>
322
);
323
}
324
```
325
326
### useAnimationControls
327
328
Hook for creating animation control objects for manual animation management.
329
330
```typescript { .api }
331
/**
332
* Create animation controls for manual animation management
333
* @returns Animation controls object
334
*/
335
function useAnimationControls(): AnimationControls;
336
337
interface AnimationControls {
338
/** Start animation with target values */
339
start(definition: Target | VariantLabels): Promise<void>;
340
/** Stop all animations */
341
stop(): void;
342
/** Set values immediately without animation */
343
set(definition: Target): void;
344
/** Mount controls (internal) */
345
mount(): void;
346
/** Unmount controls (internal) */
347
unmount(): void;
348
}
349
```
350
351
**Usage Examples:**
352
353
```typescript
354
import { motion, useAnimationControls } from "motion/react";
355
356
function ControlledAnimation() {
357
const controls = useAnimationControls();
358
359
const startAnimation = () => {
360
controls.start({
361
x: 100,
362
transition: { duration: 1 }
363
});
364
};
365
366
return (
367
<div>
368
<motion.div animate={controls} />
369
<button onClick={startAnimation}>Start</button>
370
<button onClick={() => controls.stop()}>Stop</button>
371
</div>
372
);
373
}
374
```
375
376
### useMotionValue
377
378
Hook for creating and managing animated values that can be shared between components.
379
380
```typescript { .api }
381
/**
382
* Create a motion value
383
* @param initial - Initial value
384
* @returns MotionValue instance
385
*/
386
function useMotionValue<T>(initial: T): MotionValue<T>;
387
388
interface MotionValue<T> {
389
/** Get current value */
390
get(): T;
391
/** Set value */
392
set(v: T): void;
393
/** Subscribe to value changes */
394
on(eventName: "change", callback: (latest: T) => void): () => void;
395
/** Destroy motion value */
396
destroy(): void;
397
/** Stop all animations on this value */
398
stop(): void;
399
/** Check if value is currently animating */
400
isAnimating(): boolean;
401
}
402
```
403
404
### useTransform
405
406
Hook for creating derived motion values that transform input values to output values.
407
408
```typescript { .api }
409
/**
410
* Transform a motion value through an input/output range
411
* @param value - Source motion value
412
* @param inputRange - Array of input values
413
* @param outputRange - Array of corresponding output values
414
* @param options - Transform options
415
* @returns Transformed motion value
416
*/
417
function useTransform<T>(
418
value: MotionValue<number>,
419
inputRange: number[],
420
outputRange: T[],
421
options?: TransformOptions<T>
422
): MotionValue<T>;
423
424
/**
425
* Transform a motion value using a function
426
* @param value - Source motion value or array of values
427
* @param transformer - Transform function
428
* @returns Transformed motion value
429
*/
430
function useTransform<I, O>(
431
value: MotionValue<I> | MotionValue<I>[],
432
transformer: (value: I) => O
433
): MotionValue<O>;
434
435
interface TransformOptions<T> {
436
/** Clamp output to range */
437
clamp?: boolean;
438
/** Easing function */
439
ease?: Easing | Easing[];
440
}
441
```
442
443
**Usage Examples:**
444
445
```typescript
446
import { motion, useMotionValue, useTransform } from "motion/react";
447
448
function TransformExample() {
449
const x = useMotionValue(0);
450
const opacity = useTransform(x, [-100, 0, 100], [0, 1, 0]);
451
const scale = useTransform(x, [-100, 0, 100], [0.5, 1, 0.5]);
452
453
return (
454
<motion.div
455
drag="x"
456
dragConstraints={{ left: -100, right: 100 }}
457
style={{ x, opacity, scale }}
458
>
459
Drag me horizontally
460
</motion.div>
461
);
462
}
463
```
464
465
### useSpring
466
467
Hook for creating spring-animated motion values.
468
469
```typescript { .api }
470
/**
471
* Create a spring-animated motion value
472
* @param value - Source motion value or initial value
473
* @param config - Spring configuration
474
* @returns Spring-animated motion value
475
*/
476
function useSpring(
477
value: MotionValue<number> | number,
478
config?: SpringOptions
479
): MotionValue<number>;
480
481
interface SpringOptions {
482
stiffness?: number;
483
damping?: number;
484
mass?: number;
485
bounce?: number;
486
}
487
```
488
489
### useScroll
490
491
Hook for creating scroll-based motion values.
492
493
```typescript { .api }
494
/**
495
* Track scroll position and progress
496
* @param options - Scroll tracking options
497
* @returns Object containing scroll motion values
498
*/
499
function useScroll(options?: UseScrollOptions): ScrollMotionValues;
500
501
interface UseScrollOptions {
502
/** Target element to track (defaults to window) */
503
target?: React.RefObject<Element>;
504
/** Offset boundaries for progress calculation */
505
offset?: Array<string | number>;
506
/** Layout effect timing */
507
layoutEffect?: boolean;
508
}
509
510
interface ScrollMotionValues {
511
/** Horizontal scroll position */
512
scrollX: MotionValue<number>;
513
/** Vertical scroll position */
514
scrollY: MotionValue<number>;
515
/** Horizontal scroll progress (0-1) */
516
scrollXProgress: MotionValue<number>;
517
/** Vertical scroll progress (0-1) */
518
scrollYProgress: MotionValue<number>;
519
}
520
```
521
522
### useVelocity
523
524
Hook for tracking the velocity of a motion value.
525
526
```typescript { .api }
527
/**
528
* Track velocity of a motion value
529
* @param value - Motion value to track
530
* @returns Motion value containing velocity
531
*/
532
function useVelocity(value: MotionValue<number>): MotionValue<number>;
533
```
534
535
### useInView
536
537
Hook for detecting when an element is in the viewport.
538
539
```typescript { .api }
540
/**
541
* Detect when element is in viewport
542
* @param options - Intersection observer options
543
* @returns Tuple of ref and isInView boolean
544
*/
545
function useInView(options?: UseInViewOptions): [React.RefObject<Element>, boolean];
546
547
interface UseInViewOptions {
548
/** Root element for intersection */
549
root?: React.RefObject<Element>;
550
/** Root margin */
551
margin?: string;
552
/** Intersection threshold */
553
amount?: "some" | "all" | number;
554
/** Run only once */
555
once?: boolean;
556
}
557
```
558
559
### Utility Hooks
560
561
Additional utility hooks for enhanced functionality.
562
563
```typescript { .api }
564
/**
565
* Cycle through an array of values
566
* @param items - Array of values to cycle through
567
* @returns Tuple of current value and cycle function
568
*/
569
function useCycle<T>(...items: T[]): [T, () => void];
570
571
/**
572
* Create motion template from template string
573
* @param template - Template string with motion value placeholders
574
* @param values - Motion values to substitute
575
* @returns Motion value containing template result
576
*/
577
function useMotionTemplate(
578
template: TemplateStringsArray,
579
...values: MotionValue[]
580
): MotionValue<string>;
581
582
/**
583
* Create time-based motion value
584
* @returns Motion value that updates with current time
585
*/
586
function useTime(): MotionValue<number>;
587
588
/**
589
* Optimize will-change CSS property
590
* @returns Ref to attach to element
591
*/
592
function useWillChange(): React.RefObject<Element>;
593
594
/**
595
* Check user's reduced motion preference
596
* @returns Boolean indicating if user prefers reduced motion
597
*/
598
function useReducedMotion(): boolean | null;
599
600
/**
601
* Hook for presence detection in AnimatePresence
602
* @returns Tuple of presence state and safe removal callback
603
*/
604
function usePresence(): [boolean, () => void | undefined];
605
606
/**
607
* Check if component is currently present
608
* @returns Boolean indicating current presence state
609
*/
610
function useIsPresent(): boolean;
611
612
/**
613
* Hook for DOM event handling with cleanup
614
* @param ref - Element ref to attach event to
615
* @param eventName - Name of DOM event
616
* @param handler - Event handler function
617
* @param options - Event listener options
618
*/
619
function useDomEvent(
620
ref: React.RefObject<Element>,
621
eventName: string,
622
handler: (event: Event) => void,
623
options?: AddEventListenerOptions
624
): void;
625
```
626
627
### React Contexts
628
629
React contexts for advanced motion configuration and state management.
630
631
```typescript { .api }
632
/**
633
* Core motion context for component coordination
634
*/
635
const MotionContext: React.Context<MotionContextValue>;
636
637
/**
638
* Global motion configuration context
639
*/
640
const MotionConfigContext: React.Context<MotionConfigContextValue>;
641
642
/**
643
* Layout group context for coordinating layout animations
644
*/
645
const LayoutGroupContext: React.Context<LayoutGroupContextValue>;
646
647
/**
648
* Presence context for AnimatePresence state
649
*/
650
const PresenceContext: React.Context<PresenceContextValue>;
651
652
/**
653
* Layout group switching context
654
*/
655
const SwitchLayoutGroupContext: React.Context<SwitchLayoutGroupContextValue>;
656
657
interface MotionContextValue {
658
/** Transform template function */
659
transformTemplate?: (transform: TransformProperties, generated: string) => string;
660
/** Reduced motion setting */
661
reducedMotion?: "always" | "never" | "user";
662
}
663
664
interface MotionConfigContextValue {
665
/** Global transition settings */
666
transition?: Transition;
667
/** Transform template */
668
transformTemplate?: (transform: TransformProperties, generated: string) => string;
669
/** Reduced motion preference */
670
reducedMotion?: "always" | "never" | "user";
671
}
672
673
interface LayoutGroupContextValue {
674
/** Layout group ID */
675
id?: string;
676
/** Group inheritance */
677
inherit?: boolean;
678
}
679
680
interface PresenceContextValue {
681
/** Whether component is present */
682
isPresent: boolean;
683
/** Safe to remove callback */
684
safeToRemove?: () => void;
685
/** Custom exit animation */
686
custom?: any;
687
}
688
689
interface SwitchLayoutGroupContextValue {
690
/** Switch layout group */
691
switchLayoutGroup: () => void;
692
}
693
```