UNPKG

@gechiui/components

Version:
169 lines (142 loc) 5.42 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CustomSelectControl; var _element = require("@gechiui/element"); var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _downshift = require("downshift"); var _classnames = _interopRequireDefault(require("classnames")); var _icons = require("@gechiui/icons"); var _i18n = require("@gechiui/i18n"); var _ = require("../"); /** * External dependencies */ /** * GeChiUI dependencies */ /** * Internal dependencies */ const itemToString = item => item === null || item === void 0 ? void 0 : item.name; // This is needed so that in Windows, where // the menu does not necessarily open on // key up/down, you can still switch between // options with the menu closed. const stateReducer = (_ref, _ref2) => { let { selectedItem } = _ref; let { type, changes, props: { items } } = _ref2; switch (type) { case _downshift.useSelect.stateChangeTypes.ToggleButtonKeyDownArrowDown: // If we already have a selected item, try to select the next one, // without circular navigation. Otherwise, select the first item. return { selectedItem: items[selectedItem ? Math.min(items.indexOf(selectedItem) + 1, items.length - 1) : 0] }; case _downshift.useSelect.stateChangeTypes.ToggleButtonKeyDownArrowUp: // If we already have a selected item, try to select the previous one, // without circular navigation. Otherwise, select the last item. return { selectedItem: items[selectedItem ? Math.max(items.indexOf(selectedItem) - 1, 0) : items.length - 1] }; default: return changes; } }; function CustomSelectControl(_ref3) { var _menuProps$ariaActiv; let { className, hideLabelFromVision, label, describedBy, options: items, onChange: onSelectedItemChange, value: _selectedItem } = _ref3; const { getLabelProps, getToggleButtonProps, getMenuProps, getItemProps, isOpen, highlightedIndex, selectedItem } = (0, _downshift.useSelect)({ initialSelectedItem: items[0], items, itemToString, onSelectedItemChange, ...(typeof _selectedItem !== 'undefined' && _selectedItem !== null ? { selectedItem: _selectedItem } : undefined), stateReducer }); function getDescribedBy() { if (describedBy) { return describedBy; } if (!selectedItem) { return (0, _i18n.__)('暂无选择'); } // translators: %s: The selected option. return (0, _i18n.sprintf)((0, _i18n.__)('当前选择:%s'), selectedItem.name); } const menuProps = getMenuProps({ className: 'components-custom-select-control__menu', 'aria-hidden': !isOpen }); const onKeyDownHandler = (0, _element.useCallback)(e => { var _menuProps$onKeyDown; e.stopPropagation(); menuProps === null || menuProps === void 0 ? void 0 : (_menuProps$onKeyDown = menuProps.onKeyDown) === null || _menuProps$onKeyDown === void 0 ? void 0 : _menuProps$onKeyDown.call(menuProps, e); }, [menuProps]); // We need this here, because the null active descendant is not fully ARIA compliant. if ((_menuProps$ariaActiv = menuProps['aria-activedescendant']) !== null && _menuProps$ariaActiv !== void 0 && _menuProps$ariaActiv.startsWith('downshift-null')) { delete menuProps['aria-activedescendant']; } return (0, _element.createElement)("div", { className: (0, _classnames.default)('components-custom-select-control', className) }, hideLabelFromVision ? (0, _element.createElement)(_.VisuallyHidden, (0, _extends2.default)({ as: "label" }, getLabelProps()), label) : /* eslint-disable-next-line jsx-a11y/label-has-associated-control, jsx-a11y/label-has-for */ (0, _element.createElement)("label", getLabelProps({ className: 'components-custom-select-control__label' }), label), (0, _element.createElement)(_.Button, getToggleButtonProps({ // This is needed because some speech recognition software don't support `aria-labelledby`. 'aria-label': label, 'aria-labelledby': undefined, className: 'components-custom-select-control__button', isSmall: true, describedBy: getDescribedBy() }), itemToString(selectedItem), (0, _element.createElement)(_icons.Icon, { icon: _icons.chevronDown, className: "components-custom-select-control__button-icon" })), (0, _element.createElement)("ul", (0, _extends2.default)({}, menuProps, { onKeyDown: onKeyDownHandler }), isOpen && items.map((item, index) => // eslint-disable-next-line react/jsx-key (0, _element.createElement)("li", getItemProps({ item, index, key: item.key, className: (0, _classnames.default)(item.className, 'components-custom-select-control__item', { 'is-highlighted': index === highlightedIndex, 'has-hint': !!item.__experimentalHint }), style: item.style }), item.name, item.__experimentalHint && (0, _element.createElement)("span", { className: "components-custom-select-control__item-hint" }, item.__experimentalHint), item === selectedItem && (0, _element.createElement)(_icons.Icon, { icon: _icons.check, className: "components-custom-select-control__item-icon" }))))); } //# sourceMappingURL=index.js.map