UNPKG

@grafana/ui

Version:
1 lines • 25.2 kB
{"version":3,"file":"MultiCombobox.mjs","sources":["../../../../src/components/Combobox/MultiCombobox.tsx"],"sourcesContent":["import { cx } from '@emotion/css';\nimport { useCombobox, useMultipleSelection } from 'downshift';\nimport { useCallback, useMemo, useState } from 'react';\n\nimport { t } from '@grafana/i18n';\n\nimport { useStyles2 } from '../../themes/ThemeContext';\nimport { Icon } from '../Icon/Icon';\nimport { Box } from '../Layout/Box/Box';\nimport { Portal } from '../Portal/Portal';\nimport { Text } from '../Text/Text';\nimport { Tooltip } from '../Tooltip/Tooltip';\n\nimport { ComboboxBaseProps, AutoSizeConditionals } from './Combobox';\nimport { ComboboxList } from './ComboboxList';\nimport { SuffixIcon } from './SuffixIcon';\nimport { ValuePill } from './ValuePill';\nimport { itemToString } from './filter';\nimport { getComboboxStyles } from './getComboboxStyles';\nimport { getMultiComboboxStyles } from './getMultiComboboxStyles';\nimport { ALL_OPTION_VALUE, ComboboxOption } from './types';\nimport { useComboboxFloat } from './useComboboxFloat';\nimport { MAX_SHOWN_ITEMS, useMeasureMulti } from './useMeasureMulti';\nimport { useMultiInputAutoSize } from './useMultiInputAutoSize';\nimport { useOptions } from './useOptions';\n\ninterface MultiComboboxBaseProps<T extends string | number>\n extends Omit<ComboboxBaseProps<T>, 'value' | 'onChange' | 'isClearable'> {\n value?: T[] | Array<ComboboxOption<T>>;\n onChange: (option: Array<ComboboxOption<T>>) => void;\n isClearable?: boolean;\n enableAllOption?: boolean;\n portalContainer?: HTMLElement;\n}\n\nexport type MultiComboboxProps<T extends string | number> = MultiComboboxBaseProps<T> & AutoSizeConditionals;\n\n/**\n * The behavior of the MultiCombobox is similar to that of the Combobox, but it allows you to select multiple options. For all non-multi behaviors, see the Combobox documentation.\n *\n * https://developers.grafana.com/ui/latest/index.html?path=/docs/inputs-multicombobox--docs\n */\nexport const MultiCombobox = <T extends string | number>(props: MultiComboboxProps<T>) => {\n const {\n placeholder,\n onChange,\n value,\n width,\n enableAllOption,\n invalid,\n disabled,\n minWidth,\n maxWidth,\n isClearable,\n createCustomValue = false,\n 'aria-labelledby': ariaLabelledBy,\n 'data-testid': dataTestId,\n portalContainer,\n prefixIcon,\n } = props;\n\n const styles = useStyles2(getComboboxStyles);\n const [inputValue, setInputValue] = useState('');\n\n const allOptionItem = useMemo(() => {\n return {\n label:\n inputValue === ''\n ? t('multicombobox.all.title', 'All')\n : t('multicombobox.all.title-filtered', 'All (filtered)'),\n // Type casting needed to make this work when T is a number\n value: ALL_OPTION_VALUE,\n } as ComboboxOption<T>;\n }, [inputValue]);\n\n // Handle async options and the 'All' option\n const {\n options: baseOptions,\n updateOptions,\n asyncLoading,\n asyncError,\n } = useOptions(props.options, createCustomValue);\n const options = useMemo(() => {\n // Only add the 'All' option if there's more than 1 option\n const addAllOption = enableAllOption && baseOptions.length > 1;\n return addAllOption ? [allOptionItem, ...baseOptions] : baseOptions;\n }, [baseOptions, enableAllOption, allOptionItem]);\n const loading = props.loading || asyncLoading;\n\n const selectedItems = useMemo(() => {\n if (!value) {\n return [];\n }\n\n return getSelectedItemsFromValue<T>(value, typeof props.options !== 'function' ? props.options : baseOptions);\n }, [value, props.options, baseOptions]);\n\n const { measureRef, counterMeasureRef, suffixMeasureRef, shownItems } = useMeasureMulti(\n selectedItems,\n width,\n disabled\n );\n\n const isOptionSelected = useCallback(\n (item: ComboboxOption<T>) => selectedItems.some((opt) => opt.value === item.value),\n [selectedItems]\n );\n\n const { getSelectedItemProps, getDropdownProps, setSelectedItems, addSelectedItem, removeSelectedItem, reset } =\n useMultipleSelection({\n selectedItems, // initially selected items,\n onStateChange: ({ type, selectedItems: newSelectedItems }) => {\n switch (type) {\n case useMultipleSelection.stateChangeTypes.SelectedItemKeyDownBackspace:\n case useMultipleSelection.stateChangeTypes.SelectedItemKeyDownDelete:\n case useMultipleSelection.stateChangeTypes.DropdownKeyDownBackspace:\n case useMultipleSelection.stateChangeTypes.FunctionRemoveSelectedItem:\n case useMultipleSelection.stateChangeTypes.FunctionAddSelectedItem:\n case useMultipleSelection.stateChangeTypes.FunctionSetSelectedItems:\n case useMultipleSelection.stateChangeTypes.FunctionReset:\n // Unclear why newSelectedItems would be undefined, but this seems logical\n onChange(newSelectedItems ?? []);\n break;\n\n default:\n break;\n }\n },\n stateReducer: (_state, actionAndChanges) => {\n const { changes } = actionAndChanges;\n return {\n ...changes,\n\n /**\n * TODO: Fix Hack!\n * This prevents the menu from closing when the user unselects an item in the dropdown at the expense\n * of breaking keyboard navigation.\n *\n * Downshift isn't really designed to keep selected items in the dropdown menu, so when you unselect an item\n * in a multiselect, the stateReducer tries to move focus onto another item which causes the menu to be closed.\n * This only seems to happen when you deselect the last item in the selectedItems list.\n *\n * Check out:\n * - FunctionRemoveSelectedItem in the useMultipleSelection reducer https://github.com/downshift-js/downshift/blob/master/src/hooks/useMultipleSelection/reducer.js#L75\n * - The activeIndex useEffect in useMultipleSelection https://github.com/downshift-js/downshift/blob/master/src/hooks/useMultipleSelection/index.js#L68-L72\n *\n * Forcing the activeIndex to -999 both prevents the useEffect that changes the focus from triggering (value never changes)\n * and prevents the if statement in useMultipleSelection from focusing anything.\n */\n activeIndex: -999,\n };\n },\n });\n\n const {\n getToggleButtonProps,\n //getLabelProps,\n isOpen,\n highlightedIndex,\n getMenuProps,\n getInputProps,\n getItemProps,\n } = useCombobox({\n items: options,\n itemToString,\n inputValue,\n selectedItem: null,\n stateReducer: (state, actionAndChanges) => {\n const { type } = actionAndChanges;\n let { changes } = actionAndChanges;\n const menuBeingOpened = state.isOpen === false && changes.isOpen === true;\n\n // Reset the input value when the menu is opened. If the menu is opened due to an input change\n // then make sure we keep that.\n // This will trigger onInputValueChange to load async options\n if (menuBeingOpened && changes.inputValue === state.inputValue) {\n changes = {\n ...changes,\n inputValue: '',\n };\n }\n\n switch (type) {\n case useCombobox.stateChangeTypes.InputKeyDownEnter:\n case useCombobox.stateChangeTypes.ItemClick:\n return {\n ...changes,\n isOpen: true,\n highlightedIndex: state.highlightedIndex,\n };\n case useCombobox.stateChangeTypes.InputBlur:\n setInputValue('');\n default:\n return changes;\n }\n },\n\n onIsOpenChange: ({ isOpen, inputValue }) => {\n if (isOpen && inputValue === '') {\n updateOptions(inputValue);\n }\n },\n\n onStateChange: ({ inputValue: newInputValue, type, selectedItem: newSelectedItem }) => {\n switch (type) {\n case useCombobox.stateChangeTypes.InputKeyDownEnter:\n case useCombobox.stateChangeTypes.ItemClick:\n // Don't allow selection of info options\n if (newSelectedItem?.infoOption) {\n break;\n }\n\n // Handle All functionality\n if (newSelectedItem?.value === ALL_OPTION_VALUE) {\n // TODO: fix bug where if the search filtered items list is the\n // same length, but different, than the selected items (ask tobias)\n const isAllFilteredSelected = selectedItems.length === options.length - 1;\n\n // if every option is already selected, clear the selection.\n // otherwise, select all the options (excluding the first ALL_OPTION and info options)\n const realOptions = options.slice(1).filter((option) => !option.infoOption);\n let newSelectedItems = isAllFilteredSelected && inputValue === '' ? [] : realOptions;\n\n if (!isAllFilteredSelected && inputValue !== '') {\n newSelectedItems = [...new Set([...selectedItems, ...realOptions])];\n }\n\n if (isAllFilteredSelected && inputValue !== '') {\n // Deselect all currently filtered items\n const filteredSet = new Set(realOptions.map((item) => item.value));\n newSelectedItems = selectedItems.filter((item) => !filteredSet.has(item.value));\n }\n setSelectedItems(newSelectedItems);\n } else if (newSelectedItem && isOptionSelected(newSelectedItem)) {\n // Find the actual selected item object that matches the clicked item by value\n // This is necessary because the clicked item (from async options) may be a different\n // object reference than the selected item, and useMultipleSelection uses object equality\n const itemToRemove = selectedItems.find((item) => item.value === newSelectedItem.value);\n if (itemToRemove) {\n removeSelectedItem(itemToRemove);\n }\n } else if (newSelectedItem) {\n addSelectedItem(newSelectedItem);\n }\n break;\n case useCombobox.stateChangeTypes.InputChange:\n setInputValue(newInputValue ?? '');\n updateOptions(newInputValue ?? '');\n\n break;\n default:\n break;\n }\n },\n });\n\n const { inputRef: containerRef, floatingRef, floatStyles, scrollRef } = useComboboxFloat(options, isOpen);\n const multiStyles = useStyles2(\n getMultiComboboxStyles,\n isOpen,\n invalid,\n disabled,\n width,\n minWidth,\n maxWidth,\n isClearable\n );\n\n // Selected items that show up in the input field\n const visibleItems = isOpen ? selectedItems.slice(0, MAX_SHOWN_ITEMS) : selectedItems.slice(0, shownItems);\n\n const { inputRef, inputWidth } = useMultiInputAutoSize(inputValue);\n return (\n <div className={multiStyles.container} ref={containerRef}>\n <div className={cx(multiStyles.wrapper, { [multiStyles.disabled]: disabled })} ref={measureRef}>\n {prefixIcon && (\n <Box marginLeft={0.5}>\n <Text color=\"secondary\">\n <Icon name={prefixIcon} />\n </Text>\n </Box>\n )}\n <span className={multiStyles.pillWrapper}>\n {visibleItems.map((item, index) => (\n <ValuePill\n disabled={disabled}\n onRemove={() => {\n removeSelectedItem(item);\n }}\n key={`${item.value}${index}`}\n {...getSelectedItemProps({ selectedItem: item, index })}\n >\n {itemToString(item)}\n </ValuePill>\n ))}\n {selectedItems.length > visibleItems.length && (\n <Box display=\"flex\" direction=\"row\" marginLeft={0.5} gap={1} ref={counterMeasureRef}>\n <Text>...</Text>\n <Tooltip\n interactive\n content={\n <>\n {selectedItems.slice(visibleItems.length).map((item) => (\n <div key={item.value}>{itemToString(item)}</div>\n ))}\n </>\n }\n >\n <div className={multiStyles.restNumber}>{selectedItems.length - shownItems}</div>\n </Tooltip>\n </Box>\n )}\n <input\n className={multiStyles.input}\n {...getInputProps({\n ...getDropdownProps({\n disabled,\n preventKeyAction: isOpen,\n placeholder: visibleItems.length === 0 ? placeholder : '',\n ref: inputRef,\n style: { width: inputWidth },\n }),\n 'aria-labelledby': ariaLabelledBy, // Label should be handled with the Field component\n 'data-testid': dataTestId,\n })}\n />\n\n <div className={multiStyles.suffix} ref={suffixMeasureRef} {...getToggleButtonProps()}>\n {isClearable && selectedItems.length > 0 && (\n <Icon\n name=\"times\"\n className={styles.clear}\n title={t('multicombobox.clear.title', 'Clear all')}\n tabIndex={0}\n role=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n reset();\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n reset();\n }\n }}\n />\n )}\n <SuffixIcon isLoading={loading || false} isOpen={isOpen} />\n </div>\n </span>\n </div>\n <Portal root={portalContainer}>\n <div\n className={cx(styles.menu, !isOpen && styles.menuClosed)}\n style={{\n ...floatStyles,\n width: floatStyles.width + 24, // account for checkbox\n pointerEvents: 'auto', // Override container's pointer-events: none\n }}\n {...getMenuProps({ ref: floatingRef })}\n >\n {isOpen && (\n <ComboboxList\n loading={loading}\n options={options}\n highlightedIndex={highlightedIndex}\n selectedItems={selectedItems}\n scrollRef={scrollRef}\n getItemProps={getItemProps}\n enableAllOption={enableAllOption}\n isMultiSelect={true}\n error={asyncError}\n />\n )}\n </div>\n </Portal>\n </div>\n );\n};\n\nfunction getSelectedItemsFromValue<T extends string | number>(\n value: T[] | Array<ComboboxOption<T>>,\n options: Array<ComboboxOption<T>>\n) {\n if (isComboboxOptions(value)) {\n return value;\n }\n const valueMap = new Map(value.map((val, index) => [val, index]));\n const resultingItems: Array<ComboboxOption<T>> = [];\n\n for (const option of options) {\n const index = valueMap.get(option.value);\n if (index !== undefined) {\n resultingItems[index] = option;\n valueMap.delete(option.value);\n }\n if (valueMap.size === 0) {\n // We found all values\n break;\n }\n }\n\n // Handle items that are not in options\n for (const [val, index] of valueMap) {\n resultingItems[index] = { value: val };\n }\n return resultingItems;\n}\n\nfunction isComboboxOptions<T extends string | number>(\n value: T[] | Array<ComboboxOption<T>>\n): value is Array<ComboboxOption<T>> {\n return typeof value[0] === 'object';\n}\n"],"names":["isOpen","inputValue"],"mappings":"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"}