/// /** * RadioGroup Component - Lynx 版 MUI RadioGroup * 100% 一比一复刻 MUI RadioGroup * * 管理 Radio 组件的互斥选择 * * 对应 MUI: packages/mui-material/src/RadioGroup/RadioGroup.js */ import './RadioGroup.css' import radioGroupClasses, { getRadioGroupUtilityClass } from './radioGroupClasses' export { radioGroupClasses, getRadioGroupUtilityClass } // ============================================= // 类型定义 // ============================================= export interface RadioGroupProps { /** 子元素 */ children?: any /** 自定义类名 */ className?: string /** 样式类覆盖 */ classes?: Partial /** 默认值 */ defaultValue?: string /** 是否错误状态 */ error?: boolean /** 名称属性 */ name?: string /** 值变化回调 */ onChange?: (event: any, value: string) => void /** 行排列 */ row?: boolean /** 内联样式 */ style?: Record /** sx 属性 */ sx?: Record /** 当前值 */ value?: string } // ============================================= // 辅助函数 // ============================================= function composeClasses( slots: Record, getUtilityClass: (slot: string) => string, classes?: Record ): Record { const output: Record = {} Object.keys(slots).forEach((slot) => { output[slot] = slots[slot] .filter(Boolean) .map((key) => { if (classes && classes[key as string]) { return `${getUtilityClass(key as string)} ${classes[key as string]}` } return getUtilityClass(key as string) }) .join(' ') }) return output } // ============================================= // useUtilityClasses // ============================================= interface OwnerState extends RadioGroupProps {} function useUtilityClasses(ownerState: OwnerState) { const { classes, error, row } = ownerState const slots = { root: [ 'root', error && 'error', row && 'row', ], } return composeClasses(slots, getRadioGroupUtilityClass, classes) } // ============================================= // RadioGroup 组件 // ============================================= export function RadioGroup(props: RadioGroupProps) { const { children, className, classes: classesProp, defaultValue, error = false, name, onChange, row = false, style, sx, value: valueProp, ...other } = props // 在 Lynx 环境下,组件必须是受控的 // 如果没有提供 value 属性,使用默认值 const value = valueProp !== undefined ? valueProp : defaultValue const ownerState: OwnerState = { ...props, error, row, } const classes = useUtilityClasses(ownerState) // 处理 Radio 变化 const handleRadioChange = (event: any, radioValue: string) => { if (onChange) { onChange(event, radioValue) } } // 在 Lynx 环境下,不进行子组件克隆 // 开发者需要手动管理 Radio 的 checked 状态 const enhancedChildren = children // 构建类名 const rootClasses = [ classes.root, radioGroupClasses.root, className, error && 'MuiRadioGroup-error', row && 'MuiRadioGroup-row', ].filter(Boolean).join(' ') return ( {enhancedChildren} ) } export default RadioGroup