or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

animated-components.mdanimation-hooks.mdimperative-control.mdindex.mdtransform-system.md

animation-hooks.mddocs/

0

# Animation Hooks

1

2

React hooks for declarative animation control including springs, transitions, trails, and utility hooks. These hooks provide the core animation functionality for @react-spring/web.

3

4

## Capabilities

5

6

### useSpring

7

8

Creates a single spring animation with configurable properties and easing.

9

10

```typescript { .api }

11

/**

12

* Creates a single spring animation

13

* @param props - Spring configuration and target values

14

* @returns Spring values for use in animated components

15

*/

16

function useSpring<Props extends object>(

17

props: UseSpringProps<Props>

18

): SpringValues<PickAnimated<Props>>;

19

20

/**

21

* Creates a spring with function-based props and dependencies

22

* @param props - Function returning spring configuration

23

* @param deps - Dependency array for recalculation

24

* @returns Tuple of spring values and spring ref

25

*/

26

function useSpring<Props extends object>(

27

props: () => UseSpringProps<Props>,

28

deps?: readonly any[]

29

): [SpringValues<PickAnimated<Props>>, SpringRef<PickAnimated<Props>>];

30

31

interface UseSpringProps<Props extends object = any> extends ControllerUpdate<PickAnimated<Props>> {

32

/** Reference for imperative control */

33

ref?: SpringRef<PickAnimated<Props>>;

34

}

35

```

36

37

**Usage Examples:**

38

39

```typescript

40

import { useSpring, animated } from "@react-spring/web";

41

42

// Basic spring animation

43

function FadeIn() {

44

const styles = useSpring({

45

from: { opacity: 0 },

46

to: { opacity: 1 },

47

config: { duration: 1000 }

48

});

49

50

return <animated.div style={styles}>Content</animated.div>;

51

}

52

53

// Function-based with dependencies

54

function ConditionalSpring({ show }) {

55

const [styles, api] = useSpring(() => ({

56

opacity: show ? 1 : 0,

57

transform: show ? 'translateY(0px)' : 'translateY(-50px)'

58

}), [show]);

59

60

return <animated.div style={styles}>Conditional content</animated.div>;

61

}

62

```

63

64

### useSprings

65

66

Creates multiple spring animations with individual configurations.

67

68

```typescript { .api }

69

/**

70

* Creates multiple spring animations

71

* @param length - Number of springs to create

72

* @param props - Configuration for each spring

73

* @returns Array of spring values

74

*/

75

function useSprings<Props extends object>(

76

length: number,

77

props: UseSpringProps<Props>[] | ((index: number) => UseSpringProps<Props>)

78

): SpringValues<PickAnimated<Props>>[];

79

80

/**

81

* Creates multiple springs with function-based props and dependencies

82

* @param length - Number of springs to create

83

* @param props - Function returning spring configurations

84

* @param deps - Dependency array for recalculation

85

* @returns Tuple of spring values array and spring ref

86

*/

87

function useSprings<Props extends object>(

88

length: number,

89

props: () => UseSpringProps<Props>[] | ((index: number) => UseSpringProps<Props>),

90

deps?: readonly any[]

91

): [SpringValues<PickAnimated<Props>>[], SpringRef<PickAnimated<Props>>];

92

```

93

94

**Usage Examples:**

95

96

```typescript

97

// Multiple springs with different configs

98

function MultipleBoxes({ items }) {

99

const springs = useSprings(items.length, items.map((item, index) => ({

100

from: { opacity: 0, transform: 'translateX(-100px)' },

101

to: { opacity: 1, transform: 'translateX(0px)' },

102

delay: index * 100,

103

})));

104

105

return springs.map((styles, index) => (

106

<animated.div key={index} style={styles}>

107

{items[index]}

108

</animated.div>

109

));

110

}

111

```

112

113

### useTrail

114

115

Creates staggered spring animations that follow each other in sequence.

116

117

