///
/**
* 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