import { CSSProperties, ReactNode, useContext, useState, useEffect, } from 'react' import classNames from 'classnames' import { RadioGroup, RadioGroupContext } from './RadioGroup' import { CommonComponentProps } from '../../utils/types' import { Icon } from '../icon/Icon' import './Radio.scss' export * from './RadioGroup' export interface RadioProps extends CommonComponentProps { className?: string style?: CSSProperties children?: ReactNode checked?: boolean defaultChecked?: boolean value?: any disabled?: boolean size?: string type?: 'record' | 'check' icon?: (checked: boolean) => ReactNode checkedColor?: string onChange?: (checked: boolean, value: any) => any onClick?: () => any } const typeIconMap = { record: ['circle', 'record-circle'], check: ['circle', 'check-circle-fill'], } export function Radio(props: RadioProps) { const { className, children, checked, defaultChecked, value = '', disabled = false, size = '', type = 'record', onChange, onClick, icon, checkedColor, ...restProps } = props const context = useContext(RadioGroupContext) const [innerChecked, setInnerChecked] = useState( checked ?? defaultChecked ?? false ) // 受控 useEffect(() => { if (checked != null) { setInnerChecked(checked) } }, [checked]) const isChecked = context ? context.value === value : innerChecked === true const toggle = () => { if (isChecked) { return } if (context) { onChange?.(true, value) context.onChange(value) } else { // 非受控 if (checked == null) { setInnerChecked(true) } onChange?.(true, value) } } const handleRadioClick = () => { if (!disabled) { toggle() } onClick?.() } const iconStyle = { fontSize: size, color: isChecked ? checkedColor : '', } const radioClass = classNames( 's-radio', { 's-radio-checked': isChecked, 's-radio-disabled': disabled, }, className ) return (