import classNames from 'classnames' ; import type { ChangeEvent , ReactNode } from 'react' ; import { createContext , useCallback , useContext , useState } from 'react' ; import { Button } from '../Button' ; interface RadioContextType { readonly name : string ; readonly value ? : string ; readonly setValue : ( name : string ) => void ; } const RadioContext = createContext < RadioContextType > ( { name : 'unknown' , value : 'unknown' , setValue : ( _name ) : void => { } , } ) ; export interface RadioItemProps { readonly label : string ; readonly value : string ; } const RadioItem = ( props ) : JSX . Element => { const { label , value : boundedValue } = props ; const { name , value , setValue } = useContext ( RadioContext ) ; const checked = boundedValue === value ; const handleChange = useCallback ( ( e ) => { setValue ( e . target . value ) ; } , [ setValue ] ) ; return ( < Button as = "label" variant = { checked ? 'secondary' : 'wash' } shape = "circle" size = "sm" className = "shrink-0" > { label } < input type = "radio" name = { name } value = { boundedValue } checked = { checked } className = "sr-only" onChange = { handleChange } / > < /Button>); } ; export interface RadioProps { readonly name : string ; readonly value ? : string ; readonly children : ReactNode ; readonly className ? : string ; readonly onChange ? : ( value : string ) => void ; } export const Radio = ( props ) : JSX . Element => { const { children , name , className , onChange } = props ; const [ value , setValue ] = useState < string | undefined > ( props . value ) ; const handleChange = ( newValue ) : void => { setValue ( newValue ) ; onChange ?. ( newValue ) ; } ; return ( < RadioContext . Provider value = { { name , value , setValue : handleChange , } } > < div className = { classNames ( 'space-x-2' , 'flex' , 'flex-nowrap' , className ) } > { children } < /div> < /RadioContext.Provider>); } ; Radio . Item = RadioItem ;