import React, { forwardRef, createContext, useContext, Children, cloneElement, isValidElement, useId } from 'react' /** * RadioGroup context value */ interface RadioGroupContextValue { name?: string value?: string onChange?: (event: React.ChangeEvent) => void } const RadioGroupContext = createContext({}) /** * Hook to access RadioGroup context */ export const useRadioGroup = () => useContext(RadioGroupContext) /** * Props for RadioGroup component */ export interface RadioGroupProps extends Omit, 'onChange'> { children?: React.ReactNode /** Name attribute for all radio buttons */ name?: string /** Currently selected value */ value?: string /** Default value for uncontrolled usage */ defaultValue?: string /** Called when selection changes */ onChange?: (event: React.ChangeEvent) => void /** Stack radio buttons horizontally */ row?: boolean } /** * RadioGroup - Groups Radio buttons with shared name and selection state * * @example * ```tsx * * * * * * ``` */ export const RadioGroup = forwardRef( ( { children, name: nameProp, value, defaultValue, onChange, row = false, className = '', ...props }, ref ) => { const generatedName = useId() const name = nameProp ?? generatedName // Enhance child Radio components with group context const enhancedChildren = Children.map(children, (child) => { if (isValidElement(child)) { const childValue = (child.props as Record).value as string | undefined return cloneElement(child as React.ReactElement>, { name, checked: value !== undefined ? childValue === value : undefined, defaultChecked: defaultValue !== undefined ? childValue === defaultValue : undefined, onChange, }) } return child }) return (
{enhancedChildren}
) } ) RadioGroup.displayName = 'RadioGroup'