UNPKG

@momentum-ui/react-collaboration

Version:

Cisco Momentum UI Framework for React Collaboration Applications

153 lines 8.46 kB
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); }; /* eslint-disable @typescript-eslint/ban-types */ /* eslint-disable @typescript-eslint/ban-ts-comment */ import React, { useCallback, useRef, forwardRef, useState, useEffect, } from 'react'; import classnames from 'classnames'; import './Select.style.scss'; import { DEFAULTS, STYLE } from './Select.constants'; import { useSelectState } from '@react-stately/select'; import { useButton } from '@react-aria/button'; import { HiddenSelect, useSelect } from '@react-aria/select'; import Icon from '../Icon'; import ListBoxBase from '../ListBoxBase'; import Popover from '../Popover'; import Text from '../Text'; import { useSpatialNavigationContext } from '../SpatialNavigationProvider/SpatialNavigationProvider.utils'; import { useKeyboard } from '@react-aria/interactions'; /** * @deprecated Use the equivalent from momentum.design (NPM: `@momentum-design/components/dist/react`) */ function Select(props, ref) { var _a, _b, _c; var _d, _e; var ariaLabelledBy = props["aria-labelledby"], className = props.className, style = props.style, id = props.id, isDisabled = props.isDisabled, label = props.label, name = props.name, placeholder = props.placeholder, _f = props.direction, direction = _f === void 0 ? DEFAULTS.DIRECTION : _f, title = props.title, _g = props.showBorder, showBorder = _g === void 0 ? DEFAULTS.SHOULD_SHOW_BORDER : _g, listboxMaxHeight = props.listboxMaxHeight, _h = props.isInForm, isInForm = _h === void 0 ? DEFAULTS.IS_IN_FORM : _h, listboxWidth = props.listboxWidth, shallowDisabled = props.shallowDisabled, popoverSingleOpenGroupId = props.popoverSingleOpenGroupId; var _j = useState(), popoverInstance = _j[0], setPopoverInstance = _j[1]; var hasBeenOpened = useRef(false); var selectRef = useRef(null); var boxRef = useRef(null); var spatialNav = useSpatialNavigationContext(); var state = useSelectState(props); var _k = useSelect(props, state, selectRef), labelProps = _k.labelProps, triggerProps = _k.triggerProps, valueProps = _k.valueProps, menuProps = _k.menuProps; var buttonProps = useButton(__assign(__assign(__assign({}, triggerProps), { isDisabled: isDisabled }), (ariaLabelledBy === '' ? { 'aria-labelledby': null } : ariaLabelledBy ? { 'aria-labelledby': ariaLabelledBy } : {})), selectRef).buttonProps; var ariaActivedesecendant = (menuProps === null || menuProps === void 0 ? void 0 : menuProps.id) && ((_d = state === null || state === void 0 ? void 0 : state.selectionManager) === null || _d === void 0 ? void 0 : _d.focusedKey) && "".concat(menuProps.id, "-option-").concat(state.selectionManager.focusedKey); delete buttonProps.color; delete buttonProps.onKeyDown; var getArrowIcon = function (isOpen) { return (isOpen ? 'arrow-up' : 'arrow-down'); }; var handleFocusBackOnTrigger = useCallback(function () { var _a; (_a = selectRef.current) === null || _a === void 0 ? void 0 : _a.focus(); }, []); useEffect(function () { if (popoverInstance) { if (state.isOpen) { // show popover once state changes to isOpen = true popoverInstance.show(); hasBeenOpened.current = true; } else { // hide popover once state changes to isOpen = false popoverInstance.hide(); if (hasBeenOpened.current) { // only do this if it has been opened previously to prevent unexpected focus handleFocusBackOnTrigger(); } } } }, [state.isOpen, popoverInstance, handleFocusBackOnTrigger]); /** * Handle closeOnSelect from @react-aria manually */ var closePopover = useCallback(function () { state.close(); }, [state]); /** * Handle onKeyDown from @react-aria manually */ var onKeyDown = useCallback(function (e) { if (spatialNav) { return; } switch (e.key) { // useButton already provides Keyboard event support for Enter and Space case 'ArrowUp': case 'ArrowDown': e.preventDefault(); state.open(); break; } }, [spatialNav, state]); var otherProps = shallowDisabled ? { 'aria-disabled': true, 'data-shallow-disabled': true, onMouseDown: function (e) { e.currentTarget.focus(); }, onKeyDown: function (e) { if (e.key !== 'Tab') { e.preventDefault(); } }, onPointerDown: undefined, } : { onKeyDown: onKeyDown, }; var triggerComponent = (React.createElement("button", __assign({ id: name }, buttonProps, { role: "combobox", "aria-expanded": !!state.isOpen, "aria-controls": id, "aria-activedescendant": ariaActivedesecendant, className: classnames(STYLE.dropdownInput, (_a = {}, _a[STYLE.selected] = state.selectedItem, _a), (_b = {}, _b[STYLE.open] = state.isOpen, _b), (_c = {}, _c[STYLE.borderLess] = !showBorder, _c)), title: title }, otherProps), React.createElement("span", __assign({ title: (_e = state.selectedItem) === null || _e === void 0 ? void 0 : _e.textValue }, valueProps, { className: STYLE.selectedItemWrapper }), state.selectedItem ? state.selectedItem.rendered : placeholder), React.createElement("span", { "aria-hidden": "true", className: STYLE.iconWrapper }, React.createElement(Icon, { name: getArrowIcon(state.isOpen), weight: "bold", scale: 16 })))); // special handling for spatial navigation var keyboardProps = useKeyboard({ onKeyDown: function (event) { if (spatialNav && event.key === spatialNav.back) { closePopover(); event.nativeEvent.stopImmediatePropagation(); } }, }).keyboardProps; // delete color prop which is passed down and used in the ModalContainer // because it conflicts with the HTML color property delete keyboardProps.color; return (React.createElement("div", { className: classnames(className, STYLE.wrapper), ref: ref, /* @ts-ignore: next-line */ style: __assign({ '--local-width': listboxWidth || '100%' }, style), id: id }, label && (React.createElement("label", __assign({ htmlFor: name }, labelProps), React.createElement(Text, { tagName: "p" }, label))), isInForm && (React.createElement(HiddenSelect, { isDisabled: isDisabled, state: state, triggerRef: selectRef, label: label, name: name })), React.createElement(Popover, __assign({ interactive: true, showArrow: false, // remove role of Popover ModalContainer since the listbox role is passed through the ListBoxBase component via menuProps // eslint-disable-next-line jsx-a11y/aria-role role: null, triggerComponent: React.cloneElement(triggerComponent, { ref: selectRef, }), trigger: "manual", setInstance: setPopoverInstance, placement: direction, onClickOutside: closePopover, onHide: closePopover, hideOnEsc: !spatialNav, style: { maxHeight: listboxMaxHeight || 'none' }, className: STYLE.popover, strategy: listboxWidth ? 'fixed' : 'absolute', singleOpenGroupId: popoverSingleOpenGroupId }, (spatialNav ? keyboardProps : {})), React.createElement(ListBoxBase, __assign({}, menuProps, { ref: boxRef, state: state, disallowEmptySelection: true, // eslint-disable-next-line jsx-a11y/no-autofocus autoFocus: state.focusStrategy || DEFAULTS.FOCUS_STRATEGY, className: STYLE.menuListBox }))))); } /** * Dropdown / Select Element which displays a listbox with options. */ /** * @deprecated Use the equivalent from momentum.design (NPM: `@momentum-design/components/dist/react`) */ var _Select = forwardRef(Select); _Select.displayName = 'Select'; export default _Select; //# sourceMappingURL=Select.js.map