BlockDex

Components

Registries

Free blocks

Method

BlockDex

Components

Registries

Free blocks

Method

Open API

BlockDex

Components

Registries

Free blocks

Method

Open API

Components/@codyshanley/split-flap

Split-Flap Panel

codyshanley/split-flap
FreeComponent

Solari-style split-flap display for React. CSS 3D, no canvas.

Install it

npx shadcn@latest add https://codyshanley.com/r/split-flap.json

Source

components/split-flap-slat.tsxcodyshanley.com/r/split-flap.json
1/**
2 * Split-Flap Panel — a CSS-3D recreation of Solari-style departure boards.
3 * Built by Cody Shanley · https://codyshanley.com/playground/split-flap?utm_source=github&utm_medium=attribution&utm_campaign=split-flap
4 * MIT licensed. Free to use, modify, and redistribute.
5 */
6"use client";
7
8import { useEffect, useRef, useState } from "react";
9
10export const SPLITFLAP_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789. ";
11
12function nextChar(c: string): string {
13 const i = SPLITFLAP_ALPHABET.indexOf(c);
14 return SPLITFLAP_ALPHABET[(i + 1) % SPLITFLAP_ALPHABET.length];
15}
16
17/** Forward-only distance from `from` to `to` on the one-way alphabet chain.
18 * Matches real Solari mechanism: X -> D = 8 (via Y,Z,blank,A,B,C,D), not 6. */
19export function computeFlipCount(from: string, to: string): number {
20 const a = SPLITFLAP_ALPHABET.indexOf(from);
21 const b = SPLITFLAP_ALPHABET.indexOf(to);
22 if (a < 0 || b < 0) return 0;
23 return (b - a + SPLITFLAP_ALPHABET.length) % SPLITFLAP_ALPHABET.length;
24}
25
26interface Props {
27 target: string;
28 stepMs?: number;
29 startDelayMs?: number;
30 minFlips?: number;
31 onFlip?: () => void;
32 size?: "default" | "xl" | "compact" | "hero";
33 /** Freeze the slat in a mid-flip pose for visual inspection. Disables animation. */
34 frozenMidFlip?: boolean;
35 /** Debug: override the letters shown. Useful for static reference slats. */
36 staticLetter?: string;
37 /** Letter to display as the initial state without animation. Read once at mount. */
38 initialCurrent?: string;
39}
40
41export function SplitFlapSlat({
42 target,
43 stepMs = 110,
44 startDelayMs = 0,
45 minFlips = 1,
46 onFlip,
47 size = "default",
48 frozenMidFlip = false,
49 staticLetter,
50 initialCurrent,
51}: Props) {
52 const [current, setCurrent] = useState<string>(staticLetter ?? initialCurrent ?? " ");
53 const [next, setNext] = useState<string | null>(null);
54 const [isFlipping, setIsFlipping] = useState(false);
55 const currentRef = useRef(current);
56
57 useEffect(() => {
58 currentRef.current = current;
59 }, [current]);
60
61 useEffect(() => {
62 if (staticLetter !== undefined || frozenMidFlip) return;
63
64 const prefersReduced =
65 typeof window !== "undefined" &&
66 window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
67
68 if (prefersReduced) {
69 setCurrent(target);
70 return;
71 }
72
73 let cancelled = false;
74 const timers: ReturnType<typeof setTimeout>[] = [];
75
76 const flipsNeeded = () => {
77 const from = SPLITFLAP_ALPHABET.indexOf(currentRef.current);
78// … truncated

Files it writes

  • registry/split-flap/split-flap-slat.tsx
  • registry/split-flap/split-flap-display.tsx
  • registry/split-flap/split-flap.css

Facts

Registry
@codyshanley
Type
registry:component
Access
Free
Files written
3
Licence
MIT
First indexed
2026-08-03
Last confirmed
yesterday

Go to the source

codyshanley.com codemanshan/splitflap on GitHub Raw registry item This item as JSON
BlockDex

Built by

Kynth Studio

Index

Components
Registries
Method
Open API

Guides

shadcn component libraries
Best shadcn registries
Free shadcn blocks

Reference

Corpus counts
Crawl health
hello@kynth.studio
Privacy
Terms

BlockDex

BlockDex

Built by

Kynth Studio

Index

Components
Registries
Method
Open API

Guides

shadcn component libraries
Best shadcn registries
Free shadcn blocks

Reference

Corpus counts
Crawl health
hello@kynth.studio
Privacy
Terms

BlockDex

BlockDex

Built by

Kynth Studio

Index

Components
Registries
Method
Open API

Guides

shadcn component libraries
Best shadcn registries
Free shadcn blocks

Reference

Corpus counts
Crawl health
hello@kynth.studio
Privacy
Terms

BlockDex