react-elegant-ui
Version:
Elegant UI components, made by BEM best practices for react
114 lines • 4.37 kB
JavaScript
var __assign = this && this.__assign || function () {
__assign = Object.assign || function (t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __rest = this && this.__rest || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
}
return t;
};
import React, { useMemo } from 'react';
import { useComponentRegistry } from '../../lib/di';
import { cn } from '@bem-react/classname';
import { getTextOfItem as getTextOfOption, flattenItems } from '../Menu/Menu';
import './Select.css';
import './Trigger/Select-Trigger.css';
export var cnSelect = cn('Select');
export { getTextOfItem as getTextOfOption, isGroup } from '../Menu/Menu';
export var getTextOfSelectedOptions = function (options, value, opts) {
var _a = opts || {},
_b = _a.separator,
separator = _b === void 0 ? ', ' : _b,
_c = _a.isRemoveHiddenItems,
isRemoveHiddenItems = _c === void 0 ? false : _c,
_d = _a.isRemoveHiddenGroups,
isRemoveHiddenGroups = _d === void 0 ? false : _d;
// Convert to value array
var values = [].concat(value !== null && value !== void 0 ? value : []);
// Skip empty value
if (values.length === 0) {
return '';
}
// Collect map `value: index`
// optimization to prevent search in array
var valuesIndexMap = {};
values.forEach(function (value, idx) {
valuesIndexMap[value] = idx;
});
// Make array with static size to prevent dynamic memory allocations
var textsList = Array(values.length);
var flattenOptions = flattenItems(options, isRemoveHiddenGroups);
// iterate options instead values for performance with large options list
// O(options**values) instead O(values**options) in bad case
flattenOptions.forEach(function (option) {
// Optionally skip hidden options
if (isRemoveHiddenItems && option.hidden) return;
var value = option.id;
var valueIndex = valuesIndexMap[value];
// Skip options that is not selected
if (valueIndex === undefined) return;
var text = getTextOfOption(option);
// Skip options with empty text
if (text.length === 0) return;
// Write option text by value index
// it need to keep values order
textsList[valueIndex] = text;
});
// Remove empty slots
var filteredTexts = textsList.filter(function (text) {
return text !== undefined;
});
return filteredTexts.join(separator);
};
export var defaultProps = {
placeholder: '—',
value: ''
};
export var Select = function (_a) {
var disabled = _a.disabled,
opened = _a.opened,
setOpened = _a.setOpened,
value = _a.value,
setValue = _a.setValue,
className = _a.className,
placeholder = _a.placeholder,
innerRef = _a.innerRef,
triggerRef = _a.triggerRef,
addonBefore = _a.addonBefore,
addonAfter = _a.addonAfter,
options = _a.options,
props = __rest(_a, ["disabled", "opened", "setOpened", "value", "setValue", "className", "placeholder", "innerRef", "triggerRef", "addonBefore", "addonAfter", "options"]);
var isMultiselectable = Array.isArray(value);
// Update value text
var selectedOptionsText = useMemo(function () {
return getTextOfSelectedOptions(options, value);
}, [options, value]);
var selectText = selectedOptionsText.length > 0 ? selectedOptionsText : placeholder;
var Trigger = useComponentRegistry(cnSelect()).Trigger;
return /*#__PURE__*/React.createElement("span", __assign({
className: cnSelect({
disabled: disabled,
opened: opened
}, [className]),
ref: innerRef
}, props), addonBefore, /*#__PURE__*/React.createElement(Trigger, {
tabIndex: disabled ? -1 : 0,
disabled: disabled,
innerRef: triggerRef,
role: "listbox",
"aria-haspopup": "listbox",
"aria-label": selectText,
"aria-expanded": opened,
"aria-multiselectable": isMultiselectable
}, selectText), addonAfter);
};
Select.defaultProps = defaultProps;