Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
45 lines
1.5 KiB
TypeScript
45 lines
1.5 KiB
TypeScript
import { cn } from "~/lib/utils.ts";
|
|
import type { Option } from "./discover-state.ts";
|
|
|
|
// 一行单选芯片(选中用 pill-selected);标签在左,窄屏横向滚动。allLabel 给了就多一个「不限」芯片(value 为空)。
|
|
|
|
export function ChipRow({
|
|
label,
|
|
options,
|
|
value,
|
|
onChange,
|
|
allLabel,
|
|
}: {
|
|
label: string;
|
|
options: Option[];
|
|
value: string | undefined;
|
|
onChange: (v: string | undefined) => void;
|
|
allLabel?: string;
|
|
}) {
|
|
const all = allLabel ? [{ value: "", label: allLabel }, ...options] : options;
|
|
return (
|
|
<div className="flex min-w-0 items-center gap-3">
|
|
<span className="w-10 shrink-0 text-meta text-muted-foreground">{label}</span>
|
|
<fieldset aria-label={label} className="scroll-bleed flex min-w-0 gap-1 overflow-x-auto border-0">
|
|
{all.map((o) => {
|
|
const on = (value ?? "") === o.value;
|
|
return (
|
|
<button
|
|
key={o.value || "_all"}
|
|
type="button"
|
|
aria-pressed={on}
|
|
onClick={() => onChange(o.value || undefined)}
|
|
className={cn(
|
|
"h-7 shrink-0 cursor-pointer rounded-full border border-transparent px-2.5 text-meta whitespace-nowrap text-muted-foreground outline-none transition-colors duration-micro hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring",
|
|
on && "pill-selected text-foreground",
|
|
)}
|
|
>
|
|
{o.label}
|
|
</button>
|
|
);
|
|
})}
|
|
</fieldset>
|
|
</div>
|
|
);
|
|
}
|