import { useEffect, useState } from "react"; import { ReplayButton, SEARCH_RESULTS } from "./fakes"; const DEMOS = [ { query: "beach-day_042.jpg", mode: "Filename", description: "Plain text matches file names — the default, instant search. One name, one file.", results: SEARCH_RESULTS.filename, }, { query: "/s golden sunset over water", mode: "Semantic", description: "Describe what's in the picture. Visual embeddings find matches even when filenames say nothing.", results: SEARCH_RESULTS.semantic, }, { query: "/t landscape", mode: "Tags", description: "Search by AI or manual tags. Autocomplete suggests tags as you type.", results: SEARCH_RESULTS.tags, }, ] as const; const TYPE_MS = 55; const HOLD_MS = 2600; /// Types each demo query, shows matching results, advances through all three /// modes once, then stops on the last with a replay control. export function StepSearchDemo() { const [demoIndex, setDemoIndex] = useState(0); const [typed, setTyped] = useState(0); const [finished, setFinished] = useState(false); const demo = DEMOS[demoIndex]; const isLastDemo = demoIndex === DEMOS.length - 1; useEffect(() => { if (finished) return; if (typed < demo.query.length) { const timer = setTimeout(() => setTyped((n) => n + 1), TYPE_MS); return () => clearTimeout(timer); } // Fully typed: hold, then advance — or finish on the last demo. const timer = setTimeout(() => { if (isLastDemo) { setFinished(true); } else { setDemoIndex((i) => i + 1); setTyped(0); } }, HOLD_MS); return () => clearTimeout(timer); }, [typed, demo.query.length, isLastDemo, finished]); const replay = () => { setDemoIndex(0); setTyped(0); setFinished(false); }; const fullyTyped = typed >= demo.query.length; return (

One search bar, three modes — picked by prefix. No prefix searches filenames, /s searches by meaning, /t searches tags.

{/* Mock search bar */}
{demo.query.slice(0, typed)} {!finished ? | : null} {demo.mode}
{/* Results — fixed-width tiles, centered, so 1/2/3 results all look right */}
{demo.results.map((src, i) => (
))}

{demo.description}

{finished ? : null}
); }