Each letter sits in its own tile and flips through the wheel until the word settles. Set length on the component to lock how many tiles show. Spaces render as blank tiles, so the board width stays put.
45ms
55ms
tsx
"use client"import { useState } from "react"import { SplitFlap } from "@/components/motion/split-flap"import { Button } from "@/components/ui/button"const TEXTS = [ "DEPARTURE", "GATE A12", "ON TIME", "BOARDING"]export function Example() { const [index, setIndex] = useState(0) const [play, setPlay] = useState(0) return ( <div className="flex flex-col items-center gap-6"> <SplitFlap text={TEXTS[index]} length={9} play={play} speed={45} stagger={55} className="text-2xl sm:text-3xl" /> <Button variant="outline" onClick={() => { setIndex((current) => (current + 1) % TEXTS.length) setPlay((current) => current + 1) }} > Flip </Button> </div> )}Installation
npx @arctis-sh/@arctis-sh/ui@latest add split-flapUsage
import { useState } from "react"import { SplitFlap } from "@/components/motion/split-flap"const [play, setPlay] = useState(0)<> <SplitFlap text="ON TIME" length={9} play={play} speed={45} stagger={55} /> <button type="button" onClick={() => setPlay((n) => n + 1)}> Flip </button></>API Reference
SplitFlap
| Prop | Type | Default |
|---|---|---|
| text | string | — |
| length | number | text.length |
| play | number | 0 |
| speed | number | 45 |
| stagger | number | 55 |
| characters | string | ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 |
| className | string | — |
Also accepts the other native div attributes. length is the fixed tile count. Omit it and the board sizes to the current text. Shorter text pads with blank tiles. Longer text truncates. speed is ms between flap steps. stagger delays each character start.