UNPKG

@coreui/react-pro

Version:

UI Components Library for React.js

216 lines (212 loc) 15.7 kB
'use strict'; var tslib_es6 = require('../../node_modules/tslib/tslib.es6.js'); var React = require('react'); var index = require('../../node_modules/classnames/index.js'); var PropTypes = require('prop-types'); var CFormControlWrapper = require('../form/CFormControlWrapper.js'); var CMultiSelectNativeSelect = require('./CMultiSelectNativeSelect.js'); var CMultiSelectOptions = require('./CMultiSelectOptions.js'); var CMultiSelectSelection = require('./CMultiSelectSelection.js'); var useForkedRef = require('../../hooks/useForkedRef.js'); var usePopper = require('../../hooks/usePopper.js'); var isRTL = require('../../utils/isRTL.js'); var utils = require('./utils.js'); var CMultiSelect = React.forwardRef(function (_a, ref) { var _b; var allowCreateOptions = _a.allowCreateOptions, className = _a.className, _c = _a.cleaner, cleaner = _c === void 0 ? true : _c, clearSearchOnSelect = _a.clearSearchOnSelect, disabled = _a.disabled, feedback = _a.feedback, feedbackInvalid = _a.feedbackInvalid, feedbackValid = _a.feedbackValid, id = _a.id, invalid = _a.invalid, label = _a.label, loading = _a.loading, _d = _a.multiple, multiple = _d === void 0 ? true : _d, name = _a.name, onChange = _a.onChange, onFilterChange = _a.onFilterChange, onHide = _a.onHide, onShow = _a.onShow, options = _a.options, _e = _a.optionsMaxHeight, optionsMaxHeight = _e === void 0 ? 'auto' : _e, _f = _a.optionsStyle, optionsStyle = _f === void 0 ? 'checkbox' : _f, optionsTemplate = _a.optionsTemplate, optionsGroupsTemplate = _a.optionsGroupsTemplate, _g = _a.placeholder, placeholder = _g === void 0 ? 'Select...' : _g, required = _a.required, _h = _a.resetSelectionOnOptionsChange, resetSelectionOnOptionsChange = _h === void 0 ? false : _h, _j = _a.search, search = _j === void 0 ? true : _j, _k = _a.searchNoResultsLabel, searchNoResultsLabel = _k === void 0 ? 'No results found' : _k, _l = _a.selectAll, selectAll = _l === void 0 ? true : _l, _m = _a.selectAllLabel, selectAllLabel = _m === void 0 ? 'Select all options' : _m, _o = _a.selectionType, selectionType = _o === void 0 ? 'tags' : _o, _p = _a.selectionTypeCounterText, selectionTypeCounterText = _p === void 0 ? 'item(s) selected' : _p, size = _a.size, text = _a.text, tooltipFeedback = _a.tooltipFeedback, valid = _a.valid, virtualScroller = _a.virtualScroller, _q = _a.visible, visible = _q === void 0 ? false : _q, _r = _a.visibleItems, visibleItems = _r === void 0 ? 10 : _r, rest = tslib_es6.__rest(_a, ["allowCreateOptions", "className", "cleaner", "clearSearchOnSelect", "disabled", "feedback", "feedbackInvalid", "feedbackValid", "id", "invalid", "label", "loading", "multiple", "name", "onChange", "onFilterChange", "onHide", "onShow", "options", "optionsMaxHeight", "optionsStyle", "optionsTemplate", "optionsGroupsTemplate", "placeholder", "required", "resetSelectionOnOptionsChange", "search", "searchNoResultsLabel", "selectAll", "selectAllLabel", "selectionType", "selectionTypeCounterText", "size", "text", "tooltipFeedback", "valid", "virtualScroller", "visible", "visibleItems"]); var multiSelectRef = React.useRef(null); var multiSelectForkedRef = useForkedRef.useForkedRef(ref, multiSelectRef); var dropdownRef = React.useRef(null); var nativeSelectRef = React.useRef(null); var togglerRef = React.useRef(null); var searchRef = React.useRef(null); var isInitialMount = React.useRef(true); var _s = usePopper.usePopper(), popper = _s.popper, initPopper = _s.initPopper, destroyPopper = _s.destroyPopper; var _t = React.useState(options), _options = _t[0], setOptions = _t[1]; var _u = React.useState(visible), _visible = _u[0], setVisible = _u[1]; var _v = React.useState(''), searchValue = _v[0], setSearchValue = _v[1]; var _w = React.useState([]), selected = _w[0], setSelected = _w[1]; var _x = React.useState([]), userOptions = _x[0], setUserOptions = _x[1]; var filteredOptions = React.useMemo(function () { return utils.flattenOptionsArray(search === 'external' ? tslib_es6.__spreadArray(tslib_es6.__spreadArray([], _options, true), utils.filterOptionsList(searchValue, userOptions), true) : utils.filterOptionsList(searchValue, tslib_es6.__spreadArray(tslib_es6.__spreadArray([], _options, true), userOptions, true)), true); }, [_options, searchValue, userOptions]); var flattenedOptions = React.useMemo(function () { return utils.flattenOptionsArray(options); }, [JSON.stringify(options)]); var userOption = React.useMemo(function () { if (allowCreateOptions && filteredOptions.some(function (option) { return option.label && option.label.toLowerCase() === searchValue.toLowerCase(); })) { return false; } return searchRef.current && utils.createOption(String(searchValue), flattenedOptions); }, [filteredOptions, searchValue]); var popperConfig = { placement: (isRTL.default(multiSelectRef.current) ? 'bottom-end' : 'bottom-start'), modifiers: [ { name: 'preventOverflow', options: { boundary: 'clippingParents', }, }, { name: 'offset', options: { offset: [0, 2], }, }, ], }; React.useEffect(function () { setOptions(options); if (resetSelectionOnOptionsChange) { return setSelected([]); } var _selected = flattenedOptions.filter(function (option) { return option.selected === true; }); var deselected = flattenedOptions.filter(function (option) { return option.selected === false; }); _selected && setSelected(utils.selectOptions(_selected, selected, deselected)); }, [JSON.stringify(options)]); React.useEffect(function () { !isInitialMount.current && onFilterChange && onFilterChange(searchValue); }, [searchValue]); React.useEffect(function () { if (!isInitialMount.current && nativeSelectRef.current) { nativeSelectRef.current.dispatchEvent(new Event('change', { bubbles: true })); } if (popper) { popper.update(); } }, [JSON.stringify(selected)]); React.useEffect(function () { if (_visible) { onShow && onShow(); window.addEventListener('mouseup', handleMouseUp); window.addEventListener('keyup', handleKeyUp); togglerRef.current && dropdownRef.current && initPopper(togglerRef.current, dropdownRef.current, popperConfig); searchRef.current && searchRef.current.focus(); } return function () { onHide && onHide(); setSearchValue(''); if (searchRef.current) { searchRef.current.value = ''; } window.removeEventListener('mouseup', handleMouseUp); window.removeEventListener('keyup', handleKeyUp); destroyPopper(); }; }, [_visible]); React.useEffect(function () { isInitialMount.current = false; }, []); var handleKeyUp = function (event) { if (event.key === 'Escape') { setVisible(false); } }; var handleMouseUp = function (event) { if (multiSelectRef.current && multiSelectRef.current.contains(event.target)) { return; } setVisible(false); }; var handleSearchChange = function (event) { var value = event.target.value; setSearchValue(value); }; var handleSearchKeyDown = function (event) { if (event.key === 'Enter' && searchValue && allowCreateOptions) { event.preventDefault(); if (userOption) { setSelected(tslib_es6.__spreadArray(tslib_es6.__spreadArray([], selected, true), userOption, true)); setUserOptions(tslib_es6.__spreadArray(tslib_es6.__spreadArray([], userOptions, true), userOption, true)); } if (!userOption) { setSelected(tslib_es6.__spreadArray(tslib_es6.__spreadArray([], selected, true), [ filteredOptions.find(function (option) { return String(option.label).toLowerCase() === searchValue.toLowerCase(); }), ], false)); } setSearchValue(''); if (searchRef.current) { searchRef.current.value = ''; } return; } if (searchValue.length > 0) { return; } if (event.key === 'Backspace' || event.key === 'Delete') { var last_1 = selected.filter(function (option) { return !option.disabled; }).pop(); last_1 && setSelected(selected.filter(function (option) { return option.value !== last_1.value; })); } }; var handleOptionOnClick = function (option) { if (!multiple) { setSelected([option]); setVisible(false); setSearchValue(''); if (searchRef.current) { searchRef.current.value = ''; } return; } if (option.custom && !userOptions.some(function (_option) { return _option.value === option.value; })) { setUserOptions(tslib_es6.__spreadArray(tslib_es6.__spreadArray([], userOptions, true), [option], false)); } if (clearSearchOnSelect || option.custom) { setSearchValue(''); if (searchRef.current) { searchRef.current.value = ''; searchRef.current.focus(); } } if (selected.some(function (_option) { return _option.value === option.value; })) { setSelected(selected.filter(function (_option) { return _option.value !== option.value; })); } else { setSelected(tslib_es6.__spreadArray(tslib_es6.__spreadArray([], selected, true), [option], false)); } }; var handleSelectAll = function () { setSelected(utils.selectOptions(tslib_es6.__spreadArray(tslib_es6.__spreadArray([], flattenedOptions.filter(function (option) { return !option.disabled; }), true), userOptions, true), selected)); }; var handleDeselectAll = function () { setSelected(selected.filter(function (option) { return option.disabled; })); }; return (React.createElement(CFormControlWrapper.CFormControlWrapper, { describedby: rest['aria-describedby'], feedback: feedback, feedbackInvalid: feedbackInvalid, feedbackValid: feedbackValid, id: id, invalid: invalid, label: label, text: text, tooltipFeedback: tooltipFeedback, valid: valid }, React.createElement(CMultiSelectNativeSelect.CMultiSelectNativeSelect, { id: id, multiple: multiple, name: name, options: selected, required: required, value: multiple ? selected.map(function (option) { return option.value.toString(); }) : selected.map(function (option) { return option.value; })[0], onChange: function () { return onChange && onChange(selected); }, ref: nativeSelectRef }), React.createElement("div", { className: index.default('form-multi-select', (_b = {}, _b["form-multi-select-".concat(size)] = size, _b.disabled = disabled, _b['is-invalid'] = invalid, _b['is-valid'] = valid, _b.show = _visible, _b), className), "aria-expanded": _visible, ref: multiSelectForkedRef }, React.createElement("div", { className: "form-multi-select-input-group", onClick: function () { return setVisible(true); }, ref: togglerRef }, React.createElement(CMultiSelectSelection.CMultiSelectSelection, { multiple: multiple, onRemove: function (option) { return !disabled && handleOptionOnClick(option); }, placeholder: placeholder, search: search, selected: selected, selectionType: selectionType, selectionTypeCounterText: selectionTypeCounterText }, search && (React.createElement("input", tslib_es6.__assign({ type: "text", className: "form-multi-select-search", disabled: disabled, autoComplete: "off", onChange: handleSearchChange, onKeyDown: handleSearchKeyDown }, (selected.length === 0 && { placeholder: placeholder }), (selected.length > 0 && selectionType === 'counter' && { placeholder: "".concat(selected.length, " ").concat(selectionTypeCounterText), }), (selected.length > 0 && !multiple && { placeholder: selected.map(function (option) { return option.label; })[0] }), (multiple && selected.length > 0 && selectionType !== 'counter' && { size: searchValue.length + 2 }), { ref: searchRef })))), React.createElement("div", { className: "form-multi-select-buttons" }, !disabled && cleaner && selected.length > 0 && (React.createElement("button", { type: "button", className: "form-multi-select-cleaner", onClick: function () { return handleDeselectAll(); } })), React.createElement("button", { type: "button", className: "form-multi-select-indicator", onClick: function (event) { event.preventDefault(); event.stopPropagation(); setVisible(!_visible); } }))), React.createElement("div", { className: "form-multi-select-dropdown", role: "menu", ref: dropdownRef }, multiple && selectAll && (React.createElement("button", { type: "button", className: "form-multi-select-all", onClick: function () { return handleSelectAll(); } }, selectAllLabel)), React.createElement(CMultiSelectOptions.CMultiSelectOptions, { handleOptionOnClick: function (option) { return !disabled && handleOptionOnClick(option); }, loading: loading, options: filteredOptions.length === 0 && allowCreateOptions ? userOption || [] : filteredOptions, optionsMaxHeight: optionsMaxHeight, optionsStyle: optionsStyle, optionsTemplate: optionsTemplate, optionsGroupsTemplate: optionsGroupsTemplate, searchNoResultsLabel: searchNoResultsLabel, selected: selected, virtualScroller: virtualScroller, visibleItems: visibleItems }))))); }); CMultiSelect.propTypes = tslib_es6.__assign({ className: PropTypes.string, cleaner: PropTypes.bool, clearSearchOnSelect: PropTypes.bool, disabled: PropTypes.bool, loading: PropTypes.bool, multiple: PropTypes.bool, name: PropTypes.string, onChange: PropTypes.func, onFilterChange: PropTypes.func, onHide: PropTypes.func, onShow: PropTypes.func, options: PropTypes.array.isRequired, optionsMaxHeight: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), optionsStyle: PropTypes.oneOf(['checkbox', 'text']), optionsTemplate: PropTypes.func, optionsGroupsTemplate: PropTypes.func, placeholder: PropTypes.string, required: PropTypes.bool, resetSelectionOnOptionsChange: PropTypes.bool, search: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['external'])]), searchNoResultsLabel: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), selectAll: PropTypes.bool, selectAllLabel: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), selectionType: PropTypes.oneOf(['counter', 'tags', 'text']), selectionTypeCounterText: PropTypes.string, size: PropTypes.oneOf(['sm', 'lg']), virtualScroller: PropTypes.bool, visible: PropTypes.bool, visibleItems: PropTypes.number }, CFormControlWrapper.CFormControlWrapper.propTypes); CMultiSelect.displayName = 'CMultiSelect'; exports.CMultiSelect = CMultiSelect; //# sourceMappingURL=CMultiSelect.js.map