Flip Card Demo
loomui/flip-card-demoFreeExample
A two-by-two matching game played by turning cards over.
Install it
npx shadcn@latest add https://loomui.design/r/flip-card-demo.jsonSource
1"use client"23import * as React from "react"45import { FlipCard } from "@/registry/loomui/flip-card"67/** Fixed order, not shuffled, so the server and the client agree. */8const DECK = ["🫐", "🍑", "🍑", "🫐"]9const MISS_DELAY = 70010/** The card's own turn. The match ring waits for both to land. */11const FLIP_MS = 4801213const FACE =14 "grid size-24 place-items-center rounded-xl border text-3xl transition-colors"1516export default function FlipCardDemo() {17 const [faceUp, setFaceUp] = React.useState<number[]>([])18 const [matched, setMatched] = React.useState<number[]>([])19 // The ring waits for the turn, so it lands on a card already face up.20 const [landed, setLanded] = React.useState<number[]>([])21 const timer = React.useRef<ReturnType<typeof setTimeout>>(undefined)22 const ring = React.useRef<ReturnType<typeof setTimeout>>(undefined)2324 React.useEffect(25 () => () => {26 clearTimeout(timer.current)27 clearTimeout(ring.current)28 },29 []30 )3132 const reveal = (index: number) => {33 if (34 faceUp.length === 2 ||35 faceUp.includes(index) ||36 matched.includes(index)37 ) {38 return39 }4041 const next = [...faceUp, index]42 setFaceUp(next)4344 if (next.length < 2) {45 return46 }4748 const [first, second] = next49 if (DECK[first] === DECK[second]) {50 setMatched((current) => [...current, first, second])51 setFaceUp([])52 ring.current = setTimeout(53 () => setLanded((current) => [...current, first, second]),54 FLIP_MS55 )56 return57 }5859 timer.current = setTimeout(() => setFaceUp([]), MISS_DELAY)60 }6162 const reset = () => {63 clearTimeout(timer.current)64 clearTimeout(ring.current)65 setFaceUp([])66 setMatched([])67 setLanded([])68 }6970 const won = landed.length === DECK.length7172 return (73 <div className="flex flex-col items-center gap-5">74 <div className="grid grid-cols-2 gap-3">75 {DECK.map((emoji, index) => (76 <FlipCard77 key={index}78 flipped={faceUp.includes(index) || matched.includes(index)}79 onClick={() => reveal(index)}80 aria-label={`Card ${index + 1}`}81 front={82 <span83 className={`${FACE} bg-card text-muted-foreground/60 text-xl`}84 >85 ?86 </span>87 }88 back={89 <span90 className={`${FACE} bg-card ${91// … truncated
What it pulls in
Other registry items
Files it writes
More from loomui
All 91 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Aurora Backdrop Demoaurora-backdrop-demo | loomui | Examples | Free | no deps | |
| Bento Grid Demobento-grid-demo | loomui | Examples | Free | no deps | |
| Card Stack Democard-stack-demo | loomui | Examples | Free | no deps | |
| Compare Slider Democompare-slider-demo | loomui | Examples | Free | no deps | |
| Confetti Button Democonfetti-button-demo | loomui | Examples | Free | no deps | |
| Count Up Democount-up-demo | loomui | Examples | Free | no deps | |
| Credit Card Democredit-card-demo | loomui | Examples | Free | no deps | |
| Drawer Demodrawer-demo | loomui | Examples | Free | no deps |