```typescript { .api }

118

/**

119

* Creates staggered spring animations

120

* @param length - Number of items in the trail

121

* @param props - Spring configuration applied to all items

122

* @returns Array of spring values with staggered timing

123

*/

124

function useTrail<Props extends object>(

125

length: number,

126

props: UseTrailProps<Props>

127

): SpringValues<PickAnimated<Props>>[];

128

129

/**

130

* Creates trail with function-based props and dependencies

131

* @param length - Number of items in the trail

132

* @param props - Function returning spring configuration

133

* @param deps - Dependency array for recalculation

134

* @returns Tuple of spring values array and spring ref

135

*/

136

function useTrail<Props extends object>(

137

length: number,

138

props: () => UseTrailProps<Props>,

139

deps?: readonly any[]

140

): [SpringValues<PickAnimated<Props>>[], SpringRef<PickAnimated<Props>>];

141

142

type UseTrailProps<Props extends object = any> = UseSpringProps<Props>;

143

```

144

145

**Usage Examples:**

146

147

```typescript

148

// Staggered list animation

149

function StaggeredList({ words }) {

150

const trails = useTrail(words.length, {

151

from: { opacity: 0, transform: 'translateY(20px)' },

152

to: { opacity: 1, transform: 'translateY(0px)' },

153

});

154

155

return trails.map((styles, index) => (

156

<animated.div key={index} style={styles}>

157

{words[index]}

158

</animated.div>

159

));

160

}

161

```

162

163

### useTransition

164

165

Animates list transitions with enter, update, and leave phases.

166

167

```typescript { .api }

168

/**

169

* Animates list transitions with enter/update/leave phases

170

* @param data - Array of items to transition

171

* @param props - Transition configuration

172

* @returns Transition function for rendering items

173

*/

174

function useTransition<Item, Props extends object>(

175

data: OneOrMore<Item>,

176

props: UseTransitionProps<Item, Props>

177

): TransitionFn<Item, PickAnimated<Props>>;

178

179

/**

180

* Creates transition with function-based props and dependencies

181

* @param data - Array of items to transition

182

* @param props - Function returning transition configuration

183

* @param deps - Dependency array for recalculation

184

* @returns Tuple of transition function and spring ref

185

*/

186

function useTransition<Item, Props extends object>(

187

data: OneOrMore<Item>,

188

props: () => UseTransitionProps<Item, Props>,

189

deps?: readonly any[]

190

): [TransitionFn<Item, PickAnimated<Props>>, SpringRef<PickAnimated<Props>>];

191

192

interface UseTransitionProps<Item, Props extends object = any> {

193

/** Animation when items enter */

194

from?: TransitionTo<Item, PickAnimated<Props>>;

195

/** Animation when items first appear or update */

196

enter?: TransitionTo<Item, PickAnimated<Props>>;

197

/** Animation when items update */

198

update?: TransitionTo<Item, PickAnimated<Props>>;

199

/** Animation when items leave */

200

leave?: TransitionTo<Item, PickAnimated<Props>>;

201

/** Key function for item identification */

202

keys?: ItemKeys<Item>;

203

/** Animation configuration */

204

config?: SpringConfig | ((item: Item, state: string) => SpringConfig);

205

/** Delay before animation starts */

206

delay?: number;

207

/** Animation trail delay between items */

208

trail?: number;

209

}

210

211

type TransitionFn<Item, State extends Lookup> = (

212

style: SpringValues<State>,

213

item: Item,

214

transition: TransitionState<Item>,

215

index: number

216

) => React.ReactElement;

217

```

218

219

**Usage Examples:**

220

221

```typescript

222

// List transitions

223

function TodoList({ todos }) {

224

const transitions = useTransition(todos, {

225

from: { opacity: 0, height: 0 },

226

enter: { opacity: 1, height: 'auto' },

227

leave: { opacity: 0, height: 0 },

228

keys: todo => todo.id,

229

});

230

231

return transitions((style, todo) => (

232

<animated.div style={style}>

233

{todo.text}

234

</animated.div>

235

));

236

}

237

238

// Modal transitions

239

function Modal({ show, children }) {

240

const transitions = useTransition(show, {

241

from: { opacity: 0, transform: 'scale(0.9)' },

242

enter: { opacity: 1, transform: 'scale(1)' },

243

leave: { opacity: 0, transform: 'scale(0.9)' },

244

});

245

246

return transitions((style, item) =>

247

item ? (

248

<animated.div style={style}>

249

{children}

250

</animated.div>

251

) : null

252

);

253

}

254

```

255

256

### useChain

257

258

Chains multiple spring animations to run in sequence.

259

260

