{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "masai-radio-group", "title": "Masai Radio Group", "description": "Composed radio group built with Radix; includes standalone Masai radio button component on install.", "dependencies": [ "@radix-ui/react-radio-group" ], "files": [ { "path": "registry/components/masai-radio-button.tsx", "content": "\"use client\";\n\nimport * as React from \"react\";\nimport * as RadioGroupPrimitive from \"@radix-ui/react-radio-group\";\nimport { cn } from \"@/lib/utils\";\n\ntype MasaiRadioButtonSize = \"regular\" | \"large\";\n\nexport type MasaiRadioButtonProps = {\n size?: MasaiRadioButtonSize;\n isSelected?: boolean;\n disabled?: boolean;\n label?: string;\n description?: string;\n onSelect?: (selected: boolean) => void;\n className?: string;\n};\n\nconst radioSizeClasses: Record = {\n regular: { root: \"h-5 w-5\", dot: \"h-2.5 w-2.5\" },\n large: { root: \"h-6 w-6\", dot: \"h-3 w-3\" },\n};\n\n/**\n * MasaiRadioButton — single radio wrapper on Radix RadioGroup.\n * Useful for standalone previews and custom layouts.\n */\nexport function MasaiRadioButton({\n size = \"regular\",\n isSelected = false,\n disabled = false,\n label,\n description,\n onSelect,\n className,\n}: MasaiRadioButtonProps) {\n const value = isSelected ? \"selected\" : \"unselected\";\n const { root, dot } = radioSizeClasses[size];\n const labelClassName = size === \"large\" ? \"type-b1-regular text-gray-900\" : \"type-b2-regular text-gray-900\";\n\n return (\n onSelect?.(next === \"selected\")}\n disabled={disabled}\n className={cn(\"inline-flex items-start\", className)}\n >\n \n \n );\n}\n", "type": "registry:ui" }, { "path": "registry/components/masai-radio-group.tsx", "content": "\"use client\";\n\nimport * as React from \"react\";\nimport * as RadioGroupPrimitive from \"@radix-ui/react-radio-group\";\nimport { cn } from \"@/lib/utils\";\n\ntype MasaiRadioGroupSize = \"regular\" | \"large\";\n\nexport type MasaiRadioOption = {\n value: string;\n label?: string;\n description?: string;\n disabled?: boolean;\n};\n\nexport type MasaiRadioGroupOrientation = \"vertical\" | \"horizontal\";\n\nexport type MasaiRadioGroupProps = {\n size?: MasaiRadioGroupSize;\n value: string;\n onValueChange: (value: string) => void;\n options: Array;\n /** Default stacking; use `className` for grids (e.g. `grid grid-cols-2 gap-4`). */\n orientation?: MasaiRadioGroupOrientation;\n} & Omit<\n React.ComponentPropsWithoutRef,\n \"children\" | \"value\" | \"defaultValue\" | \"onValueChange\"\n>;\n\nconst orientationLayoutClasses: Record = {\n vertical: \"flex flex-col gap-3\",\n horizontal: \"flex flex-row flex-wrap items-start gap-x-6 gap-y-3\",\n};\n\nconst radioSizeClasses: Record = {\n regular: { root: \"h-5 w-5\", dot: \"h-2.5 w-2.5\" },\n large: { root: \"h-6 w-6\", dot: \"h-3 w-3\" },\n};\n\n/**\n * MasaiRadioGroup — grouped radios on Radix.\n * Registry install includes `masai-radio-button.tsx` for standalone use.\n */\nexport function MasaiRadioGroup({\n size = \"regular\",\n value,\n onValueChange,\n options,\n orientation = \"vertical\",\n className,\n disabled,\n ...rootProps\n}: MasaiRadioGroupProps) {\n const { root, dot } = radioSizeClasses[size];\n const labelClassName = size === \"large\" ? \"type-b1-regular text-gray-900\" : \"type-b2-regular text-gray-900\";\n\n return (\n \n {options.map((option) => (\n \n \n \n \n \n \n {option.label || option.description ? (\n \n {option.label ? {option.label} : null}\n {option.description ? {option.description} : null}\n \n ) : null}\n \n ))}\n \n );\n}\n", "type": "registry:ui" } ], "type": "registry:ui" }