import clsx from "clsx"; // The chip family's geometry and paint, apart from the component (`Chip.tsx`) so the hidden measuring // mirror of an overflowing chip lane can lay out exactly like the chips it measures. export type ChipVariant = "filter" | "token" | "tag" | "suggest" | "ghost"; export type ChipSize = | "md" // 28, text-sm — the applied-filter row above the feed | "sm" // 24, text-xs — a filter row | "xs"; // 24, text-2xs, tight — a tag in a table row const PAINT: Record = { // `.pill` owns the resting, hover AND pressed colours; a colour utility here would beat the pressed // fill, so the open-popover state is the only one spelled out. filter: "pill border shadow-xs aria-expanded:border-accent aria-expanded:text-accent", token: "chip act:hover:border-accent act:hover:bg-accent/20 aria-expanded:border-accent", // B3: a filled control's hover mixes its own text colour into the fill, never an opacity dim. tag: "chip-solid font-medium act:hover:bg-[color-mix(in_srgb,var(--accent-fg)_14%,var(--accent))]", suggest: "border border-dashed border-accent/50 text-accent/90 act:hover:text-accent act:hover:border-accent", ghost: "border border-dashed border-border text-muted act:hover:text-accent act:hover:border-accent", }; const SIZES: Record = { md: "h-7 px-2.5 text-sm gap-1", sm: "h-6 px-2.5 text-xs gap-1.5", xs: "h-6 px-1.5 text-2xs gap-1", }; const BASE = "inline-flex min-w-6 shrink-0 items-center justify-center rounded-full whitespace-nowrap transition touch-target disabled:opacity-50 aria-disabled:opacity-50 [&>svg]:shrink-0"; /** The chip's geometry + paint as a class string: for the hidden measuring mirror of an overflowing * chip lane, which must lay out exactly like the chips it measures but must not be buttons. */ export function chipClass(variant: ChipVariant = "filter", size: ChipSize = "sm") { return clsx(BASE, PAINT[variant], SIZES[size]); }