All Taste components
Inputs
Chips & toggle group
Chips for picking several options, and a joined button group for picking exactly one.
multi-select chips · single-select group · pressed · hover
Cuisines you serve
Payment terms
"use client";
import { Check } from "lucide-react";
import { cn } from "@/lib/utils";
export function ChipSelect({ label, options, value, onChange }:
{ label: string; options: string[]; value: string[]; onChange: (v: string[]) => void }) {
const toggle = (o: string) => onChange(value.includes(o) ? value.filter((v) => v !== o) : [...value, o]);
return (
<div role="group" aria-label={label} className="flex flex-wrap gap-2">
{options.map((o) => {
const on = value.includes(o);
return (
<button
key={o}
type="button"
aria-pressed={on}
onClick={() => toggle(o)}
className={cn(
"inline-flex h-8 items-center gap-1.5 whitespace-nowrap rounded border px-3 text-[13px] font-medium transition",
on ? "border-primary/45 bg-primary-soft pl-[9px] text-primary-soft-fg" : "border-border-strong bg-bg text-fg-muted hover:bg-surface hover:text-fg",
)}
>
{on && <Check className="size-3.5" aria-hidden />}
{o}
</button>
);
})}
</div>
);
}
export function ToggleGroup({ label, options, value, onChange }:
{ label: string; options: string[]; value: string; onChange: (v: string) => void }) {
return (
<div role="group" aria-label={label} className="inline-flex max-w-full overflow-hidden rounded border border-border-strong bg-bg">
{options.map((o) => (
<button
key={o}
type="button"
aria-pressed={o === value}
onClick={() => onChange(o)}
className={cn(
"h-[34px] flex-auto whitespace-nowrap border-l border-border-strong px-3 text-[13px] font-medium text-fg-muted transition first:border-l-0",
"hover:bg-surface hover:text-fg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring",
"aria-pressed:bg-primary-soft aria-pressed:text-primary-soft-fg",
)}
>
{o}
</button>
))}
</div>
);
}
The code uses the Taste Tailwind preset. Make yours on the Taste page with Export my system.