import { ChangeEvent, FocusEvent, MouseEvent, useCallback } from 'react'; import TextField, { TextFieldProps } from '@mui/material/TextField'; import InputAdornment from '@mui/material/InputAdornment'; import { ariaDescribedByIds, BaseInputTemplateProps, examplesId, getInputProps, labelValue, FormContextType, RJSFSchema, StrictRJSFSchema, } from '@rjsf/utils'; import { SchemaExamples } from '@rjsf/core'; const TYPES_THAT_SHRINK_LABEL = ['date', 'datetime-local', 'file', 'time']; /** The `BaseInputTemplate` is the template to use to render the basic `` component for the `core` theme. * It is used as the template for rendering many of the based widgets that differ by `type` and callbacks only. * It can be customized/overridden for other themes or individual implementations as needed. * * @param props - The `WidgetProps` for this template */ export default function BaseInputTemplate< T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any, >(props: BaseInputTemplateProps) { const { id, name, // remove this from textFieldProps htmlName, placeholder, required, readonly, disabled, type, label, hideLabel, hideError, value, onChange, onChangeOverride, onBlur, onFocus, autofocus, options, schema, uiSchema, rawErrors = [], errorSchema, registry, InputLabelProps, InputProps, slotProps, ...textFieldProps } = props; const { ClearButton } = registry.templates.ButtonTemplates; // Now we need to pull out the step, min, max into an inner `inputProps` for material-ui const { step, min, max, accept, ...rest } = getInputProps(schema, type, options); const htmlInputProps = { ...slotProps?.htmlInput, step, min, max, accept, ...(schema.examples ? { list: examplesId(id) } : undefined), }; const _onChange = ({ target: { value } }: ChangeEvent) => onChange(value === '' ? options.emptyValue : value); const _onBlur = ({ target }: FocusEvent) => onBlur(id, target && target.value); const _onFocus = ({ target }: FocusEvent) => onFocus(id, target && target.value); const DisplayInputLabelProps = TYPES_THAT_SHRINK_LABEL.includes(type) ? { ...slotProps?.inputLabel, ...InputLabelProps, shrink: true } : { ...slotProps?.inputLabel, ...InputLabelProps }; const _onClear = useCallback( (e: MouseEvent) => { e.preventDefault(); e.stopPropagation(); onChange(options.emptyValue ?? ''); }, [onChange, options.emptyValue], ); const inputProps = { ...InputProps, ...slotProps?.input }; if (options.allowClearTextInputs && value && !readonly && !disabled) { const clearAdornment = ( ); inputProps.endAdornment = !inputProps.endAdornment ? ( clearAdornment ) : ( <> {inputProps.endAdornment} {clearAdornment} ); } return ( <> 0} onChange={onChangeOverride || _onChange} onBlur={_onBlur} onFocus={_onFocus} {...(textFieldProps as TextFieldProps)} aria-describedby={ariaDescribedByIds(id, !!schema.examples)} /> ); }