import { ReactNode, useCallback, useRef } from 'react'; import { IRadioContext } from './GroupContext'; import { IDisabledContext } from '../disabled'; export interface IRadioEvent extends Omit, 'target'> { target: { type: 'radio'; checked: boolean; } & IRadioProps; } export interface IRadioProps { value?: Value; disabled?: boolean; readOnly?: boolean; width?: number | string; className?: string; checked?: boolean; onChange?: (e: IRadioEvent) => void; style?: React.CSSProperties; children?: ReactNode; onMouseEnter?: React.MouseEventHandler; onMouseLeave?: React.MouseEventHandler; } function makeEvent( event: React.ChangeEvent, props: IRadioProps ) { const e: IRadioEvent = Object.create(event); e.target = { ...props, type: 'radio', checked: event.target.checked, }; return e; } export function useRadioHandler( ctx: IRadioContext | null, props: IRadioProps ) { const propsRef = useRef(props); propsRef.current = props; const cxOnChange = ctx && ctx.onRadioChange; return useCallback( event => { const e = makeEvent(event, propsRef.current); if (cxOnChange) { cxOnChange(e); } else { const { onChange } = propsRef.current; onChange && onChange(e); } }, [cxOnChange] ); } function getDisabled( disabledCtx: IDisabledContext, groupCtx: IRadioContext | null, props: IRadioProps ): boolean { if (typeof props.disabled === 'boolean') { return props.disabled; } if (groupCtx && typeof groupCtx.disabled === 'boolean') { return groupCtx.disabled; } return disabledCtx.value; } function getReadOnly( groupCtx: IRadioContext | null, props: IRadioProps ): boolean { if (typeof props.readOnly === 'boolean') { return props.readOnly; } if (groupCtx) { return groupCtx.readOnly; } return false; } export function getRadioState( disabledCtx: IDisabledContext, groupCtx: IRadioContext | null, props: IRadioProps ) { const disabled = getDisabled(disabledCtx, groupCtx, props); const readOnly = getReadOnly(groupCtx, props); let checked: boolean; if (groupCtx) { checked = groupCtx.isValueEqual(groupCtx.value, props.value); } else { checked = !!props.checked; } return { checked, disabled, readOnly, }; }