"use client"; import { useEffect, useMemo, useRef, useState } from "react"; import { Check, Search, X } from "lucide-react"; const MONO = "var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace)"; /** * 语言选择自定义下拉(统一站点样式): * - variant="toolbar":广场工具台(含"全部语言"与清除) * - variant="editor":新建/编辑片段表单(药丸形,语言必选) */ export default function SnippetLangSelect({ value, onChange, languages, allowAll = true, variant = "toolbar", ariaLabel = "选择语言", allLabel = "全部语言", disabled = false, }: { value: string; onChange: (v: string) => void; languages: string[]; allowAll?: boolean; variant?: "toolbar" | "editor"; ariaLabel?: string; allLabel?: string; disabled?: boolean; }) { const [open, setOpen] = useState(false); const [q, setQ] = useState(""); const ref = useRef(null); const inputRef = useRef(null); useEffect(() => { if (!open) return; setQ(""); const t = window.setTimeout(() => inputRef.current?.focus(), 30); const onDown = (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", onDown); document.addEventListener("keydown", onKey); return () => { window.clearTimeout(t); document.removeEventListener("mousedown", onDown); document.removeEventListener("keydown", onKey); }; }, [open]); const filtered = useMemo(() => { const kw = q.trim().toLowerCase(); return kw ? languages.filter((l) => l.includes(kw)) : languages; }, [q, languages]); const triggerCls = variant === "editor" ? "j13-sn-search h-8 rounded-full pl-3 pr-2.5 text-[12.5px] gap-1.5" : "j13-sn-search w-full h-9 rounded-lg px-3 text-[12.5px] gap-2"; const wrapCls = variant === "editor" ? "relative shrink-0" : "relative shrink-0 sm:w-44 w-full"; const menuCls = variant === "editor" ? "j13-sn-lang-menu absolute z-30 mt-1.5 left-0 w-56 rounded-xl overflow-hidden" : "j13-sn-lang-menu absolute z-30 mt-1.5 left-0 right-0 sm:right-auto sm:w-60 rounded-xl overflow-hidden"; return (
{open && (
setQ(e.target.value)} placeholder="筛选语言…" aria-label="筛选语言" className="w-full h-8 rounded-md pl-7 pr-2 text-[12px] outline-none" style={{ background: "var(--panel-2)", border: "1px solid transparent", color: "var(--ink)" }} />
    {allowAll ? ( { onChange(""); setOpen(false); }} label={allLabel} dotDim /> ) : null} {filtered.length === 0 ? (
  • 没有匹配的语言
  • ) : ( filtered.map((l) => ( { onChange(l); setOpen(false); }} label={l} mono /> )) )}
)}
); } function ArrowDownIcon({ className = "", rotated }: { className?: string; rotated: boolean }) { return ( ); } function LangOption({ active, onClick, label, mono, dotDim, }: { active: boolean; onClick: () => void; label: string; mono?: boolean; dotDim?: boolean; }) { return (
  • ); }