{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "radio-group", "title": "RadioButton", "description": "A radio group component", "dependencies": [ "@radix-ui/react-radio-group", "lucide-react" ], "files": [ { "path": "registry/cs/ui/radio-group/radio-group.tsx", "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\nimport type { CsBtnColor, CsIcon } from \"@/registry/cs/ui/button/button\"\n\n/** Radio button option. */\nexport interface RadioOption {\n label?: string\n value: T\n disabled?: boolean\n icon?: CsIcon\n}\n\n/** Props for RadioButtons (button-style radio group). */\nexport interface RadioButtonsProps\n extends Omit, \"onChange\" | \"defaultValue\"> {\n /** Options to display. */\n options: RadioOption[]\n /** Controlled value. */\n value?: T\n /** Uncontrolled default value. */\n defaultValue?: T\n /** Name for the radio group. */\n name?: string\n /** Button size. */\n size?: \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\"\n /** Button color. */\n color?: CsBtnColor\n /** Border radius. */\n radius?: \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\"\n /** Layout direction. */\n direction?: \"row\" | \"column\"\n /** Gap between options. */\n gap?: \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\"\n /** Bold text. */\n bold?: boolean\n /** Icon position. */\n iconPosition?: \"left\" | \"right\"\n /** Full width options. */\n w100?: boolean\n /** Disabled state. */\n disabled?: boolean\n /** Callback with string value. */\n onString?: (value: string) => void\n /** Callback with number value. */\n onNumber?: (value: number) => void\n}\n\nconst SIZE_MAP = {\n xs: \"h-6 px-2 text-xs gap-1\",\n sm: \"h-8 px-3 text-sm gap-1.5\",\n md: \"h-9 px-4 text-sm gap-2\",\n lg: \"h-10 px-5 text-base gap-2\",\n xl: \"h-12 px-6 text-base gap-2.5\",\n}\n\nconst RADIUS_MAP = {\n xs: \"rounded-none\",\n sm: \"rounded-sm\",\n md: \"rounded-md\",\n lg: \"rounded-lg\",\n xl: \"rounded-full\",\n}\n\nconst GAP_MAP = {\n xs: \"gap-1\",\n sm: \"gap-2\",\n md: \"gap-3\",\n lg: \"gap-4\",\n xl: \"gap-6\",\n}\n\nconst COLOR_ACTIVE: Record = {\n primary: \"bg-cs-primary text-cs-primary-text border-cs-primary\",\n secondary: \"bg-cs-secondary text-cs-secondary-text border-cs-secondary\",\n grey: \"bg-cs-grey text-cs-grey-text border-cs-grey\",\n dark: \"bg-cs-dark text-cs-dark-text border-cs-dark\",\n red: \"bg-cs-red text-cs-red-text border-cs-red\",\n blue: \"bg-cs-blue text-cs-blue-text border-cs-blue\",\n green: \"bg-cs-green text-cs-green-text border-cs-green\",\n yellow: \"bg-cs-yellow text-cs-yellow-text border-cs-yellow\",\n orange: \"bg-cs-orange text-cs-orange-text border-cs-orange\",\n}\n\nfunction RadioButtons({\n options,\n value: controlledValue,\n defaultValue,\n name,\n size = \"md\",\n color = \"primary\",\n radius = \"lg\",\n direction = \"row\",\n gap = \"md\",\n bold = false,\n iconPosition = \"left\",\n w100 = false,\n disabled = false,\n className,\n onString,\n onNumber,\n ...props\n}: RadioButtonsProps) {\n const groupName = name ?? React.useId()\n const [internalValue, setInternalValue] = React.useState(defaultValue)\n const currentValue = controlledValue ?? internalValue\n\n const handleChange = (val: T) => {\n if (controlledValue === undefined) setInternalValue(val)\n onString?.(String(val))\n onNumber?.(Number(val))\n }\n\n return (\n \n {options?.map((option) => {\n const isActive = currentValue === option.value\n const iconElement =\n option.icon && typeof option.icon === \"function\"\n ? React.createElement(option.icon as React.FC>)\n : option.icon\n\n return (\n \n handleChange(option.value)}\n className=\"sr-only\"\n />\n {iconPosition === \"left\" && iconElement}\n {option.label && {option.label}}\n {iconPosition === \"right\" && iconElement}\n \n )\n })}\n \n )\n}\n\nexport { RadioButtons }\n", "type": "registry:ui" } ], "type": "registry:ui" }