/// /** * FilledInput Component - Lynx 版 MUI FilledInput * 100% 一比一复刻 MUI FilledInput * * 带有填充背景的输入框 * * 对应 MUI: packages/mui-material/src/FilledInput/FilledInput.js */ import './FilledInput.css' import filledInputClasses, { getFilledInputUtilityClass } from './filledInputClasses' import { InputBase, InputBaseProps } from '../InputBase' import { useFormControl, formControlState } from '../FormControl' export { filledInputClasses, getFilledInputUtilityClass } // ============================================= // 类型定义 // ============================================= export interface FilledInputProps extends InputBaseProps { /** 是否禁用下划线 */ disableUnderline?: boolean /** 是否隐藏标签 */ hiddenLabel?: boolean } // ============================================= // 辅助函数 // ============================================= 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 FilledInputProps { focused?: boolean } function useUtilityClasses(ownerState: OwnerState) { const { classes, disableUnderline, hiddenLabel } = ownerState const slots = { root: ['root', !disableUnderline && 'underline', hiddenLabel && 'hiddenLabel'], input: ['input', hiddenLabel && 'inputHiddenLabel'], } return composeClasses(slots, getFilledInputUtilityClass, classes) } // ============================================= // FilledInput 组件 // ============================================= export function FilledInput(props: FilledInputProps) { const { className, disableUnderline = false, fullWidth = false, hiddenLabel: hiddenLabelProp, multiline = false, type = 'text', ...other } = props const classes = useUtilityClasses(props) const muiFormControl = useFormControl() const fcs = formControlState({ props, muiFormControl, states: ['color', 'disabled', 'error', 'focused', 'hiddenLabel', 'size', 'required'], }) const hiddenLabel = hiddenLabelProp ?? fcs.hiddenLabel const ownerState: OwnerState = { ...props, color: fcs.color || 'primary', disabled: fcs.disabled, disableUnderline, error: fcs.error, focused: fcs.focused, fullWidth, hiddenLabel, multiline, size: fcs.size, type, } // 构建类名 const rootClasses = [ classes.root, filledInputClasses.root, className, !disableUnderline && filledInputClasses.underline, fcs.focused && filledInputClasses.focused, fcs.disabled && filledInputClasses.disabled, fcs.error && filledInputClasses.error, fcs.size === 'small' && filledInputClasses.sizeSmall, multiline && filledInputClasses.multiline, hiddenLabel && filledInputClasses.hiddenLabel, props.startAdornment && filledInputClasses.adornedStart, props.endAdornment && filledInputClasses.adornedEnd, ].filter(Boolean).join(' ') // 输入类名 const inputClasses = [ classes.input, filledInputClasses.input, fcs.size === 'small' && filledInputClasses.inputSizeSmall, multiline && filledInputClasses.inputMultiline, hiddenLabel && filledInputClasses.inputHiddenLabel, props.startAdornment && filledInputClasses.inputAdornedStart, props.endAdornment && filledInputClasses.inputAdornedEnd, ].filter(Boolean).join(' ') return ( {/* Underline */} {!disableUnderline && ( )} ) } // MUI 名称标识 FilledInput.muiName = 'Input' export default FilledInput