"use client"; import { useEffect, useId, useRef, useState, type CSSProperties, type KeyboardEvent, type ReactNode } from "react"; import "./card-catalogue-faq.css"; /** * Card Catalogue FAQ * Questions filed like a library's card catalogue. Each topic is a drawer * with a brass label and a count; pull one and its index cards rise out of * it, standing edge-up so you read only their headings. Lift a card and it * comes up out of the row to show the answer on its ruled face. */ export type CatalogueCard = { q: string; a: ReactNode }; export type Drawer = { id: string; label: string; cards: CatalogueCard[] }; type Props = { drawers: Drawer[]; defaultDrawer?: string; theme?: "paper" | "night"; motion?: "full" | "reduced"; className?: string; }; export function CardCatalogueFaq({ drawers, defaultDrawer, theme = "paper", motion = "full", className = "" }: Props) { const uid = useId(); const [drawer, setDrawer] = useState(defaultDrawer ?? drawers[0].id); const [card, setCard] = useState(null); const [pulls, setPulls] = useState(0); const tabs = useRef<(HTMLButtonElement | null)[]>([]); const current = drawers.find((d) => d.id === drawer) ?? drawers[0]; // Deep links: #billing opens a drawer, #billing-2 also lifts its second card. useEffect(() => { const read = () => { const m = window.location.hash.slice(1).match(/^(.+?)(?:-(\d+))?$/); const d = m && drawers.find((x) => x.id === m[1]); if (!d) return; setDrawer(d.id); setCard(m![2] ? Number(m![2]) - 1 : null); }; read(); window.addEventListener("hashchange", read); return () => window.removeEventListener("hashchange", read); }, [drawers]); const pull = (id: string) => { if (id === drawer) return; setDrawer(id); setCard(null); setPulls((p) => p + 1); }; const onTabKey = (e: KeyboardEvent, i: number) => { const to = e.key === "ArrowRight" ? (i + 1) % drawers.length : e.key === "ArrowLeft" ? (i - 1 + drawers.length) % drawers.length : e.key === "Home" ? 0 : e.key === "End" ? drawers.length - 1 : null; if (to === null) return; e.preventDefault(); pull(drawers[to].id); tabs.current[to]?.focus(); }; return (
{drawers.map((d, i) => ( ))}
    {current.cards.map((c, i) => { const open = card === i; return (
  1. {c.a}
  2. ); })}
); }