UNPKG

@coreui/react-pro

Version:

UI Components Library for React.js

98 lines (95 loc) 6 kB
import React, { forwardRef } from 'react'; import PropTypes from 'prop-types'; import classNames from '../../_virtual/index.js'; import { CElementCover } from '../element-cover/CElementCover.js'; import { CVirtualScroller } from '../virtual-scroller/CVirtualScroller.js'; import getNextSibling from '../../utils/getNextSibling.js'; import getPreviousSibling from '../../utils/getPreviousSibling.js'; const CMultiSelectOptions = forwardRef(({ loading, onGroupOnClick, onKeyDown, onOptionOnClick, options, optionsMaxHeight, optionsStyle, optionsTemplate, optionsGroupsSelectable, optionsGroupsStyle, optionsGroupsTemplate, searchNoResultsLabel, selected, virtualScroller, visibleItems = 10, }, ref) => { const handleKeyDown = (event, option) => { if (event.code === 'Space' || event.key === 'Enter') { event.preventDefault(); onOptionOnClick === null || onOptionOnClick === void 0 ? void 0 : onOptionOnClick(option); } if (event.key === 'Down' || event.key === 'ArrowDown') { event.preventDefault(); const target = event.target; const next = getNextSibling(target, '.form-multi-select-option'); next && next.focus(); } if (event.key === 'Up' || event.key === 'ArrowUp') { event.preventDefault(); const target = event.target; const prev = getPreviousSibling(target, '.form-multi-select-option'); prev && prev.focus(); } }; const handleGroupKeyDown = (event, group) => { if (event.code === 'Space' || event.key === 'Enter') { event.preventDefault(); onGroupOnClick === null || onGroupOnClick === void 0 ? void 0 : onGroupOnClick(group); return; } if (event.key === 'Down' || event.key === 'ArrowDown') { event.preventDefault(); const next = getNextSibling(event.target, '.form-multi-select-option'); next && next.focus(); } if (event.key === 'Up' || event.key === 'ArrowUp') { event.preventDefault(); const prev = getPreviousSibling(event.target, '.form-multi-select-option'); prev && prev.focus(); } }; const getGroupCheckboxState = (group) => { var _a; const groupOptions = ((_a = group.options) !== null && _a !== void 0 ? _a : []).filter((option) => !option.disabled); const selectedCount = groupOptions.filter((option) => selected.some((_option) => _option.value === option.value)).length; if (groupOptions.length > 0 && selectedCount >= groupOptions.length) { return 'all'; } return selectedCount === 0 ? 'none' : 'indeterminate'; }; const createOptions = (options) => options.length > 0 ? (options.map((option, index) => 'value' in option ? (React.createElement("div", { className: classNames('form-multi-select-option', { 'form-multi-select-option-with-checkbox': optionsStyle === 'checkbox', 'form-multi-selected': selected.some((_option) => _option.value === option.value), disabled: option.disabled, }), key: index, onClick: () => onOptionOnClick && onOptionOnClick(option), onKeyDown: (event) => handleKeyDown(event, option), tabIndex: 0, role: "option", "aria-selected": selected.some((_option) => _option.value === option.value), "aria-disabled": Boolean(option.disabled) }, optionsTemplate ? optionsTemplate(option) : option.label)) : (React.createElement("div", Object.assign({ className: classNames('form-multi-select-optgroup-label', { 'form-multi-select-optgroup-label-with-checkbox': optionsGroupsSelectable && optionsGroupsStyle === 'checkbox', 'form-multi-selected': optionsGroupsSelectable && optionsGroupsStyle === 'checkbox' && getGroupCheckboxState(option) === 'all', 'form-multi-select-indeterminate': optionsGroupsSelectable && optionsGroupsStyle === 'checkbox' && getGroupCheckboxState(option) === 'indeterminate', }), key: index }, (optionsGroupsSelectable && optionsGroupsStyle === 'checkbox' && { onClick: () => onGroupOnClick === null || onGroupOnClick === void 0 ? void 0 : onGroupOnClick(option), onKeyDown: (event) => handleGroupKeyDown(event, option), tabIndex: 0, role: 'button', })), optionsGroupsTemplate ? optionsGroupsTemplate(option) : option.label)))) : (React.createElement("div", { className: "form-multi-select-options-empty", role: "status" }, searchNoResultsLabel)); return (React.createElement(React.Fragment, null, virtualScroller ? (React.createElement(CVirtualScroller, { className: "form-multi-select-options", onKeyDown: onKeyDown, visibleItems: visibleItems, ref: ref }, createOptions(options))) : (React.createElement("div", Object.assign({ className: "form-multi-select-options", onKeyDown: onKeyDown }, (optionsMaxHeight !== 'auto' && { style: { maxHeight: optionsMaxHeight, overflow: 'scroll' }, }), { ref: ref }), createOptions(options))), loading && React.createElement(CElementCover, null))); }); CMultiSelectOptions.propTypes = { loading: PropTypes.bool, onGroupOnClick: PropTypes.func, onOptionOnClick: PropTypes.func, options: PropTypes.array.isRequired, optionsMaxHeight: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), optionsStyle: PropTypes.oneOf(['checkbox', 'text']), optionsTemplate: PropTypes.func, optionsGroupsSelectable: PropTypes.bool, optionsGroupsStyle: PropTypes.oneOf(['checkbox', 'text']), optionsGroupsTemplate: PropTypes.func, searchNoResultsLabel: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), virtualScroller: PropTypes.bool, visibleItems: PropTypes.number, }; CMultiSelectOptions.displayName = 'CMultiSelectOptions'; export { CMultiSelectOptions }; //# sourceMappingURL=CMultiSelectOptions.js.map