diff --git a/services/web/frontend/js/shared/components/ol/ol-autocomplete.tsx b/services/web/frontend/js/shared/components/ol/ol-autocomplete.tsx index 45b0a97206..9c057874bd 100644 --- a/services/web/frontend/js/shared/components/ol/ol-autocomplete.tsx +++ b/services/web/frontend/js/shared/components/ol/ol-autocomplete.tsx @@ -107,22 +107,23 @@ function OLAutocompleteInternal({ const showCreateOption = allowCreateForInput && internalInputValue && !exactMatch + const createDisplayItem: OLAutocompleteDisplayItem[] = showCreateOption + ? [{ type: 'create' as const, inputValue: internalInputValue }] + : [] + const displayItems: OLAutocompleteDisplayItem[] = [ + ...(expandUp ? [] : createDisplayItem), ...inputItems.map(item => ({ type: 'item' as const, value: item.value, label: item.label, })), - ...(showCreateOption - ? [ - { - type: 'create' as const, - inputValue: internalInputValue, - }, - ] - : []), + ...(expandUp ? createDisplayItem : []), ] + const getDisplayIndex = (inputItemIndex: number) => + !expandUp && showCreateOption ? inputItemIndex + 1 : inputItemIndex + const hasGroupedItems = inputItems.some(item => Boolean(item.group)) const { @@ -141,6 +142,28 @@ function OLAutocompleteInternal({ if (!item) return '' return item.type === 'create' ? item.inputValue : item.label }, + stateReducer: (_state, { type, changes }) => { + if (type === useCombobox.stateChangeTypes.InputChange) { + const newInputValue = changes.inputValue || '' + const newAllowCreate = + typeof allowCreate === 'function' + ? allowCreate(newInputValue) + : allowCreate + const hasExactMatch = items.some( + item => item.label.toLowerCase() === newInputValue.toLowerCase() + ) + const hasMatchingItems = items.some(item => + item.label.toLowerCase().includes(newInputValue.toLowerCase()) + ) + const newShowCreate = newAllowCreate && newInputValue && !hasExactMatch + return { + ...changes, + highlightedIndex: + !expandUp && newShowCreate && hasMatchingItems ? 1 : 0, + } + } + return changes + }, onSelectedItemChange: ({ selectedItem }) => { if (selectedItem) { if (selectedItem.type === 'create') { @@ -159,13 +182,41 @@ function OLAutocompleteInternal({ const shouldShowDropdown = isOpen && displayItems.length > 0 + const renderCreateOption = (index: number) => ( + <> + {hasGroupedItems && expandUp && ( +
+ )} +