```typescript { .api }

261

/**

262

* Chains multiple spring animations to run in sequence

263

* @param refs - Array of spring refs to chain

264

* @param timeSteps - Optional timing for each animation (0-1)

265

* @param timeFrame - Total duration for the entire chain

266

*/

267

function useChain(

268

refs: SpringRef[],

269

timeSteps?: number[],

270

timeFrame?: number

271

): void;

272

```

273

274

**Usage Examples:**

275

276

```typescript

277

function ChainedAnimation() {

278

const [open, setOpen] = useState(false);

279

280

const [fadeStyles, fadeApi] = useSpring(() => ({

281

opacity: open ? 1 : 0

282

}), []);

283

284

const [scaleStyles, scaleApi] = useSpring(() => ({

285

transform: open ? 'scale(1)' : 'scale(0)'

286

}), []);

287

288

// Chain fade first, then scale

289

useChain(open ? [fadeApi, scaleApi] : [scaleApi, fadeApi], [0, 0.5], 1000);

290

291

return (

292

<animated.div style={fadeStyles}>

293

<animated.div style={scaleStyles}>

294

Chained animation

295

</animated.div>

296

</animated.div>

297

);

298

}

299

```

300

301

### useSpringRef

302

303

Creates a reference for imperative control of spring animations.

304

305

```typescript { .api }

306

/**

307

* Creates a reference for imperative spring control

308

* @returns Spring reference for imperative API calls

309

*/

310

function useSpringRef<State extends Lookup = Lookup>(): SpringRef<State>;

311

```

312

313

### useSpringValue

314

315

Creates a single animated value that can be used independently.

316

317

```typescript { .api }

318

/**

319

* Creates a single animated value

320

* @param initialValue - Initial value for the spring

321

* @param props - Optional spring configuration

322

* @returns SpringValue instance

323

*/

324

function useSpringValue<T>(

325

initialValue: T,

326

props?: SpringUpdate<T>

327

): SpringValue<T>;

328

```

329

330

**Usage Examples:**

331

332

```typescript

333

function IndependentValue() {

334

const opacity = useSpringValue(0, { config: { tension: 300 } });

335

336

const handleClick = () => {

337

opacity.start(opacity.get() === 0 ? 1 : 0);

338

};

339

340

return (

341

<animated.div

342

style={{ opacity }}

343

onClick={handleClick}

344

>

345

Click to toggle

346

</animated.div>

347

);

348

}

349

```

350

351

### Utility Hooks

352

353

Additional hooks for specific use cases.

354

355

```typescript { .api }

356

/**

357

* Creates scroll-based animations

358

* @param props - Scroll animation configuration

359

* @returns Spring values responding to scroll events

360

*/

361

function useScroll(props?: UseScrollProps): SpringValues<ScrollData>;

362

363

/**

364

* Creates resize-based animations

365

* @param props - Resize animation configuration

366

* @returns Spring values responding to resize events

367

*/

368

function useResize(props?: UseResizeProps): SpringValues<ResizeData>;

369

370

/**

371

* Creates intersection observer-based animations

372

* @param props - InView animation configuration

373

* @returns Tuple of spring values and ref to observe

374

*/

375

function useInView(props?: UseInViewProps): [SpringValues<InViewData>, React.RefObject<Element>];

376

```

377

378

## Declarative Components

379

380

React components providing declarative alternatives to animation hooks.

381

382

### Spring Component

383

384

Declarative component for single spring animations using render props pattern.

385

386

```typescript { .api }

387

/**

388

* Declarative spring animation component

389

* @param props - Spring configuration with children render prop

390

* @returns JSX element from children function

391

*/

392

function Spring<State extends object>(

393

props: SpringComponentProps<State>

394

): JSX.Element | null;

395

396

interface SpringComponentProps<State extends object> extends UseSpringProps<State> {

397

/** Render prop function receiving spring values */

398

children: (values: SpringValues<State>) => React.JSX.Element | null;

399

}

400

```

401

402

**Usage Examples:**

403

404

```typescript

405

import { Spring } from "@react-spring/web";

406

407

function DeclarativeSpring() {

408

return (

409

<Spring

410

from={{ opacity: 0 }}

411

to={{ opacity: 1 }}

412

config={{ duration: 1000 }}

413

>

414

{styles => <div style={styles}>Animated content</div>}

415

</Spring>

416

);

417

}

418

```

419

420

### Trail Component

421

422

Declarative component for staggered trail animations using render props pattern.

