import React, { useCallback, useMemo } from 'react'; import { ariaDescribedByIds, enumOptionsIndexForValue, enumOptionsValueForIndex, labelValue, FormContextType, RJSFSchema, StrictRJSFSchema, WidgetProps, } from '@rjsf/utils'; import { Select, MultiSelect } from '@mantine/core'; import { cleanupOptions } from '../utils'; /** The `SelectWidget` is a widget for rendering dropdowns. * It is typically used with string properties constrained with enum options. * * @param props - The `WidgetProps` for this component */ export default function SelectWidget( props: WidgetProps ) { const { id, value, placeholder, required, disabled, readonly, autofocus, label, hideLabel, multiple, rawErrors, options, onChange, onBlur, onFocus, } = props; const { enumOptions, enumDisabled, emptyValue } = options; const themeProps = cleanupOptions(options); const handleChange = useCallback( (nextValue: any) => { if (!disabled && !readonly && onChange) { onChange(enumOptionsValueForIndex(nextValue, enumOptions, emptyValue)); } }, [onChange, disabled, readonly, enumOptions, emptyValue] ); const handleBlur = useCallback( ({ target }: React.FocusEvent) => { if (onBlur) { onBlur(id, enumOptionsValueForIndex(target && target.value, enumOptions, emptyValue)); } }, [onBlur, id, enumOptions, emptyValue] ); const handleFocus = useCallback( ({ target }: React.FocusEvent) => { if (onFocus) { onFocus(id, enumOptionsValueForIndex(target && target.value, enumOptions, emptyValue)); } }, [onFocus, id, enumOptions, emptyValue] ); const selectedIndexes = enumOptionsIndexForValue(value, enumOptions, multiple); const selectOptions = useMemo(() => { if (Array.isArray(enumOptions)) { return enumOptions.map((option, index) => ({ key: String(index), value: String(index), label: option.label, disabled: Array.isArray(enumDisabled) && enumDisabled.indexOf(option.value) !== -1, })); } return []; }, [enumDisabled, enumOptions]); const Component = multiple ? MultiSelect : Select; return ( 0 ? rawErrors.join('\n') : undefined} searchable {...themeProps} aria-describedby={ariaDescribedByIds(id)} comboboxProps={{ withinPortal: false }} /> ); }