{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "radio-group",
  "type": "registry:ui",
  "title": "Radio group",
  "description": "Single-choice radio set for plans, filters, and option lists.",
  "dependencies": [
    "@base-ui/react@^1.7.0"
  ],
  "registryDependencies": [
    "https://control-ui.dev/r/core.json"
  ],
  "files": [
    {
      "path": "src/registry/knob-contracts/choice-knobs.ts",
      "target": "@components/control-ui/knob-contracts/choice-knobs.ts",
      "type": "registry:component",
      "content": "// Generated from src/registry/sources/control-ui/recipes/choice.css by scripts/gen-knob-contracts.ts — run `bun run sync:knobs`.\nexport const choiceKnobs = [\n  \"--cui-choice-radius\",\n  \"--cui-choice-border-color\",\n  \"--cui-choice-checked-background\",\n  \"--cui-choice-checked-border-color\",\n] as const;\nexport type ChoiceKnobStyle = Partial<Record<(typeof choiceKnobs)[number], string>>;\n"
    },
    {
      "path": "src/registry/sources/control-ui/recipes/choice.css",
      "target": "@components/control-ui/styles/recipes/choice.css",
      "type": "registry:file",
      "content": "@layer components {\n  :where([data-control-family=\"choice\"][data-choice-kind=\"checkbox\"][data-slot=\"root\"]),\n  :where([data-control-family=\"choice\"][data-choice-kind=\"radio-group\"][data-slot=\"item\"]) {\n    --cui-choice-radius: var(--radius-sm);\n    --cui-choice-border-color: var(--border);\n    --cui-choice-checked-background: var(--primary);\n    --cui-choice-checked-border-color: var(--primary);\n    --_choice-background: oklch(from var(--card) l c h / 0.72);\n    border-radius: var(--cui-choice-radius);\n    background: var(--_choice-background);\n    box-shadow:\n      inset 0 0 0 1px var(--cui-choice-border-color),\n      var(--shadow-sm);\n    color: currentColor;\n    outline: none;\n    transition-property: background-color, box-shadow, color;\n    transition-duration: var(--duration-fast);\n    transition-timing-function: var(--ease-standard);\n  }\n\n  :where([data-control-family=\"choice\"][data-choice-kind=\"radio-group\"][data-slot=\"item\"]) {\n    --cui-choice-radius: 9999px;\n    outline-style: none;\n  }\n\n  :where([data-control-family=\"choice\"][data-choice-kind=\"checkbox\"][data-slot=\"root\"]:hover),\n  :where([data-control-family=\"choice\"][data-choice-kind=\"radio-group\"][data-slot=\"item\"]:hover) {\n    --cui-choice-border-color: oklch(from var(--foreground) l c h / 0.25);\n  }\n\n  :where([data-control-family=\"choice\"][data-choice-kind=\"checkbox\"][data-slot=\"root\"]:is([data-checked], [data-indeterminate])),\n  :where([data-control-family=\"choice\"][data-choice-kind=\"radio-group\"][data-slot=\"item\"]:is([data-checked], [data-indeterminate])) {\n    --_choice-background: var(--cui-choice-checked-background);\n    --cui-choice-border-color: var(--cui-choice-checked-border-color);\n    color: var(--primary-foreground);\n  }\n\n  :where([data-control-family=\"choice\"][data-choice-kind=\"checkbox\"][data-slot=\"root\"][data-disabled]),\n  :where([data-control-family=\"choice\"][data-choice-kind=\"radio-group\"][data-slot=\"item\"][data-disabled]) {\n    opacity: 0.5;\n  }\n\n  :where([data-control-family=\"choice\"][data-choice-kind=\"checkbox\"][data-slot=\"root\"][data-invalid]),\n  :where([data-control-family=\"choice\"][data-choice-kind=\"radio-group\"][data-slot=\"item\"][data-invalid]) {\n    --cui-choice-border-color: var(--destructive);\n    box-shadow:\n      inset 0 0 0 1px var(--cui-choice-border-color),\n      var(--shadow-sm),\n      0 0 0 1px var(--destructive);\n  }\n\n  :where([data-control-family=\"choice\"][data-choice-kind=\"checkbox\"][data-slot=\"root\"] [data-slot=\"indicator\"]),\n  :where([data-control-family=\"choice\"][data-choice-kind=\"radio-group\"][data-slot=\"item\"] [data-slot=\"indicator\"]) {\n    color: currentColor;\n  }\n\n  :where([data-control-family=\"choice\"][data-choice-kind=\"radio-group\"] [data-slot=\"indicator\"]) {\n    border-radius: 9999px;\n    background: var(--primary-foreground);\n  }\n\n  :where([data-control-family=\"choice\"][data-choice-kind=\"checkbox\"][data-slot=\"indicator\"]) {\n    color: currentcolor;\n  }\n\n  :where([data-control-family=\"choice\"][data-choice-kind=\"checkbox\"][data-slot=\"root\"]) {\n    outline-style: none;\n  }\n}\n\n@property --cui-choice-radius {\n  syntax: \"<length-percentage>\";\n  inherits: true;\n  initial-value: 0px;\n}\n\n@property --cui-choice-border-color {\n  syntax: \"<color>\";\n  inherits: true;\n  initial-value: transparent;\n}\n\n@property --cui-choice-checked-background {\n  syntax: \"<color>\";\n  inherits: true;\n  initial-value: transparent;\n}\n\n@property --cui-choice-checked-border-color {\n  syntax: \"<color>\";\n  inherits: true;\n  initial-value: transparent;\n}\n"
    },
    {
      "path": "src/registry/sources/control-ui/ui/radio-group.tsx",
      "target": "@components/control-ui/ui/radio-group.tsx",
      "type": "registry:ui",
      "content": "\"use client\";\n\nimport { Radio as RadioPrimitive } from \"@base-ui/react/radio\";\nimport { RadioGroup as RadioGroupPrimitive } from \"@base-ui/react/radio-group\";\nimport type { ComponentProps, CSSProperties } from \"react\";\nimport type { ControlledChoice } from \"@/components/control-ui/control-props\";\nimport type { ChoiceKnobStyle } from \"@/components/control-ui/knob-contracts/choice-knobs\";\nimport { cn } from \"@/components/control-ui/lib/cn\";\n\nexport type RadioGroupProps<TValue extends string = string> = Omit<ComponentProps<\"div\">, \"defaultValue\" | \"onChange\"> &\n  ControlledChoice<TValue> & {\n    disabled?: boolean;\n    readOnly?: boolean;\n    required?: boolean;\n    name?: string;\n    orientation?: \"horizontal\" | \"vertical\";\n  } & { style?: CSSProperties & ChoiceKnobStyle };\n\nexport type RadioProps = Omit<\n  {\n    value: string;\n    disabled?: boolean;\n    readOnly?: boolean;\n    required?: boolean;\n    id?: string;\n    className?: string;\n    \"aria-label\"?: string;\n    \"aria-labelledby\"?: string;\n  },\n  \"style\"\n> & { style?: CSSProperties & ChoiceKnobStyle };\n\n// `orientation` is visual only — Base UI owns roving focus on both axes and exposes no such prop.\nexport function RadioGroup<TValue extends string = string>({ className, orientation = \"vertical\", ...props }: RadioGroupProps<TValue>) {\n  return (\n    <RadioGroupPrimitive<TValue>\n      data-control-ui=\"radio-group\"\n      data-control-family=\"choice\"\n      data-choice-kind=\"radio-group\"\n      data-slot=\"root\"\n      data-orientation={orientation}\n      className={cn(\n        \"flex gap-2 data-[orientation=horizontal]:flex-row data-[orientation=horizontal]:gap-4 data-[orientation=vertical]:flex-col\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nexport function Radio({ className, disabled, ...props }: RadioProps) {\n  return (\n    <RadioPrimitive.Root\n      data-control-ui=\"radio-group\"\n      data-choice-kind=\"radio-group\"\n      data-slot=\"item\"\n      data-control-family=\"choice\"\n      disabled={disabled}\n      className={cn(\n        \"group/radio relative inline-flex size-4 shrink-0 cursor-pointer items-center justify-center\",\n        \"data-[disabled]:cursor-not-allowed\",\n        className,\n      )}\n      {...props}\n    >\n      <RadioPrimitive.Indicator\n        data-control-ui=\"radio-group\"\n        data-control-family=\"choice\"\n        data-choice-kind=\"radio-group\"\n        data-slot=\"indicator\"\n        className=\"size-1.5 data-[unchecked]:hidden\"\n      />\n    </RadioPrimitive.Root>\n  );\n}\n"
    }
  ],
  "css": {
    "@import \"../components/control-ui/styles/recipes/choice.css\"": {}
  },
  "meta": {}
}
