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