import * as React from 'react'; import { Controller, useFormContext } from 'react-hook-form'; import FormHelperText from '@mui/material/FormHelperText'; import Autocomplete, { AutocompleteProps, createFilterOptions } from '@mui/material/Autocomplete'; import Typography from '@mui/material/Typography'; import type { IFieldDropdownOption } from '@automatisch/types'; interface ControlledAutocompleteProps extends AutocompleteProps { shouldUnregister?: boolean; name: string; required?: boolean; showOptionValue?: boolean; description?: string; dependsOn?: string[]; } const getOption = (options: readonly IFieldDropdownOption[], value: string) => options.find((option) => option.value === value) || null; // Enables filtering by value in autocomplete dropdown const filterOptions = createFilterOptions({ stringify: ({ label, value }) => ` ${label} ${value} ` }) function ControlledAutocomplete( props: ControlledAutocompleteProps ): React.ReactElement { const { control, watch, setValue, resetField } = useFormContext(); const { required = false, name, defaultValue, shouldUnregister = false, onBlur, onChange, description, options = [], dependsOn = [], showOptionValue, ...autocompleteProps } = props; let dependsOnValues: unknown[] = []; if (dependsOn?.length) { dependsOnValues = watch(dependsOn); } React.useEffect(() => { const hasDependencies = dependsOnValues.length; const allDepsSatisfied = dependsOnValues.every(Boolean); if (hasDependencies && !allDepsSatisfied) { // Reset the field if any dependency is not satisfied setValue(name, null); resetField(name); } }, dependsOnValues); return ( (
{/* encapsulated with an element such as div to vertical spacing delegated from parent */} { const typedSelectedOption = selectedOption as IFieldDropdownOption; if ( typedSelectedOption !== null && Object.prototype.hasOwnProperty.call( typedSelectedOption, 'value' ) ) { controllerOnChange(typedSelectedOption.value); } else { controllerOnChange(typedSelectedOption); } onChange?.(event, selectedOption, reason, details); }} onBlur={(...args) => { controllerOnBlur(); onBlur?.(...args); }} ref={ref} data-test={`${name}-autocomplete`} renderOption={(optionProps, option) => (
  • {option.label} {showOptionValue && ( {option.value} )}
  • )} /> {fieldState.isTouched ? fieldState.error?.message || description : description}
    )} /> ); } export default ControlledAutocomplete;