'use client'; import { useEffect, useRef, useState } from 'react'; const STYLES = `.wf-menu-btn{appearance:none;-webkit-appearance:none;border:none;display:inline-flex;align-items:center;justify-content:center;height:40px;padding:0 12px;border-radius:6px;font-size:14px;font-weight:500;line-height:20px;color:var(--ds-gray-1000);background:var(--ds-background-100);box-shadow:0 0 0 1px var(--ds-gray-400);cursor:pointer;white-space:nowrap;transition:background 150ms}.wf-menu-btn:hover{background:var(--ds-gray-alpha-200)}.wf-menu-item{appearance:none;-webkit-appearance:none;border:none;display:flex;align-items:center;width:100%;height:40px;padding:0 8px;border-radius:6px;font-size:14px;color:var(--ds-gray-1000);background:transparent;cursor:pointer;transition:background 150ms}.wf-menu-item:hover{background:var(--ds-gray-alpha-100)}`; export interface MenuDropdownOption { value: T; label: string; } interface MenuDropdownProps { options: MenuDropdownOption[]; value: T; onChange: (value: T) => void; } /** * A dropdown menu that matches Geist's MenuButton (secondary) + Menu styling. * Uses CSS classes with proper :hover specificity (no inline background). */ export function MenuDropdown({ options, value, onChange, }: MenuDropdownProps) { const [open, setOpen] = useState(false); const ref = useRef(null); const label = options.find((o) => o.value === value)?.label ?? options[0]?.label ?? ''; useEffect(() => { if (!open) return; function handleClickOutside(e: MouseEvent) { if (ref.current && !ref.current.contains(e.target as Node)) { setOpen(false); } } document.addEventListener('mousedown', handleClickOutside); return () => document.removeEventListener('mousedown', handleClickOutside); }, [open]); return (