{
  "name": "radio-group",
  "type": "registry:ui",
  "title": "Radio Group",
  "description": "Single-select controls for choosing exactly one option from a short visible list.",
  "registryDependencies": [
    "@siteplane/base"
  ],
  "dependencies": [
    "@base-ui/react@1.5.0",
    "class-variance-authority@0.7.1"
  ],
  "files": [
    {
      "path": "src/components/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 { cva, type VariantProps } from \"class-variance-authority\";\nimport type React from \"react\";\nimport { createContext, useContext } from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport {\n  type SiteplaneControlSize,\n  useResolvedControlSize,\n} from \"@/components/ui/siteplane-provider\";\n\nexport const radioVariants = cva(\n  \"siteplane-radio-motion relative inline-flex shrink-0 cursor-pointer items-center justify-center rounded-(--checkbox-radius) border border-input bg-background not-dark:bg-clip-padding shadow-xs/5 outline-none transition-shadow before:pointer-events-none before:absolute before:inset-0 before:rounded-[inherit] not-data-disabled:not-data-checked:not-aria-invalid:before:shadow-[0_1px_--theme(--color-black/4%)] focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background aria-invalid:border-destructive/36 focus-visible:aria-invalid:border-destructive/64 focus-visible:aria-invalid:ring-destructive/48 data-disabled:cursor-not-allowed data-disabled:opacity-64 dark:not-data-checked:bg-input/32 dark:aria-invalid:ring-destructive/24 dark:not-data-disabled:not-data-checked:not-aria-invalid:before:shadow-[0_-1px_--theme(--color-white/6%)] [[data-disabled],[data-checked],[aria-invalid]]:shadow-none\",\n  {\n    defaultVariants: {\n      size: \"default\",\n    },\n    variants: {\n      size: {\n        default: \"size-4.5 sm:size-4\",\n        lg: \"size-5 sm:size-4.5\",\n        sm: \"size-4 sm:size-3.5\",\n        xl: \"size-5.5 sm:size-5\",\n      },\n    },\n  },\n);\n\nconst radioIndicatorVariants = cva(\n  \"absolute -inset-px flex items-center justify-center rounded-(--checkbox-radius) before:rounded-[calc(var(--checkbox-radius)*0.5)] before:bg-primary-foreground\",\n  {\n    defaultVariants: {\n      size: \"default\",\n    },\n    variants: {\n      size: {\n        default: \"size-4.5 before:size-2 sm:size-4 sm:before:size-1.5\",\n        lg: \"size-5 before:size-2.5 sm:size-4.5 sm:before:size-2\",\n        sm: \"size-4 before:size-1.5 sm:size-3.5 sm:before:size-1.5\",\n        xl: \"size-5.5 before:size-3 sm:size-5 sm:before:size-2.5\",\n      },\n    },\n  },\n);\n\nconst RadioSizeContext = createContext<SiteplaneControlSize | null>(null);\n\nexport interface RadioGroupProps\n  extends Omit<RadioGroupPrimitive.Props, \"size\"> {\n  size?: SiteplaneControlSize;\n}\n\nexport function RadioGroup({\n  className,\n  size,\n  ...props\n}: RadioGroupProps): React.ReactElement {\n  const resolvedSize = useResolvedControlSize(size);\n\n  return (\n    <RadioSizeContext.Provider value={resolvedSize}>\n      <RadioGroupPrimitive\n        className={cn(\"flex flex-col gap-3\", className)}\n        data-size={resolvedSize}\n        data-slot=\"radio-group\"\n        {...props}\n      />\n    </RadioSizeContext.Provider>\n  );\n}\n\nexport interface RadioProps\n  extends Omit<RadioPrimitive.Root.Props, \"size\">,\n    VariantProps<typeof radioVariants> {}\n\nexport function Radio({\n  className,\n  size,\n  ...props\n}: RadioProps): React.ReactElement {\n  const groupSize = useContext(RadioSizeContext);\n  const resolvedSize = useResolvedControlSize(size ?? groupSize);\n\n  return (\n    <RadioPrimitive.Root\n      className={cn(radioVariants({ size: resolvedSize }), className)}\n      data-size={resolvedSize}\n      data-slot=\"radio\"\n      {...props}\n    >\n      <RadioPrimitive.Indicator\n        className={radioIndicatorVariants({ size: resolvedSize })}\n        data-slot=\"radio-indicator\"\n        keepMounted\n      />\n    </RadioPrimitive.Root>\n  );\n}\n\nexport { RadioGroupPrimitive, RadioPrimitive };\n"
    }
  ],
  "categories": [
    "form-controls"
  ],
  "docs": "# Radio Group\n\n> Siteplane UI release `0.1.1`.\n\n## Public Purpose\n\nUse Radio Group when exactly one option must be selected from a short, visible set.\n\n## Import\n\n`import { Radio, RadioGroup } from \"@/components/ui/radio-group\";`\n\n`import { Field, FieldDescription, FieldError, FieldLabel } from \"@/components/ui/field\";`\n\n`import { Form } from \"@/components/ui/form\";`\n\n`import { Button } from \"@/components/ui/button\";`\n\n`import { Label } from \"@/components/ui/label\";`\n\n## Public API\n\n- `RadioGroup` accepts the Base UI group props, controlled or uncontrolled value, `disabled`, `readOnly` and `size=\"sm\" | \"default\" | \"lg\" | \"xl\"`.\n- Each `Radio` requires a unique `value` and can override `disabled`, `readOnly` and inherited size.\n- `disabled` on the group disables every option; use item-level `disabled` only when individual choices are unavailable.\n- `readOnly` prevents changes without applying disabled styling, so accompany it with clear context when the state might otherwise look editable.\n\n## Public Motion\n\n- Selection updates the native indicator, border and focus styles without changing layout dimensions.\n- Radio Group adds no group-level enter or exit animation. System and provider reduced-motion modes move the indicator directly to its final state instead of interpolating its fade and scale.\n\n## Public Accessibility\n\n- Give every group an accessible name through `aria-label` or `aria-labelledby`.\n- Couple visible option labels to their Radio controls and give standalone controls an explicit label.\n- Pair invalid state with visible error text; disabled and read-only state must be understandable without relying on color alone.\n\n## Public Agent Guidance\n\n- Use Checkbox Group for multiple selection and Select when the option set should remain collapsed.\n- Prefer group-level `disabled` when the complete choice is unavailable.\n- Do not build raw radio inputs outside the Radio Group contract.\n\n## Public Links\n\n- [Documentation and preview](https://ui.siteplane.io/docs/components/form-controls/radio-group)\n\n- [Registry source](https://ui.siteplane.io/r/radio-group.json)\n",
  "meta": {
    "siteplane:agentContractVersion": 1,
    "siteplane:docs": "https://ui.siteplane.io/docs/components/form-controls/radio-group",
    "siteplane:releaseVersion": "0.1.1",
    "siteplane:sourceOwned": true
  },
  "devDependencies": []
}
