"use client";
import * as React from "react";
import { COUNTRIES, CountryFlag, CountrySearchPalette, continentOf, nativeCountryName } from "@/components/ui/country-search-palette";
const settings = {
open: true,
tour: true,
globe: true,
continents: true,
};
const SUGGESTED = ["US", "GB", "DE", "JP", "BR", "IN"];
const TOUR = ["japan", "brasil", "deutschland", "kenya"];
const TYPE_MS = 110;
const HOLD_MS = 1500;
const FIRST_KEY_MS = 600;
const CCGATHER_URL = "https://ccgather.com/?utm_source=21st&utm_medium=component&utm_campaign=country_palette";
export default function Demo(props: Partial<typeof settings>) {
const s = { ...settings, ...props };
const [code, setCode] = React.useState("JP");
const [open, setOpen] = React.useState(s.open);
const [search, setSearch] = React.useState("");
const [touring, setTouring] = React.useState(s.tour && s.open);
const selected = COUNTRIES.find((country) => country.code === code);
const [native, setNative] = React.useState(null as string | null);
React.useEffect(() => {
setNative(selected ? nativeCountryName(selected.code, selected.name) : null);
}, [selected]);
React.useEffect(() => {
if (!touring || !open) return;
const timers: number[] = [];
let at = FIRST_KEY_MS;
for (const word of TOUR) {
const letters = Array.from(word);
for (let i = 1; i <= letters.length; i++) {
const text = letters.slice(0, i).join("");
timers.push(window.setTimeout(() => setSearch(text), at));
at += TYPE_MS;
}
at += HOLD_MS;
}
timers.push(window.setTimeout(() => setTouring(false), at));
return () => timers.forEach((timer) => window.clearTimeout(timer));
}, [touring, open]);
React.useEffect(() => {
if (!touring) return;
const stop = (event: Event) => {
if (event.isTrusted) setTouring(false);
};
window.addEventListener("pointerdown", stop, true);
window.addEventListener("keydown", stop, true);
return () => {
window.removeEventListener("pointerdown", stop, true);
window.removeEventListener("keydown", stop, true);
};
}, [touring]);
return (
<div className="flex min-h-screen w-full flex-col items-center justify-center gap-4 bg-background p-6">
<div className="w-full max-w-sm space-y-3 rounded-2xl border border-border bg-card p-5 text-card-foreground shadow-sm">
<p className="text-[11px] font-medium uppercase tracking-[0.14em] text-muted-foreground">Country or region</p>
<CountrySearchPalette
value={code}
onValueChange={(next) => setCode(next)}
suggested={SUGGESTED}
showGlobe={s.globe}
showContinents={s.continents}
open={open}
onOpenChange={(next) => {
setOpen(next);
if (!next) {
setTouring(false);
setSearch("");
}
}}
search={search}
onSearchChange={setSearch}
/>
{selected && (
<div className="flex items-center gap-2 text-xs text-muted-foreground">
<CountryFlag code={selected.code} className="h-3 w-[18px]" />
<span className="text-foreground">{selected.name}</span>
{native && <span dir="auto">{native}</span>}
<span>· {continentOf(selected.code) ?? "—"}</span>
</div>
)}
</div>
<p className="text-xs text-muted-foreground">
Press <kbd className="rounded border border-border bg-muted px-1 font-mono text-[10px]">⌘K</kbd> to search ·{" "}
<a href={CCGATHER_URL} target="_blank" rel="noreferrer" className="underline underline-offset-4 transition-colors hover:text-foreground">
from CCgather
</a>
</p>
</div>
);
}