423

424

```typescript { .api }

425

/**

426

* Declarative trail animation component

427

* @param props - Trail configuration with children render prop

428

* @returns JSX element from children function

429

*/

430

function Trail<State extends object>(

431

props: TrailComponentProps<State>

432

): JSX.Element | null;

433

434

interface TrailComponentProps<State extends object> extends UseTrailProps<State> {

435

/** Number of items in the trail */

436

length: number;

437

/** Render prop function receiving array of spring values */

438

children: (values: SpringValues<State>[]) => React.JSX.Element | null;

439

}

440

```

441

442

**Usage Examples:**

443

444

```typescript

445

import { Trail } from "@react-spring/web";

446

447

function DeclarativeTrail({ items }) {

448

return (

449

<Trail

450

length={items.length}

451

from={{ opacity: 0, transform: 'translateY(20px)' }}

452

to={{ opacity: 1, transform: 'translateY(0px)' }}

453

>

454

{trails => (

455

<div>

456

{trails.map((style, index) => (

457

<div key={index} style={style}>

458

{items[index]}

459

</div>

460

))}

461

</div>

462

)}

463

</Trail>

464

);

465

}

466

```

467

468

### Transition Component

469

470

Declarative component for list transitions using render props pattern.

471

472

```typescript { .api }

473

/**

474

* Declarative transition animation component

475

* @param props - Transition configuration with children render prop

476

* @returns JSX element from children function

477

*/

478

function Transition<Item, State extends object>(

479

props: TransitionComponentProps<Item, State>

480

): JSX.Element | null;

481

482

interface TransitionComponentProps<Item, State extends object> extends UseTransitionProps<Item, State> {

483

/** Array of items to transition */

484

items: OneOrMore<Item>;

485

/** Render prop function receiving transition function */

486

children: (transitionFn: TransitionFn<Item, State>) => React.JSX.Element | null;

487

}

488

```

489

490

**Usage Examples:**

491

492

```typescript

493

import { Transition } from "@react-spring/web";

494

495

function DeclarativeTransition({ todos }) {

496

return (

497

<Transition

498

items={todos}

499

from={{ opacity: 0, height: 0 }}

500

enter={{ opacity: 1, height: 'auto' }}

501

leave={{ opacity: 0, height: 0 }}

502

keys={todo => todo.id}

503

>

504

{transitions => (

505

<div>

506

{transitions((style, todo) => (

507

<div style={style}>{todo.text}</div>

508

))}

509

</div>

510

)}

511

</Transition>

512

);

513

}

514

```

515

516

### useScroll

517

518

Creates scroll-linked animations that respond to window or element scroll position.

519

520

```typescript { .api }

521

/**

522

* Creates scroll-linked animations

523

* @param options - Configuration including optional container ref

524

* @returns Spring values with scroll progress and position

525

*/

526

function useScroll(

527

options?: UseScrollOptions

528

): SpringValues<{

529

scrollX: number;

530

scrollY: number;

531

scrollXProgress: number;

532

scrollYProgress: number;

533

}>;

534

535

interface UseScrollOptions extends Omit<SpringProps, 'to' | 'from'> {

536

/** Container element to observe (defaults to window) */

537

container?: MutableRefObject<HTMLElement>;

538

}

539

```

540

541

**Usage Examples:**

542

543

```typescript

544

import { useScroll, animated } from "@react-spring/web";

545

546

// Window scroll progress

547

function ScrollIndicator() {

548

const { scrollYProgress } = useScroll();

549

550

return (

551

<animated.div

552

style={{

553

transform: scrollYProgress.to(y => `scaleX(${y})`)

554

}}

555

/>

556

);

557

}

558

559

// Element scroll tracking

560

function ScrollContainer() {

561

const containerRef = useRef<HTMLDivElement>(null);

562

const { scrollY } = useScroll({ container: containerRef });

563

564

return (

565

<div ref={containerRef} style={{ height: 300, overflow: 'auto' }}>

566

<animated.div style={{ transform: scrollY.to(y => `translateY(${y}px)`) }}>

567

Scroll content

568

</animated.div>

569

</div>

570

);

571

}

572

```

573

574

### useResize

575

576

Creates animations based on element or window resize events.

577

578

