|
|
|
@ -6,6 +6,7 @@ import { useCallback, useMemo, useState } from 'react'; |
|
|
|
|
import { useStyles2 } from '../../themes'; |
|
|
|
|
import { t } from '../../utils/i18n'; |
|
|
|
|
import { Checkbox } from '../Forms/Checkbox'; |
|
|
|
|
import { Icon } from '../Icon/Icon'; |
|
|
|
|
import { Box } from '../Layout/Box/Box'; |
|
|
|
|
import { Stack } from '../Layout/Stack/Stack'; |
|
|
|
|
import { Portal } from '../Portal/Portal'; |
|
|
|
@ -36,7 +37,8 @@ interface MultiComboboxBaseProps<T extends string | number> extends Omit<Combobo |
|
|
|
|
export type MultiComboboxProps<T extends string | number> = MultiComboboxBaseProps<T> & AutoSizeConditionals; |
|
|
|
|
|
|
|
|
|
export const MultiCombobox = <T extends string | number>(props: MultiComboboxProps<T>) => { |
|
|
|
|
const { placeholder, onChange, value, width, enableAllOption, invalid, disabled, minWidth, maxWidth } = props; |
|
|
|
|
const { placeholder, onChange, value, width, enableAllOption, invalid, disabled, minWidth, maxWidth, isClearable } = |
|
|
|
|
props; |
|
|
|
|
|
|
|
|
|
const styles = useStyles2(getComboboxStyles); |
|
|
|
|
const [inputValue, setInputValue] = useState(''); |
|
|
|
@ -80,7 +82,7 @@ export const MultiCombobox = <T extends string | number>(props: MultiComboboxPro |
|
|
|
|
[selectedItems] |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
const { getSelectedItemProps, getDropdownProps, setSelectedItems, addSelectedItem, removeSelectedItem } = |
|
|
|
|
const { getSelectedItemProps, getDropdownProps, setSelectedItems, addSelectedItem, removeSelectedItem, reset } = |
|
|
|
|
useMultipleSelection({ |
|
|
|
|
selectedItems, // initally selected items,
|
|
|
|
|
onStateChange: ({ type, selectedItems: newSelectedItems }) => { |
|
|
|
@ -91,6 +93,7 @@ export const MultiCombobox = <T extends string | number>(props: MultiComboboxPro |
|
|
|
|
case useMultipleSelection.stateChangeTypes.FunctionRemoveSelectedItem: |
|
|
|
|
case useMultipleSelection.stateChangeTypes.FunctionAddSelectedItem: |
|
|
|
|
case useMultipleSelection.stateChangeTypes.FunctionSetSelectedItems: |
|
|
|
|
case useMultipleSelection.stateChangeTypes.FunctionReset: |
|
|
|
|
// Unclear why newSelectedItems would be undefined, but this seems logical
|
|
|
|
|
onChange(newSelectedItems ?? []); |
|
|
|
|
break; |
|
|
|
@ -220,7 +223,16 @@ export const MultiCombobox = <T extends string | number>(props: MultiComboboxPro |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const { inputRef: containerRef, floatingRef, floatStyles, scrollRef } = useComboboxFloat(options, isOpen); |
|
|
|
|
const multiStyles = useStyles2(getMultiComboboxStyles, isOpen, invalid, disabled, width, minWidth, maxWidth); |
|
|
|
|
const multiStyles = useStyles2( |
|
|
|
|
getMultiComboboxStyles, |
|
|
|
|
isOpen, |
|
|
|
|
invalid, |
|
|
|
|
disabled, |
|
|
|
|
width, |
|
|
|
|
minWidth, |
|
|
|
|
maxWidth, |
|
|
|
|
isClearable |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
const virtualizerOptions = { |
|
|
|
|
count: options.length, |
|
|
|
@ -284,6 +296,24 @@ export const MultiCombobox = <T extends string | number>(props: MultiComboboxPro |
|
|
|
|
/> |
|
|
|
|
|
|
|
|
|
<div className={multiStyles.suffix} ref={suffixMeasureRef} {...getToggleButtonProps()}> |
|
|
|
|
{isClearable && selectedItems.length > 0 && ( |
|
|
|
|
<Icon |
|
|
|
|
name="times" |
|
|
|
|
className={styles.clear} |
|
|
|
|
title={t('multicombobox.clear.title', 'Clear all')} |
|
|
|
|
tabIndex={0} |
|
|
|
|
role="button" |
|
|
|
|
onClick={(e) => { |
|
|
|
|
e.stopPropagation(); |
|
|
|
|
reset(); |
|
|
|
|
}} |
|
|
|
|
onKeyDown={(e) => { |
|
|
|
|
if (e.key === 'Enter' || e.key === ' ') { |
|
|
|
|
reset(); |
|
|
|
|
} |
|
|
|
|
}} |
|
|
|
|
/> |
|
|
|
|
)} |
|
|
|
|
<SuffixIcon isLoading={loading || false} isOpen={isOpen} /> |
|
|
|
|
</div> |
|
|
|
|
</span> |
|
|
|
|