/// /** * TextField Component - Lynx 版 MUI TextField * 100% 一比一复刻 MUI TextField * * TextField 是一个便捷的包装器组件,集成了: * - FormControl * - InputLabel * - Input / OutlinedInput / FilledInput * - FormHelperText * * 对应 MUI: packages/mui-material/src/TextField/TextField.js */ import './TextField.css' import { Input, InputProps } from '../Input' import { InputBase, InputBaseProps } from '../InputBase' // ============================================= // 类名定义 // ============================================= export interface TextFieldClasses { root: string } export function getTextFieldUtilityClass(slot: string): string { return `MuiTextField-${slot}` } export const textFieldClasses: TextFieldClasses = { root: 'MuiTextField-root', } // ============================================= // 类型定义 // ============================================= export type TextFieldVariant = 'filled' | 'outlined' | 'standard' export type TextFieldColor = 'primary' | 'secondary' | 'error' | 'info' | 'success' | 'warning' export type TextFieldSize = 'small' | 'medium' export type TextFieldMargin = 'dense' | 'normal' | 'none' export interface TextFieldProps { /** 自动完成 */ autoComplete?: string /** 自动聚焦 */ autoFocus?: boolean /** 子元素 (用于 select) */ children?: any /** 自定义类名 */ className?: string /** 颜色 */ color?: TextFieldColor /** 默认值 */ defaultValue?: any /** 是否禁用 */ disabled?: boolean /** 是否错误状态 */ error?: boolean /** 是否全宽 */ fullWidth?: boolean /** 帮助文本 */ helperText?: any /** ID */ id?: string /** 输入属性 */ inputProps?: Record /** 输入引用 */ inputRef?: any /** 标签 */ label?: any /** 边距 */ margin?: TextFieldMargin /** 最大行数 */ maxRows?: number /** 最小行数 */ minRows?: number /** 是否多行 */ multiline?: boolean /** 名称 */ name?: string /** 失焦事件 */ onBlur?: (event?: any) => void /** 值变化事件 */ onChange?: (event?: any) => void /** 聚焦事件 */ onFocus?: (event?: any) => void /** 占位符 */ placeholder?: string /** 是否必填 */ required?: boolean /** 行数 */ rows?: number /** 是否为 select */ select?: boolean /** 尺寸 */ size?: TextFieldSize /** 内联样式 */ style?: Record /** sx 属性 */ sx?: Record /** 输入类型 */ type?: string /** 值 */ value?: any /** 变体 */ variant?: TextFieldVariant /** InputProps */ InputProps?: Partial /** InputLabelProps */ InputLabelProps?: Record /** FormHelperTextProps */ FormHelperTextProps?: Record } // ============================================= // TextField 组件 // ============================================= export function TextField(props: TextFieldProps) { const { autoComplete, autoFocus, children, className, color = 'primary', defaultValue, disabled = false, error = false, fullWidth = false, helperText, id, inputProps, inputRef, label, margin = 'none', maxRows, minRows, multiline = false, name, onBlur, onChange, onFocus, placeholder, required = false, rows, select = false, size, style, sx, type, value, variant = 'outlined', InputProps, InputLabelProps, FormHelperTextProps, ...other } = props // 生成唯一 ID const inputId = id || `mui-textfield-${Math.random().toString(36).substr(2, 9)}` const helperTextId = helperText ? `${inputId}-helper-text` : undefined const labelId = label ? `${inputId}-label` : undefined // 构建类名 const rootClasses = [ textFieldClasses.root, `MuiTextField-variant${variant.charAt(0).toUpperCase() + variant.slice(1)}`, fullWidth && 'MuiTextField-fullWidth', margin !== 'none' && `MuiTextField-margin${margin.charAt(0).toUpperCase() + margin.slice(1)}`, disabled && 'Mui-disabled', error && 'Mui-error', required && 'Mui-required', className, ].filter(Boolean).join(' ') // 输入属性 const inputElementProps: InputBaseProps = { autoComplete, autoFocus, defaultValue, disabled, error, fullWidth, id: inputId, inputProps, inputRef, maxRows, minRows, multiline, name, onBlur, onChange, onFocus, placeholder, required, rows, size, type, value, 'aria-describedby': helperTextId, ...InputProps, } // 根据变体选择不同的样式类 const variantClass = `MuiTextField-${variant}` return ( {/* 标签 */} {label && ( {label} {required && *} )} {/* 输入区域 */} {variant === 'outlined' ? ( {/* Outlined 边框 */} {label && ( {label} )} ) : variant === 'filled' ? ( ) : ( )} {/* 帮助文本 */} {helperText && ( {helperText} )} ) } export default TextField