/// /** * FormHelperText Component - Lynx 版 MUI FormHelperText * 100% 一比一复刻 MUI FormHelperText * * 显示表单帮助文本,支持错误、禁用等状态 * * 对应 MUI: packages/mui-material/src/FormHelperText/FormHelperText.js */ import './FormHelperText.css' import formHelperTextClasses, { getFormHelperTextUtilityClass } from './formHelperTextClasses' import { useFormControl, formControlState } from '../FormControl' export { formHelperTextClasses, getFormHelperTextUtilityClass } // ============================================= // 类型定义 // ============================================= export interface FormHelperTextProps { /** 子元素 */ children?: any /** 自定义类名 */ className?: string /** 样式类覆盖 */ classes?: Partial /** 是否禁用 */ disabled?: boolean /** 是否错误状态 */ error?: boolean /** 是否填充状态 */ filled?: boolean /** 是否聚焦 */ focused?: boolean /** 边距 */ margin?: 'dense' /** 是否必填 */ required?: boolean /** 内联样式 */ style?: Record /** sx 属性 */ sx?: Record /** 变体 */ variant?: 'standard' | 'outlined' | 'filled' } // ============================================= // 辅助函数 // ============================================= function capitalize(str: string): string { return str.charAt(0).toUpperCase() + str.slice(1) } 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 FormHelperTextProps { contained?: boolean size?: string } function useUtilityClasses(ownerState: OwnerState) { const { classes, disabled, error, filled, focused, size, contained, required } = ownerState const slots = { root: [ 'root', disabled && 'disabled', error && 'error', size && `size${capitalize(size)}`, contained && 'contained', focused && 'focused', filled && 'filled', required && 'required', ], } return composeClasses(slots, getFormHelperTextUtilityClass, classes) } // ============================================= // FormHelperText 组件 // ============================================= export function FormHelperText(props: FormHelperTextProps) { const { children, className, classes: classesProp, disabled, error, filled, focused, margin, required, style, sx, variant, ...other } = props const muiFormControl = useFormControl() const fcs = formControlState({ props, muiFormControl, states: ['variant', 'size', 'disabled', 'error', 'filled', 'focused', 'required'], }) const ownerState: OwnerState = { ...props, disabled: fcs.disabled, error: fcs.error, filled: fcs.filled, focused: fcs.focused, required: fcs.required, size: fcs.size, variant: fcs.variant || 'standard', contained: fcs.variant === 'filled' || fcs.variant === 'outlined', } const classes = useUtilityClasses(ownerState) // 构建类名 const rootClasses = [ classes.root, className, fcs.disabled && 'Mui-disabled', fcs.error && 'Mui-error', fcs.focused && 'Mui-focused', fcs.required && 'Mui-required', ].filter(Boolean).join(' ') // 处理空格占位符 let content = children if (children === ' ') { content = } return ( {content} ) } export default FormHelperText