Files
2025-10-16 21:45:52 -07:00

11 lines
2.8 KiB
JSON

{
"name": "choicebox",
"description": "Enhanced choice selector",
"files": [
{
"name": "choicebox.tsx",
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Check } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\n\nexport interface ChoiceboxOption {\n value: string\n label: string\n description?: string\n}\n\nexport interface ChoiceboxProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n options: ChoiceboxOption[]\n value?: string\n onChange?: (value: string) => void\n multiple?: boolean\n}\n\nconst Choicebox = React.forwardRef<HTMLDivElement, ChoiceboxProps>(\n (\n { className, options, value, onChange, multiple = false, ...props },\n ref\n ) => {\n const [selected, setSelected] = React.useState<string[]>(\n value ? [value] : []\n )\n\n const handleSelect = (optionValue: string) => {\n if (multiple) {\n const newSelected = selected.includes(optionValue)\n ? selected.filter((v) => v !== optionValue)\n : [...selected, optionValue]\n setSelected(newSelected)\n onChange?.(newSelected.join(\",\"))\n } else {\n setSelected([optionValue])\n onChange?.(optionValue)\n }\n }\n\n return (\n <div ref={ref} className={cn(\"space-y-2\", className)} {...props}>\n {options.map((option) => (\n <button\n key={option.value}\n type=\"button\"\n onClick={() => handleSelect(option.value)}\n className={cn(\n \"relative w-full rounded-lg border-2 p-4 text-left transition-colors hover:bg-accent\",\n selected.includes(option.value)\n ? \"border-primary bg-primary/5\"\n : \"border-input\"\n )}\n >\n <div className=\"flex items-start gap-3\">\n <div\n className={cn(\n \"mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full border-2\",\n selected.includes(option.value)\n ? \"border-primary bg-primary\"\n : \"border-input\"\n )}\n >\n {selected.includes(option.value) && (\n <Check className=\"h-3 w-3 text-primary-foreground\" />\n )}\n </div>\n <div className=\"flex-1\">\n <div className=\"font-medium\">{option.label}</div>\n {option.description && (\n <div className=\"text-sm text-muted-foreground\">\n {option.description}\n </div>\n )}\n </div>\n </div>\n </button>\n ))}\n </div>\n )\n }\n)\nChoicebox.displayName = \"Choicebox\"\n\nexport { Choicebox }\n"
}
],
"type": "components:ui"
}