import React, { useEffect, useState } from 'react'; import { CollectionFilterState, DropdownCollectionFilterState, } from '../../state'; import { CollectionState, FiltersMap, TextOverflowState } from '@wix/bex-core'; import { useWixPatternsContainer } from '@wix/bex-core/react'; import { observer } from 'mobx-react-lite'; import { KeyedItemOption, MultiSelectCheckboxFilterBase, MultiSelectCheckboxFilterBaseProps, } from '../MultiSelectCheckboxFilterBase'; import { ListItem } from '../../hooks'; import { InputOverflow } from '../InputOverflow'; import { useFilterToolbarState, useDropdownTranslationContext, } from '../../providers'; import { useCollectionFilterInitialFetchTiming, CollectionFilterInitialFetchTimingProps, } from '../../hooks/useCollectionFilterInitialFetchTiming'; import { useFilterCollectionStates } from '../../hooks/useFilterCollectionStates'; import { useCollectionOptions } from '../../hooks/useCollectionOptions'; import { useDropdownPlaceholder } from '../../hooks/useDropdownPlaceholder'; export interface CollectionMultiSelectCheckboxProps< V, F extends FiltersMap = FiltersMap, > extends Omit< MultiSelectCheckboxFilterBaseProps, 'options' | 'dropdownSelect' >, CollectionFilterInitialFetchTimingProps { /** * A collection state object to fetch the dropdown items.
* A collection created using [useFilterCollection](./?path=/story/features-filter-hooks--usefiltercollection) or [useStaticListFilterCollection](./?path=/story/features-filter-hooks--usestaticlistfiltercollection) * @external */ collection: CollectionState; /** * A function that returns a [ListItemSelectProps](https://www.docs.wixdesignsystem.com/?path=/story/components-form-dropdownlistitems--listitemselect) (Optional) */ renderItem?: (item: V, index: number) => ListItem; /** * The maximum number of items that can be selected. Once reached, every * unselected option becomes disabled (already-selected options stay * deselectable). When undefined, selection is unbounded. * * Read once on mount — later changes to this prop are ignored. (Optional) */ maxSelected?: number; } function _CollectionMultiSelectCheckbox( props: CollectionMultiSelectCheckboxProps, ) { const { filter, collection, renderItem, onSelect, onClose, onOptionsShow, onDeselect, placeholder: placeholderProp, maxSelected, ...rest } = props; const container = useWixPatternsContainer(); const toolbar = useFilterToolbarState(); const { translate } = useDropdownTranslationContext(); const [collectionFilter] = useState( () => new CollectionFilterState({ collection, filter, }), ); const [dropdownCollectionFilterState] = useState( () => new DropdownCollectionFilterState({ resetOnClose: false, collectionFilter, container, toolbar, maxSelected, }), ); const { dropdownSelect, init, inputState, shouldShowPlaceholder, inputValue, } = dropdownCollectionFilterState; const { disableEditing } = inputState; const { select: { selectedKeys, selectedValues }, } = dropdownSelect; const [textOverflowState] = useState( () => new TextOverflowState({ observable: () => dropdownSelect.select.selectedValues, }), ); const { isOverflow } = textOverflowState; const { fetchedLastPage } = collection; const { fixedFooter, showInitialLoader } = useFilterCollectionStates({ collection, fixedFooter: rest.fixedFooter, }); const { skipInitialFetch, onFocus } = useCollectionFilterInitialFetchTiming(props); useEffect(() => init({ skipInitialFetch }), []); const { selectedValuesText, placeholder } = useDropdownPlaceholder({ dropdownSelect, filter, shouldShowPlaceholder, isOverflow, placeholderProp, }); const { options } = useCollectionOptions({ collection, dropdownCollectionFilterState, renderItem, filter, }); return ( { if (!dropdownSelect.hasPendingFilter) { dropdownSelect.closeAndChangeSelectedItems(); } else { dropdownSelect.close(); } inputState.onBlur(); onClose?.(); }} onSelect={(id, option) => { const { keyedItem } = option as KeyedItemOption; dropdownSelect.set(keyedItem); onSelect?.(id, option); }} onDeselect={(id, option) => { const { keyedItem } = option as KeyedItemOption; dropdownSelect.delete(keyedItem); onDeselect?.(id, option); }} value={inputValue} onFocus={() => { inputState.onFocus(); onFocus(); }} onBlur={() => { inputState.onBlur(); }} onChange={(e) => { collection.search(e.target.value, { clearResult: true }); }} onOptionsShow={() => { dropdownCollectionFilterState.onOptionsShow(); inputState.onOptionsShow(); onOptionsShow?.(); }} onKeyDown={(e) => { if (e.nativeEvent.code === 'Tab') { inputState.onTabKeyDown(); } }} onClickOutside={(e) => { props.onClickOutside?.(e); inputState.onClickOutside(); }} onClear={() => { inputState.onBlur(); collection.clearSearch(); }} disableEditing={disableEditing} placeholder={placeholder} clearButton={!disableEditing} clearButtonTooltipContent={translate('clearButtonTooltip')} focusOnClearClick inputElement={ 0} focused={inputState.isFocused} text={selectedValuesText} state={textOverflowState} /> } /> ); } export const CollectionMultiSelectCheckbox = observer( _CollectionMultiSelectCheckbox, );