"use client"; import { useEffect, useMemo, useRef, useState } from "react"; import type { IPlaygroundExample } from "../structures/IPlaygroundExample"; interface ExamplePickerProps { examples: readonly IPlaygroundExample[]; onPick: (id: string) => void; /** Display labels for groups. Maps `group` key → rendered heading. */ groupLabels?: Record; } export function ExamplePicker({ examples, onPick, groupLabels, }: ExamplePickerProps) { const [open, setOpen] = useState(false); const ref = useRef(null); useEffect(() => { if (!open) return; const close = (e: MouseEvent) => { if (ref.current && !ref.current.contains(e.target as Node)) { setOpen(false); } }; const onKey = (e: KeyboardEvent) => { if (e.key === "Escape") setOpen(false); }; document.addEventListener("mousedown", close); document.addEventListener("keydown", onKey); return () => { document.removeEventListener("mousedown", close); document.removeEventListener("keydown", onKey); }; }, [open]); const grouped = useMemo(() => { return examples.reduce>((acc, e) => { const key = e.group ?? "Examples"; (acc[key] ??= []).push(e); return acc; }, {}); }, [examples]); if (examples.length === 0) return null; return (
{open && (
{Object.entries(grouped).map(([group, items]) => (
{groupLabels?.[group] ?? group}
{items.map((item) => ( ))}
))}
)}
); }