import React, { useEffect, useMemo, useState } from 'react' import useTheme from '../use-theme' import { useRadioContext } from './radio-context' import RadioGroup, { getRadioSize } from './radio-group' import RadioDescription from './radio-description' import { pickChild } from '../utils/collections' import logWarning from '../utils/use-warning' import { NormalSizes } from '../utils/prop-types' interface RadioEventTarget { checked: boolean } export interface RadioEvent { target: RadioEventTarget stopPropagation: () => void preventDefault: () => void nativeEvent: React.ChangeEvent } interface Props { checked?: boolean value?: string | number size?: NormalSizes className?: string disabled?: boolean onChange?: (e: RadioEvent) => void } const defaultProps = { size: 'medium' as NormalSizes, disabled: false, className: '' } type NativeAttrs = Omit, keyof Props> export type RadioProps = Props & typeof defaultProps & NativeAttrs const Radio: React.FC> = ({ className, checked, onChange, disabled, size, value: radioValue, children, ...props }) => { const theme = useTheme() const [selfChecked, setSelfChecked] = useState(!!checked) const { value: groupValue, disabledAll, inGroup, updateState } = useRadioContext() const [withoutDescChildren, DescChildren] = pickChild(children, RadioDescription) if (inGroup) { if (checked !== undefined) { logWarning('Remove props "checked" if in the Radio.Group.', 'Radio') } if (radioValue === undefined) { logWarning('Props "value" must be deinfed if in the Radio.Group.', 'Radio') } // eslint-disable-next-line react-hooks/rules-of-hooks useEffect(() => { setSelfChecked(groupValue === radioValue) }, [groupValue, radioValue]) } const fontSize = useMemo(() => getRadioSize(size), [size]) const isDisabled = useMemo(() => disabled || disabledAll, [disabled, disabledAll]) const changeHandler = (event: React.ChangeEvent) => { if (isDisabled) return const selfEvent: RadioEvent = { target: { checked: !selfChecked }, stopPropagation: event.stopPropagation, preventDefault: event.preventDefault, nativeEvent: event } setSelfChecked(!selfChecked) if (inGroup) { updateState && updateState(radioValue as string | number) } onChange && onChange(selfEvent) } useEffect(() => { if (checked === undefined) return setSelfChecked(Boolean(checked)) }, [checked]) return (
) } type RadioComponent

= React.FC

& { Group: typeof RadioGroup Desc: typeof RadioDescription Description: typeof RadioDescription } type ComponentProps = Partial & Omit & NativeAttrs Radio.defaultProps = defaultProps export default Radio as RadioComponent