UNPKG

@awsui/components-react

Version:

AWS UI is a collection of [React](https://reactjs.org/) components that help create intuitive, responsive, and accessible user experiences for web applications. It is developed by Amazon Web Services (AWS). This work is available under the terms of the [A

105 lines (104 loc) 8.18 kB
import { __assign, __rest, __spreadArrays } from "tslib"; import React, { useCallback, useMemo, useState, useRef } from 'react'; import clsx from 'clsx'; import styles from './styles.css.js'; import Dropdown from '../internal/components/dropdown'; import DropdownStatus from '../internal/components/dropdown-status'; import Filter from '../select/parts/filter'; import Trigger from '../select/parts/trigger'; import SelectedTokens from '../internal/components/selected-tokens'; import { LiveRegion } from '../internal/components/live-region'; import { getBaseProps } from '../internal/base-component'; import { flattenOptions } from '../internal/components/option/utils/flatten-options'; import { filterOptions } from '../internal/components/option/utils/filter-options'; import { useSelect } from '../select/utils/use-select'; import { fireNonCancelableEvent } from '../internal/events'; import { useSelectedTokens } from './utils/use-selected-tokens'; import { useLoadItems } from '../select/utils/use-load-items'; import { useAnnouncement } from '../select/utils/use-announcement'; import { useFocusTracker } from '../internal/hooks/use-focus-tracker'; import { useFormFieldContext } from '../internal/context/form-field-context'; import { findOptionIndex } from '../select/utils/connect-options'; import { generateTestIndexes } from '../internal/components/options-list/utils/test-indexes'; import PlainList from '../select/parts/plain-list'; import VirtualList from '../select/parts/virtual-list'; import { useTelemetry } from '../internal/hooks/use-telemetry'; var InternalMultiselect = React.forwardRef(function (_a, externalRef) { var _b; var _c = _a.options, options = _c === void 0 ? [] : _c, _d = _a.filteringType, filteringType = _d === void 0 ? 'none' : _d, filteringPlaceholder = _a.filteringPlaceholder, filteringAriaLabel = _a.filteringAriaLabel, ariaRequired = _a.ariaRequired, placeholder = _a.placeholder, disabled = _a.disabled, ariaLabel = _a.ariaLabel, _e = _a.statusType, statusType = _e === void 0 ? 'finished' : _e, empty = _a.empty, loadingText = _a.loadingText, finishedText = _a.finishedText, errorText = _a.errorText, recoveryText = _a.recoveryText, noMatch = _a.noMatch, selectedAriaLabel = _a.selectedAriaLabel, renderHighlightedAriaLive = _a.renderHighlightedAriaLive, _f = _a.selectedOptions, selectedOptions = _f === void 0 ? [] : _f, deselectAriaLabel = _a.deselectAriaLabel, _g = _a.keepOpen, keepOpen = _g === void 0 ? true : _g, tokenLimit = _a.tokenLimit, i18nStrings = _a.i18nStrings, onBlur = _a.onBlur, onFocus = _a.onFocus, onLoadItems = _a.onLoadItems, onChange = _a.onChange, virtualScroll = _a.virtualScroll, _h = _a.__hideTokens, __hideTokens = _h === void 0 ? false : _h, restProps = __rest(_a, ["options", "filteringType", "filteringPlaceholder", "filteringAriaLabel", "ariaRequired", "placeholder", "disabled", "ariaLabel", "statusType", "empty", "loadingText", "finishedText", "errorText", "recoveryText", "noMatch", "selectedAriaLabel", "renderHighlightedAriaLive", "selectedOptions", "deselectAriaLabel", "keepOpen", "tokenLimit", "i18nStrings", "onBlur", "onFocus", "onLoadItems", "onChange", "virtualScroll", "__hideTokens"]); useTelemetry('Multiselect'); var baseProps = getBaseProps(restProps); var formFieldContext = useFormFieldContext(restProps); var _j = useLoadItems({ onLoadItems: onLoadItems, options: options, statusType: statusType }), fireDelayedInput = _j.fireDelayedInput, handleLoadMore = _j.handleLoadMore, handleRecoveryClick = _j.handleRecoveryClick, fireLoadItems = _j.fireLoadItems; var _k = useState(''), filteringValue = _k[0], setFilteringValue = _k[1]; var updateSelectedOption = useCallback(function (option) { var newSelectedOptions = __spreadArrays(selectedOptions); var index = findOptionIndex(newSelectedOptions, option); if (index > -1) { newSelectedOptions.splice(index, 1); } else { newSelectedOptions.push(option); } fireNonCancelableEvent(onChange, { selectedOptions: newSelectedOptions }); }, [onChange, selectedOptions]); var _l = useMemo(function () { return flattenOptions(options); }, [options]), flatOptions = _l.flatOptions, parentMap = _l.parentMap; var filteredOptions = useMemo(function () { if (filteringType !== 'auto') { return flatOptions; } return filterOptions(flatOptions, filteringValue); }, [flatOptions, filteringType, filteringValue]); generateTestIndexes(filteredOptions, parentMap.get.bind(parentMap)); var rootRef = useRef(); useFocusTracker({ rootRef: rootRef, onBlur: onBlur, onFocus: onFocus }); var scrollToIndex = useRef(null); var _m = useSelect({ selectedOptions: selectedOptions, updateSelectedOption: updateSelectedOption, options: filteredOptions, filteringType: filteringType, rootRef: rootRef, externalRef: externalRef, keepOpen: keepOpen, multiSelection: true, fireLoadItems: fireLoadItems, setFilteringValue: setFilteringValue, scrollToIndex: (_b = scrollToIndex.current) !== null && _b !== void 0 ? _b : undefined }), isOpen = _m.isOpen, highlightedOption = _m.highlightedOption, getTriggerProps = _m.getTriggerProps, getFilterProps = _m.getFilterProps, getMenuProps = _m.getMenuProps, getDropdownProps = _m.getDropdownProps, getOptionProps = _m.getOptionProps, isKeyboard = _m.isKeyboard, resetHighlight = _m.resetHighlight, announceSelected = _m.announceSelected; var filter = (React.createElement(Filter, { filteringType: filteringType, filteringPlaceholder: filteringPlaceholder, filteringAriaLabel: filteringAriaLabel, ariaRequired: ariaRequired, filterProps: getFilterProps(), filteringValue: filteringValue, setFilteringValue: setFilteringValue, resetHighlight: resetHighlight, fireDelayedInput: fireDelayedInput })); var trigger = (React.createElement(Trigger, __assign({ placeholder: placeholder, disabled: disabled, ariaLabel: ariaLabel, triggerProps: getTriggerProps(disabled), selectedOption: null, isOpen: isOpen }, formFieldContext))); var dropdownProps = __assign({ trigger: trigger, header: filter }, getDropdownProps()); var menuProps = __assign(__assign({}, getMenuProps()), { onLoadMore: handleLoadMore }); var dropdownStatus = (React.createElement(DropdownStatus, { statusType: statusType, empty: empty, loadingText: loadingText, finishedText: finishedText, errorText: errorText, recoveryText: recoveryText, noMatch: noMatch, onRecoveryClick: handleRecoveryClick, isNoMatch: filteredOptions && filteredOptions.length === 0, isEmpty: !options || options.length === 0 })); var announcement = useAnnouncement({ announceSelected: announceSelected, highlightedOption: highlightedOption, parentMap: parentMap, selectedAriaLabel: selectedAriaLabel, renderHighlightedAriaLive: renderHighlightedAriaLive }); var selectedTokensProps = useSelectedTokens({ disabled: disabled, tokenLimit: tokenLimit, i18nStrings: i18nStrings, selectedOptions: selectedOptions, updateSelectedOption: updateSelectedOption, updateFocus: function () { return getTriggerProps().ref.current.focus(); } }); var ListComponent = virtualScroll ? VirtualList : PlainList; return (React.createElement("div", __assign({}, baseProps, { ref: rootRef, className: clsx(styles.root, baseProps.className) }), React.createElement(Dropdown, __assign({}, dropdownProps), React.createElement(ListComponent, { menuProps: menuProps, getOptionProps: getOptionProps, filteredOptions: filteredOptions, filteringValue: filteringValue, isKeyboard: isKeyboard, dropdownStatus: dropdownStatus, ref: scrollToIndex, checkboxes: true })), !__hideTokens && React.createElement(SelectedTokens, __assign({}, selectedTokensProps, { deselectAriaLabel: deselectAriaLabel })), isKeyboard && React.createElement(LiveRegion, { message: announcement }))); }); export default InternalMultiselect;