import { useState } from "react"; import { Globe } from "lucide-react"; import { MenuCheck } from "./ui/MenuCheck"; import { LANGUAGES, type LangCode } from "../i18n"; import { PopoverItem, PopoverSurface } from "./ui/AnchoredPopover"; import { useAnchoredPopover } from "./ui/anchoredPopoverHooks"; import { Pressable } from "./ui/Pressable"; import { RAIL_GLYPH, RAIL_ROW } from "./ui/NavRail"; import { SURFACE } from "./ui/surfaces"; // Compact language picker (globe + current code). Presentational: the parent decides what // changing the language does (set it; persist server-side when signed in). // // Two variants, now one implementation on the popover platform: "header" opens below the pill // (used on the landing page and the setup wizard) and "rail" is an icon-only button in the left // nav's bottom cluster whose menu opens to the RIGHT, bottom-aligned. Both used to hand-roll their // own anchoring, and the header one also opened on hover — dropped on purpose: the platform focuses // the first item when a menu opens, so a hover-open would yank focus off whatever the user was doing. export default function LanguageSwitcher({ value, onChange, align = "right", variant = "header", }: { value: LangCode; onChange: (code: LangCode) => void; align?: "left" | "right"; variant?: "header" | "rail"; }) { const [open, setOpen] = useState(false); const currentIdx = Math.max( 0, LANGUAGES.findIndex((l) => l.code === value), ); const current = LANGUAGES.find((l) => l.code === value) ?? LANGUAGES[0]; const rail = variant === "rail"; const pop = useAnchoredPopover({ open, onOpenChange: setOpen, placement: rail ? "right-end" : align === "right" ? "bottom-end" : "bottom-start", offset: rail ? 8 : 4, // Single choice: opening lands on the language already in use. selectedIndex: currentIdx, }); const { setReference } = pop.refs; return ( <> {rail ? ( /* A rail row (F32), with the current-language badge (HU/EN) on the glyph's corner so the active language reads at a glance. The ring matches the page to detach it from the icon; its type is the rail count badge's (text-3xs), the smallest step on the scale (it was an 8px one-off). */ {current.code.toUpperCase()} ) : ( )} {rail ? null : {current.code}} {LANGUAGES.map((l) => ( { onChange(l.code); setOpen(false); }} label={l.label} className="w-full flex items-center gap-2 text-sm px-2 py-2 rounded-lg text-muted outline-hidden transition hover:text-fg" > {l.label} ))} ); }