Split Flap

Airport-board letter flips.

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-flap

Usage

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

PropTypeDefault
textstring—
lengthnumbertext.length
playnumber0
speednumber45
staggernumber55
charactersstringABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
classNamestring—

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.