{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "dependencies": [
    "@base-ui/react@1.8.0"
  ],
  "description": "A radio group with a springy dot and keyboard-driven selection.",
  "docs": "Two steps after installing: import the copied stylesheet once at your app entry — it lands at `styles/liquefy-ui.css` — or `@import` it from your global CSS *before* `tailwindcss`, so Tailwind utilities keep winning over component styles. Then wrap the tree in `<LiquefyProvider>`, which is where every component reads its tokens from. Every copied file already carries its own 'use client' directive. Full documentation: https://liquefy-ui.com/#/docs/installation",
  "files": [
    {
      "content": "'use client'\n\nimport { Radio } from '@base-ui/react/radio'\nimport { RadioGroup } from '@base-ui/react/radio-group'\nimport { forwardRef, type ButtonHTMLAttributes, type HTMLAttributes, type ReactNode } from 'react'\nimport { useLiquefyConfig } from '@/lib/provider'\nimport { useLiquidStyles, type LiquidStyleProps } from '@/lib/styles-prop'\nimport { useLiquidGlass } from '@/hooks/use-liquid-glass'\n\n// The group used to be a div of buttons sharing a context, which meant Tab\n// stopped on every option and the arrow keys did nothing at all — the two\n// things a radio group is specified to do. Base UI brings roving focus, the\n// arrow keys, and a hidden input per option so the group submits with a form.\n\nexport type LiquidRadioGroupProps = Omit<HTMLAttributes<HTMLDivElement>, 'defaultValue' | 'onChange'> & LiquidStyleProps & {\n  children: ReactNode\n  defaultValue?: string\n  disabled?: boolean\n  label?: string\n  name?: string\n  onValueChange?: (value: string) => void\n  orientation?: 'horizontal' | 'vertical'\n  value?: string\n}\n\nexport const LiquidRadioGroup = forwardRef<HTMLDivElement, LiquidRadioGroupProps>(({\n  children,\n  className,\n  defaultValue,\n  disabled,\n  label,\n  name = 'lq-radio-group',\n  onValueChange,\n  orientation = 'vertical',\n  style,\n  styles,\n  value,\n  ...props\n}, ref) => {\n  const root = useLiquidStyles('lq-radio-group', { className, style, styles })\n\n  return (\n    <RadioGroup\n      aria-label={label}\n      className={root.className}\n      data-orientation={orientation}\n      defaultValue={defaultValue}\n      disabled={disabled}\n      name={name}\n      onValueChange={(nextValue) => onValueChange?.(String(nextValue))}\n      ref={ref}\n      style={root.style}\n      value={value}\n      {...props}\n    >\n      {children}\n    </RadioGroup>\n  )\n})\n\nLiquidRadioGroup.displayName = 'LiquidRadioGroup'\n\nexport type LiquidRadioProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'value'> & LiquidStyleProps & {\n  hint?: string\n  label?: ReactNode\n  value: string\n}\n\nexport const LiquidRadio = forwardRef<HTMLButtonElement, LiquidRadioProps>(({\n  className,\n  disabled,\n  hint,\n  label,\n  style,\n  styles,\n  value,\n  ...props\n}, forwardedRef) => {\n  const config = useLiquefyConfig()\n  const [elementRef, canvasRef] = useLiquidGlass<HTMLButtonElement>(forwardedRef, {\n    bounce: 0.08,\n    disabled,\n    glow: config.glow,\n    intensity: config.intensity,\n    lens: config.lens && config.transparency,\n    lensStrength: config.refraction,\n    motion: config.motion,\n    ripple: config.ripple,\n    shimmer: config.shimmer,\n    sparkle: config.sparkle,\n    tilt: 0,\n    tint: config.tint,\n    webgl: config.webgl,\n    wobbliness: config.wobbliness,\n  })\n  // The label is the layout box, so it owns className, style and styles alike.\n  const root = useLiquidStyles('lq-radio', { className, style, styles })\n\n  return (\n    <label className={root.className} data-disabled={disabled || undefined} style={root.style}>\n      <Radio.Root\n        className=\"lq-radio__control\"\n        disabled={disabled}\n        nativeButton\n        ref={elementRef}\n        render={<button type=\"button\" />}\n        // `render` swaps the span Base UI would have made for a button, but the\n        // prop types still describe the span. The cast is that swap, written down.\n        {...(props as Radio.Root.Props)}\n        value={value}\n      >\n        {config.webgl && <canvas aria-hidden=\"true\" className=\"lq-surface__shader\" ref={canvasRef} />}\n        {/* The dot scales in from nothing, so it has to be there to scale. */}\n        <Radio.Indicator className=\"lq-radio__dot\" keepMounted />\n      </Radio.Root>\n      {(label || hint) && (\n        <span className=\"lq-radio__copy\">\n          {label && <span className=\"lq-control-label\">{label}</span>}\n          {hint && <span className=\"lq-control-hint\">{hint}</span>}\n        </span>\n      )}\n    </label>\n  )\n})\n\nLiquidRadio.displayName = 'LiquidRadio'\n",
      "path": "registry/liquid-radio.tsx",
      "type": "registry:ui"
    }
  ],
  "name": "liquid-radio",
  "registryDependencies": [
    "https://liquefy-ui.com/r/liquefy-ui.json",
    "https://liquefy-ui.com/r/provider.json",
    "https://liquefy-ui.com/r/styles-prop.json",
    "https://liquefy-ui.com/r/use-liquid-glass.json"
  ],
  "title": "LiquidRadioGroup",
  "type": "registry:ui"
}