```typescript { .api }

579

/**

580

* Creates resize-responsive animations

581

* @param options - Configuration including optional container ref

582

* @returns Spring values with width and height

583

*/

584

function useResize(

585

options?: UseResizeOptions

586

): SpringValues<{

587

width: number;

588

height: number;

589

}>;

590

591

interface UseResizeOptions extends Omit<SpringProps, 'to' | 'from'> {

592

/** Container element to observe (defaults to window) */

593

container?: MutableRefObject<HTMLElement | null | undefined>;

594

}

595

```

596

597

**Usage Examples:**

598

599

```typescript

600

import { useResize, animated } from "@react-spring/web";

601

602

// Window resize responsive

603

function ResponsiveBox() {

604

const { width, height } = useResize();

605

606

return (

607

<animated.div

608

style={{

609

width: width.to(w => w * 0.8),

610

height: height.to(h => h * 0.6)

611

}}

612

/>

613

);

614

}

615

616

// Element resize tracking

617

function ResizableContainer() {

618

const containerRef = useRef<HTMLDivElement>(null);

619

const { width } = useResize({ container: containerRef });

620

621

return (

622

<div ref={containerRef}>

623

<animated.div style={{ fontSize: width.to(w => w / 20) }}>

624

Scalable text

625

</animated.div>

626

</div>

627

);

628

}

629

```

630

631

### useInView

632

633

Creates animations triggered by element intersection with viewport.

634

635

```typescript { .api }

636

/**

637

* Creates intersection observer animations

638

* @param args - Intersection observer configuration

639

* @returns Tuple of element ref and boolean in-view state

640

*/

641

function useInView(args?: IntersectionArgs): [RefObject<any>, boolean];

642

643

/**

644

* Creates intersection observer animations with spring values

645

* @param props - Function returning spring configuration

646

* @param args - Intersection observer configuration

647

* @returns Tuple of element ref and spring values

648

*/

649

function useInView<Props extends object>(

650

props: () => Props & Valid<Props, UseSpringProps<Props>>,

651

args?: IntersectionArgs

652

): [RefObject<any>, SpringValues<PickAnimated<Props>>];

653

654

interface IntersectionArgs extends Omit<IntersectionObserverInit, 'root' | 'threshold'> {

655

/** Root element for intersection (defaults to viewport) */

656

root?: React.MutableRefObject<HTMLElement>;

657

/** Trigger animation only once */

658

once?: boolean;

659

/** Intersection amount trigger: 'any', 'all', number, or array */

660

amount?: 'any' | 'all' | number | number[];

661

}

662

```

663

664

**Usage Examples:**

665

666

```typescript

667

import { useInView, animated } from "@react-spring/web";

668

669

// Basic visibility detection

670

function FadeInOnScroll() {

671

const [ref, inView] = useInView();

672

673

return (

674

<div ref={ref}>

675

{inView ? 'Visible!' : 'Not visible'}

676

</div>

677

);

678

}

679

680

// Animated entrance on scroll

681

function AnimatedOnScroll() {

682

const [ref, springs] = useInView(

683

() => ({

684

from: { opacity: 0, y: 50 },

685

to: { opacity: 1, y: 0 },

686

}),

687

{ once: true }

688

);

689

690

return (

691

<animated.div ref={ref} style={springs}>

692

Fade in when scrolled into view

693

</animated.div>

694

);

695

}

696

697

// Custom intersection threshold

698

function PartiallyVisible() {

699

const [ref, springs] = useInView(

700

() => ({

701

from: { scale: 0.8 },

702

to: { scale: 1 },

703

}),

704

{ amount: 0.5 } // Trigger when 50% visible

705

);

706

707

return (

708

<animated.div ref={ref} style={springs}>

709

Scales when half visible

710

</animated.div>

711

);

712

}

713

```

714

715

## Common Spring Configuration

716

717

```typescript { .api }

718

interface SpringConfig {

719

/** Animation duration in milliseconds */

720

duration?: number;

721

/** Spring tension (stiffness) */

722

tension?: number;

723

/** Spring friction (damping) */

724

friction?: number;

725

/** Mass of the spring */

726

mass?: number;

727

/** Precision threshold for stopping */

728

precision?: number;

729

/** Velocity threshold for stopping */

730

velocity?: number;

731

/** Animation easing function */

732

easing?: EasingFunction;

733

/** Clamp values to prevent overshoot */

734

clamp?: boolean;

735

}

736

```