import type { ChangeEvent, FocusEvent, MouseEvent } from 'react'; import { useCallback } from 'react'; import type { BaseInputTemplateProps, FormContextType, RJSFSchema, StrictRJSFSchema } from '@rjsf/utils'; import { ariaDescribedByIds, examplesId, getInputProps } from '@rjsf/utils'; import SchemaExamples from '../SchemaExamples'; /** 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 ...rest htmlName, value, readonly, disabled, autofocus, onBlur, onFocus, onChange, onChangeOverride, options, schema, uiSchema, registry, rawErrors, type, hideLabel, // remove this from ...rest hideError, // remove this from ...rest ...rest } = props; const { ClearButton } = registry.templates.ButtonTemplates; // Note: since React 15.2.0 we can't forward unknown element attributes, so we // exclude the "options" and "schema" ones here. if (!id) { // oxlint-disable-next-line no-console console.log('No id for', props); throw new Error(`no id for props ${JSON.stringify(props)}`); } const inputProps = { ...rest, ...getInputProps(schema, type, options), }; let inputValue; if (inputProps.type === 'number' || inputProps.type === 'integer') { inputValue = value || value === 0 ? value : ''; } else { inputValue = value == null ? '' : value; } const handleChange = useCallback( ({ target: { value: newValue } }: ChangeEvent) => onChange(newValue === '' ? options.emptyValue : newValue), [onChange, options], ); const handleBlur = useCallback(({ target }: FocusEvent) => onBlur(id, target?.value), [onBlur, id]); const handleFocus = useCallback( ({ target }: FocusEvent) => onFocus(id, target?.value), [onFocus, id], ); const handleClear = useCallback( (e: MouseEvent) => { e.preventDefault(); e.stopPropagation(); onChange(options.emptyValue ?? ''); }, [onChange, options.emptyValue], ); return ( <> {options.allowClearTextInputs && !readonly && !disabled && inputValue && ( )} ); }