import React, { FunctionComponent, MouseEventHandler, useContext, useEffect, useState, } from 'react' import { CheckChecked, CheckNormal } from '@nutui/icons-react-taro' import RadioContext from './context' import RadioGroup from '@/packages/radiogroup/index.taro' import { BasicComponent, ComponentDefaults } from '@/utils/typings' type Shape = 'button' | 'round' type Position = 'right' | 'left' export interface RadioProps extends BasicComponent { className: string style: React.CSSProperties disabled: boolean checked: boolean shape: Shape textPosition: Position value: string | number | boolean iconName: React.ReactNode iconActiveName: React.ReactNode iconSize: string | number onChange: MouseEventHandler } const defaultProps = { ...ComponentDefaults, className: '', style: {}, disabled: false, checked: false, shape: 'round', value: '', textPosition: 'right', iconName: 'check-normal', iconActiveName: 'check-checked', iconSize: 18, onChange: (e) => {}, } as RadioProps export const Radio: FunctionComponent< Partial & React.HTMLAttributes > & { RadioGroup: typeof RadioGroup } = (props) => { const { children } = { ...defaultProps, ...props, } const { className, disabled, checked, shape, textPosition, value, iconName, iconActiveName, iconSize, onChange, iconClassPrefix, iconFontClassName, ...rest } = props const componentName = 'nut-radio' const [checkedStatement, setCheckedStatement] = useState(checked) const [valueStatement, setValueStatement] = useState(value) const [disabledStatement, setDisabledStatement] = useState(disabled) const context = useContext(RadioContext) useEffect(() => { setDisabledStatement(disabled) setValueStatement(value) setCheckedStatement(checked) }, [disabled, value, checked]) const renderLabel = () => { return (
{children}
) } const renderButton = () => { return (
{children}
) } const color = () => { if (disabledStatement) { return 'nut-radio__icon--disable' } if (checkedStatement) { return 'nut-radio__icon' } return 'nut-radio__icon--unchecked' } const renderIcon = () => { const { iconName, iconSize, iconActiveName } = props if (!disabledStatement && checkedStatement) { return React.isValidElement(iconActiveName) ? ( React.cloneElement(iconActiveName, { size: iconSize, className: color(), }) ) : ( ) } return React.isValidElement(iconName) ? ( React.cloneElement(iconName, { size: iconSize, className: color(), }) ) : ( ) } const reverseState = textPosition === 'left' const renderRadioItem = () => { if (shape === 'button') { return renderButton() } if (reverseState) { return [renderLabel(), renderIcon()] } return [renderIcon(), renderLabel()] } const handleClick: MouseEventHandler = (e) => { if (disabledStatement || checkedStatement) return setCheckedStatement(!checkedStatement) onChange && onChange(e) context && context.onChange(valueStatement) } return (
{renderRadioItem()}
) } Radio.defaultProps = defaultProps Radio.displayName = 'NutRadio' Radio.RadioGroup = RadioGroup