Skip to content

Commit

Permalink
πŸ› Autocomplete select all: consider disabled items (#3429)
Browse files Browse the repository at this point in the history
* πŸ› Autocmplete: select all: consider disabled items

* optimize optionDisabled initialization

* consider selected disabled items in "select all"

* clear button: consider disabled selected items

* renaming variables

* update story
  • Loading branch information
oddvernes authored May 13, 2024
1 parent ad81258 commit 83a78c7
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -340,16 +340,25 @@ export const DisabledOption: StoryFn<AutocompleteProps<MyOptionType>> = (
args,
) => {
const { options, optionLabel } = args

const [filter, setFilter] = useState<boolean>(true)
const isOptionDisabled = (item: MyOptionType) => item.trend === 'πŸ“‰'

return (
<>
<Checkbox
label="disable options"
onChange={() => {
setFilter(!filter)
}}
checked={filter}
/>
<Autocomplete
label="Select a stock"
options={options}
optionDisabled={isOptionDisabled}
optionDisabled={filter ? isOptionDisabled : undefined}
optionLabel={optionLabel}
multiple
allowSelectAll
/>
</>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,8 @@ const findPrevIndex: IndexFinderType = ({
return prevIndex
}

const defaultOptionDisabled = () => false

type OptionLabelProps<T> = T extends string | number
? {
/** Custom option label */
Expand Down Expand Up @@ -328,7 +330,7 @@ function AutocompleteInner<T>(
allowSelectAll,
initialSelectedOptions = [],
disablePortal,
optionDisabled = () => false,
optionDisabled = defaultOptionDisabled,
optionsFilter,
autoWidth,
placeholder,
Expand Down Expand Up @@ -367,6 +369,7 @@ function AutocompleteInner<T>(
return _availableItems
}, [_availableItems, showSelectAll])

//issue 2304, update dataset when options are added dynamically
useEffect(() => {
const availableHash = JSON.stringify(inputOptions)
const optionsHash = JSON.stringify(options)
Expand All @@ -379,10 +382,6 @@ function AutocompleteInner<T>(
setAvailableItems(inputOptions)
}, [inputOptions])

const disabledItems = useMemo(
() => options.filter(optionDisabled),
[options, optionDisabled],
)
const { density } = useEds()
const token = useToken(
{ density },
Expand Down Expand Up @@ -426,23 +425,40 @@ function AutocompleteInner<T>(
addSelectedItem,
removeSelectedItem,
selectedItems,
reset: resetSelection,
setSelectedItems,
} = useMultipleSelection(multipleSelectionProps)

const enabledItems = useMemo(() => {
const disabledItemsSet = new Set(inputOptions.filter(optionDisabled))
return inputOptions.filter((x) => !disabledItemsSet.has(x))
}, [inputOptions, optionDisabled])

const selectedDisabledItemsSet = useMemo(
() => new Set(selectedItems.filter(optionDisabled)),
[selectedItems, optionDisabled],
)

const selectedEnabledItems = useMemo(
() => selectedItems.filter((x) => !selectedDisabledItemsSet.has(x)),
[selectedItems, selectedDisabledItemsSet],
)

const allSelectedState = useMemo(() => {
if (!inputOptions || !selectedItems) return 'NONE'
if (inputOptions.length === selectedItems.length) return 'ALL'
if (inputOptions.length != selectedItems.length && selectedItems.length > 0)
if (!enabledItems || !selectedEnabledItems) return 'NONE'
if (enabledItems.length === selectedEnabledItems.length) return 'ALL'
if (
enabledItems.length != selectedEnabledItems.length &&
selectedEnabledItems.length > 0
)
return 'SOME'
return 'NONE'
}, [inputOptions, selectedItems])
}, [enabledItems, selectedEnabledItems])

const toggleAllSelected = () => {
if (selectedItems.length === inputOptions.length) {
setSelectedItems([])
if (selectedEnabledItems.length === enabledItems.length) {
setSelectedItems([...selectedDisabledItemsSet])
} else {
setSelectedItems(inputOptions)
setSelectedItems([...enabledItems, ...selectedDisabledItemsSet])
}
}

Expand Down Expand Up @@ -631,9 +647,7 @@ function AutocompleteInner<T>(
placeholderText =
typeof placeholderText !== 'undefined'
? placeholderText
: `${selectedItems.length}/${
options.length - disabledItems.length
} selected`
: `${selectedItems.length}/${inputOptions.length} selected`
comboBoxProps = {
...comboBoxProps,
selectedItem: null,
Expand Down Expand Up @@ -763,7 +777,8 @@ function AutocompleteInner<T>(

const clear = () => {
resetCombobox()
resetSelection()
//dont clear items if they are selected and disabled
setSelectedItems([...selectedDisabledItemsSet])
setTypedInputValue('')
}
const showClearButton =
Expand Down

0 comments on commit 83a78c7

Please sign in to comment.