{"version":3,"file":"Radio.cjs","names":[],"sources":["../../../src/components/Radio/Radio.tsx"],"sourcesContent":["/**\n * @tempest-limits props-count — RadioGroup carries the group semantics (name, value,\n * defaultValue, onChange, disabled) and its layout (horizontal, className,\n * children). The individual Radio is a separate component already — this is the\n * group, and a group needs the group's props.\n */\nimport { createContext, forwardRef, useContext, useId, useState } from \"react\";\nimport type { ChangeEvent, InputHTMLAttributes, ReactNode } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./Radio.module.css\";\n\ninterface RadioGroupContextValue {\n    name: string;\n    value?: string;\n    onChange?: (value: string) => void;\n    disabled?: boolean;\n}\n\nconst RadioGroupContext = createContext<RadioGroupContextValue | null>(null);\n\nexport interface RadioProps extends Omit<InputHTMLAttributes<HTMLInputElement>, \"type\"> {\n    label?: ReactNode;\n    description?: ReactNode;\n    value: string;\n    wrapperClassName?: string;\n}\n\n/**\n * Single radio button. Inside a {@link RadioGroup}, name/checked/onChange are\n * managed by the group; outside, behaves as a regular radio input.\n */\nexport const Radio = forwardRef<HTMLInputElement, RadioProps>(function Radio(\n    {\n        label,\n        description,\n        value,\n        disabled,\n        name,\n        checked,\n        onChange,\n        wrapperClassName,\n        className,\n        ...props\n    },\n    ref,\n) {\n    const group = useContext(RadioGroupContext);\n    const resolvedName = group?.name ?? name;\n    const resolvedDisabled = group?.disabled ?? disabled;\n    const isChecked = group ? group.value === value : checked;\n\n    function handleChange(event: ChangeEvent<HTMLInputElement>): void {\n        if (group) group.onChange?.(value);\n        onChange?.(event);\n    }\n\n    return (\n        <label\n            className={cn(styles.wrapper, resolvedDisabled && styles.disabled, wrapperClassName)}\n        >\n            <input\n                ref={ref}\n                type=\"radio\"\n                name={resolvedName}\n                value={value}\n                checked={isChecked}\n                disabled={resolvedDisabled}\n                onChange={handleChange}\n                className={cn(styles.input, className)}\n                {...props}\n            />\n            <span className={styles.dot} aria-hidden />\n            {(label || description) && (\n                <span className={styles.labelWrap}>\n                    {label && <span className={styles.label}>{label}</span>}\n                    {description && <span className={styles.description}>{description}</span>}\n                </span>\n            )}\n        </label>\n    );\n});\n\nexport interface RadioGroupProps {\n    /** Selected value (controlled). */\n    value?: string;\n    /** Default selected value (uncontrolled). */\n    defaultValue?: string;\n    /** Called when the selection changes. */\n    onChange?: (value: string) => void;\n    /** `name` attribute applied to every Radio inside. Auto-generated if omitted. */\n    name?: string;\n    /** Disable every Radio inside. */\n    disabled?: boolean;\n    /** Lay out radios horizontally. Default: false (column). */\n    horizontal?: boolean;\n    className?: string;\n    children: ReactNode;\n}\n\n/**\n * Wraps multiple {@link Radio} children and coordinates selection via context.\n * Pass `value` for controlled mode or `defaultValue` for uncontrolled.\n */\nexport function RadioGroup({\n    value,\n    defaultValue,\n    onChange,\n    name,\n    disabled,\n    horizontal = false,\n    className,\n    children,\n}: RadioGroupProps) {\n    const generatedName = useId();\n    const resolvedName = name ?? generatedName;\n\n    const [internal, setInternal] = useState<string | undefined>(defaultValue);\n    const isControlled = value !== undefined;\n    const current = isControlled ? value : internal;\n\n    function handleChange(next: string): void {\n        if (!isControlled) setInternal(next);\n        onChange?.(next);\n    }\n\n    return (\n        <RadioGroupContext.Provider\n            value={{ name: resolvedName, value: current, onChange: handleChange, disabled }}\n        >\n            <div\n                role=\"radiogroup\"\n                className={cn(styles.group, horizontal && styles.horizontal, className)}\n            >\n                {children}\n            </div>\n        </RadioGroupContext.Provider>\n    );\n}\n"],"mappings":"4HAkBA,IAAM,GAAA,EAAoB,EAAA,cAAA,CAA6C,IAAI,EAa9D,GAAA,EAAQ,EAAA,WAAA,CAAyC,SAC1D,CACI,QACA,cACA,QACA,WACA,OACA,UACA,WACA,mBACA,YACA,GAAG,GAEP,EACF,CACE,IAAM,GAAA,EAAQ,EAAA,WAAA,CAAW,CAAiB,EACpC,EAAe,GAAO,MAAQ,EAC9B,EAAmB,GAAO,UAAY,EACtC,EAAY,EAAQ,EAAM,QAAU,EAAQ,EAElD,SAAS,EAAa,EAA4C,CAC1D,GAAO,EAAM,WAAW,CAAK,EACjC,IAAW,CAAK,CACpB,CAEA,OACI,EAAA,EAAA,KAAA,CAAC,QAAD,CACI,UAAW,EAAA,GAAG,EAAA,QAAO,QAAS,GAAoB,EAAA,QAAO,SAAU,CAAgB,EADvF,SAAA,EAGI,EAAA,EAAA,IAAA,CAAC,QAAD,CACS,MACL,KAAK,QACL,KAAM,EACC,QACP,QAAS,EACT,SAAU,EACV,SAAU,EACV,UAAW,EAAA,GAAG,EAAA,QAAO,MAAO,CAAS,EACrC,GAAI,CACP,CAAA,GACD,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAA,QAAO,IAAK,cAAA,EAAa,CAAA,GACxC,GAAS,KACP,EAAA,EAAA,KAAA,CAAC,OAAD,CAAM,UAAW,EAAA,QAAO,UAAxB,SAAA,CACK,IAAS,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAA,QAAO,MAAQ,SAAA,CAAY,CAAA,EACrD,IAAe,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAA,QAAO,YAAc,SAAA,CAAkB,CAAA,CACtE,GAEP,GAEf,CAAC,EAuBD,SAAgB,EAAW,CACvB,QACA,eACA,WACA,OACA,WACA,aAAa,GACb,YACA,YACgB,CAChB,IAAM,GAAA,EAAgB,EAAA,MAAA,CAAM,EACtB,EAAe,GAAQ,EAEvB,CAAC,EAAU,IAAA,EAAe,EAAA,SAAA,CAA6B,CAAY,EACnE,EAAe,IAAU,IAAA,GACzB,EAAU,EAAe,EAAQ,EAEvC,SAAS,EAAa,EAAoB,CACjC,GAAc,EAAY,CAAI,EACnC,IAAW,CAAI,CACnB,CAEA,OACI,EAAA,EAAA,IAAA,CAAC,EAAkB,SAAnB,CACI,MAAO,CAAE,KAAM,EAAc,MAAO,EAAS,SAAU,EAAc,UAAS,EAE9E,UAAA,EAAA,EAAA,IAAA,CAAC,MAAD,CACI,KAAK,aACL,UAAW,EAAA,GAAG,EAAA,QAAO,MAAO,GAAc,EAAA,QAAO,WAAY,CAAS,EAErE,UACA,CAAA,CACmB,CAAA,CAEpC"}