@coreui/react-pro
Version:
UI Components Library for React.js
216 lines (212 loc) • 15.7 kB
JavaScript
'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