diff --git a/openmetadata-ui-core-components/src/main/resources/ui/src/components/base/autocomplete/autocomplete.tsx b/openmetadata-ui-core-components/src/main/resources/ui/src/components/base/autocomplete/autocomplete.tsx index 99f32ce16406..59191bf6f70e 100644 --- a/openmetadata-ui-core-components/src/main/resources/ui/src/components/base/autocomplete/autocomplete.tsx +++ b/openmetadata-ui-core-components/src/main/resources/ui/src/components/base/autocomplete/autocomplete.tsx @@ -56,6 +56,7 @@ interface AutocompleteContextValue { onInputChange: (value: string) => void; renderTag?: (item: SelectItemType, onRemove: () => void) => ReactNode; maxVisibleItems?: number; + multiple: boolean; } const AutocompleteContext = createContext({ @@ -65,6 +66,7 @@ const AutocompleteContext = createContext({ onRemove: () => {}, onInputChange: () => {}, maxVisibleItems: undefined, + multiple: true, }); interface AutocompleteTriggerProps extends AriaGroupProps { @@ -94,6 +96,7 @@ export interface AutocompleteProps filterOption?: (item: SelectItemType, filterText: string) => boolean; onSearchChange?: (value: string) => void; maxVisibleItems?: number; + multiple?: boolean; } const renderChipIcon = (item: SelectItemType) => { @@ -145,6 +148,12 @@ const InnerAutocomplete = ({ case 'ArrowRight': focusManager?.focusNext({ wrap: false, tabbable: false }); + break; + case 'ArrowDown': + if (comboBoxStateContext && !comboBoxStateContext.isOpen) { + comboBoxStateContext.open(); + } + break; } }; @@ -195,7 +204,7 @@ const InnerAutocomplete = ({ }; const isSelectionEmpty = context?.selectedItems?.length === 0; - const { maxVisibleItems } = context; + const { maxVisibleItems, multiple } = context; const allSelected = context?.selectedItems ?? []; const visibleSelected = maxVisibleItems === undefined @@ -240,10 +249,11 @@ const InnerAutocomplete = ({
{ return ( @@ -267,10 +278,13 @@ const AutocompleteTrigger = ({ cx( 'tw:relative tw:flex tw:w-full tw:items-center tw:gap-2 tw:rounded-lg tw:bg-primary tw:shadow-xs tw:ring-1 tw:ring-primary tw:outline-hidden tw:transition tw:duration-100 tw:ease-linear tw:ring-inset', isDisabled && 'tw:cursor-not-allowed tw:bg-disabled_subtle', + isInvalid && 'tw:ring-error_subtle', isFocusWithin && 'tw:ring-2 tw:ring-brand', + isFocusWithin && isInvalid && 'tw:ring-2 tw:ring-error', sizes[size].root ) - }> + } + isInvalid={isInvalid}> {({ isDisabled }) => ( <> {Icon && ( @@ -298,6 +312,7 @@ export const AutocompleteBase = ({ label, tooltip, hint, + isInvalid, selectedItems, onItemCleared, onItemInserted, @@ -305,6 +320,7 @@ export const AutocompleteBase = ({ popoverClassName, renderTag, filterOption, + multiple = true, onSearchChange, maxVisibleItems, name: _name, @@ -364,6 +380,9 @@ export const AutocompleteBase = ({ if (!id) { return; } + if (!multiple && internalSelected.length >= 1) { + return; + } const item = itemMap.get(id as string); if (!item) { return; @@ -407,6 +426,7 @@ export const AutocompleteBase = ({ onRemove, renderTag, maxVisibleItems, + multiple, }), [ selectedKeys, @@ -415,6 +435,7 @@ export const AutocompleteBase = ({ onRemove, renderTag, maxVisibleItems, + multiple, ] ); @@ -425,7 +446,7 @@ export const AutocompleteBase = ({ allowsEmptyCollection inputValue={filterText} items={visibleItems} - menuTrigger="focus" + menuTrigger="input" selectedKey={null} onInputChange={onInputChange} onSelectionChange={onSelectionChange} @@ -440,6 +461,7 @@ export const AutocompleteBase = ({
- {hint && {hint}} + {hint && {hint}}
)}