{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "chip-group", "title": "Chip Group", "description": "Single or multi-select filter chips on Radix ToggleGroup. Hairline, wash, glass and solid variants.", "dependencies": [ "class-variance-authority", "radix-ui" ], "registryDependencies": [ "http://localhost:5173/r/liquid-theme.json", "toggle-group" ], "files": [ { "path": "src/components/ui/chip-group.tsx", "content": "import * as React from \"react\"\nimport { ToggleGroup as ToggleGroupPrimitive } from \"radix-ui\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\n/**\n * The 3 month / 6 month / 1 year range picker, and the Equifax / TransUnion\n * source picker. Distinct from SegmentedControl: chips filter a view and can\n * be multi-select, so the selected state is a quiet outline rather than a\n * filled slab — nothing here should compete with a tile's headline number.\n */\nconst chip = cva(\n \"inline-flex select-none items-center justify-center gap-1.5 rounded-full font-sans whitespace-nowrap lq-ease transition-[background-color,color,border-color,opacity] duration-300 outline-none focus-visible:ring-3 focus-visible:ring-current/25 disabled:pointer-events-none disabled:opacity-40\",\n {\n variants: {\n size: {\n sm: \"h-7 px-3 text-[12px]\",\n md: \"h-9 px-4 text-[13px]\",\n lg: \"h-10 px-5 text-[14px]\",\n },\n variant: {\n /** Hairline outline; selection brightens the border and the label. */\n hairline:\n \"border border-current/15 text-current/45 hover:text-current/70 data-[state=on]:border-current/60 data-[state=on]:text-current\",\n /** Selection fills with a faint wash instead of a border change. */\n wash: \"border border-transparent text-current/50 hover:text-current/75 data-[state=on]:bg-current/10 data-[state=on]:text-current\",\n /** Frosted chips for photographic grounds. */\n glass:\n \"border border-white/15 text-white/55 hover:text-white/80 data-[state=on]:lq-glass data-[state=on]:text-white\",\n /** Selection fills solid — the strongest reading, use for one chip only. */\n solid:\n \"border border-current/15 text-current/55 hover:text-current/80 data-[state=on]:border-transparent data-[state=on]:bg-ink data-[state=on]:text-white\",\n },\n },\n defaultVariants: { size: \"md\", variant: \"hairline\" },\n },\n)\n\ntype Option = { value: string; label: React.ReactNode; disabled?: boolean }\n\ntype ChipGroupProps = VariantProps & {\n options: Option[]\n className?: string\n} & (\n | {\n multiple?: false\n value?: string\n defaultValue?: string\n onValueChange?: (value: string) => void\n }\n | {\n multiple: true\n value?: string[]\n defaultValue?: string[]\n onValueChange?: (value: string[]) => void\n }\n )\n\nexport function ChipGroup({\n options,\n size,\n variant,\n className,\n ...props\n}: ChipGroupProps) {\n const items = options.map((opt) => (\n \n {opt.label}\n \n ))\n\n const shared = {\n \"data-slot\": \"chip-group\",\n className: cn(\"inline-flex flex-wrap items-center gap-2\", className),\n }\n\n if (props.multiple) {\n const { multiple: _m, value, defaultValue, onValueChange } = props\n void _m\n return (\n \n {items}\n \n )\n }\n\n const { value, defaultValue, onValueChange } = props\n return (\n v && onValueChange?.(v)}\n {...shared}\n >\n {items}\n \n )\n}\n", "type": "registry:ui" } ], "type": "registry:ui" }