import type { ChangeEvent } from 'react'; import { useState } from 'react'; import type { FormContextType, RJSFSchema, StrictRJSFSchema, WidgetProps } from '@rjsf/utils'; import { ariaDescribedByIds, getInputProps } from '@rjsf/utils'; import type { AutoCompleteCompleteEvent } from 'primereact/autocomplete'; import { AutoComplete } from 'primereact/autocomplete'; /** The `AutoCompleteWidget` is a widget for rendering a field with options. * This is used instead of the base input template if the schema has examples. * * @param props - The `WidgetProps` for this component */ export default function AutoCompleteWidget< T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any, >(props: WidgetProps) { const { id, placeholder, value, required, readonly, disabled, onChange, onChangeOverride, onBlur, onFocus, autofocus, options, schema, type, rawErrors = [], } = props; const inputProps = getInputProps(schema, type, options); const primeProps = (options.prime || {}) as object; const handleChange = ({ target: { value: newValue } }: ChangeEvent) => onChange(newValue === '' ? options.emptyValue : newValue); const handleBlur = () => onBlur && onBlur(id, value); const handleFocus = () => onFocus && onFocus(id, value); const examples = (schema.examples as string[]).concat( schema.default && !(schema.examples as string[]).includes(schema.default.toString()) ? [schema.default.toString()] : [], ); const [items, setItems] = useState([]); const search = (event: AutoCompleteCompleteEvent) => { setItems(examples.filter((example) => example.toString().toLowerCase().includes(event.query.toLowerCase()))); }; return ( 0} onChange={onChangeOverride || handleChange} onBlur={handleBlur} onFocus={handleFocus} aria-describedby={ariaDescribedByIds(id, !!schema.examples)} /* Make autocomplete look like a dropdown, which looks much nicer */ pt={{ root: { className: 'p-dropdown', }, input: { root: { style: { border: 'none' }, }, }, dropdownButton: { root: { className: 'p-button-text p-button-secondary', }, }, }} /> ); }