UNPKG

jobiqo-cl

Version:

[![CircleCI](https://circleci.com/gh/jobiqo/jobiqo-cl.svg?style=svg&circle-token=5a24efa5b8bbc4879276123e77d0d3f35ca7144c)](https://circleci.com/gh/jobiqo/jobiqo-cl)

953 lines (823 loc) 29.2 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var React = require('react'); var React__default = _interopDefault(React); var index = require('../../../prop-types/index.js'); var index$2 = require('../../utils/es/index.js'); var index$4 = require('../../auto-id/es/index.js'); var index$5 = require('../../popover/es/index.js'); function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } // Actions var CLEAR_SELECTION_INDEX = "CLEAR_SELECTION_INDEX"; var CLICK_MENU_ITEM = "CLICK_MENU_ITEM"; var CLOSE_MENU = "CLOSE_MENU"; var OPEN_MENU_AT_FIRST_ITEM = "OPEN_MENU_AT_FIRST_ITEM"; var SEARCH_FOR_ITEM = "SEARCH_FOR_ITEM"; var SELECT_ITEM_AT_INDEX = "SELECT_ITEM_AT_INDEX"; var SET_BUTTON_ID = "SET_BUTTON_ID"; var DescendantContext = React.createContext(); var MenuContext = React.createContext(); var useDescendantContext = function useDescendantContext() { return React.useContext(DescendantContext); }; var useMenuContext = function useMenuContext() { return React.useContext(MenuContext); }; var initialState = { /* * The button ID is needed for aria controls and can be set directly and * updated for top-level use via context. Otherwise a default is set by useId. * TODO: Consider deprecating direct ID in 1.0 in favor of id at the top level * for passing deterministic IDs to descendent components. */ buttonId: null, /* * Whether or not the menu is expanded */ isOpen: false, /* * When a user begins typing a character string, the selection will change if * a matching item is found */ typeaheadQuery: "", /* * The index of the current selected item. When the selection is cleared a * value of -1 is used. */ selectionIndex: -1 }; //////////////////////////////////////////////////////////////////////////////// // Menu var Menu = function Menu(_ref) { var id = _ref.id, children = _ref.children; var buttonRef = React.useRef(null); var menuRef = React.useRef(null); var popoverRef = React.useRef(null); var _useDescendants = useDescendants(), descendants = _useDescendants[0], setDescendants = _useDescendants[1]; var _useReducer = React.useReducer(reducer, initialState), state = _useReducer[0], dispatch = _useReducer[1]; var menuId = index$4.useId(id); var context = { buttonRef: buttonRef, dispatch: dispatch, menuId: menuId, menuRef: menuRef, popoverRef: popoverRef, state: state }; React.useEffect(function () { return index$2.checkStyles("menu-button"); }, []); return React__default.createElement(DescendantProvider, { descendants: descendants, set: setDescendants }, React__default.createElement(MenuContext.Provider, { value: context }, typeof children === "function" ? children({ isOpen: state.isOpen }) : children)); }; Menu.displayName = "Menu"; if (process.env.NODE_ENV !== "production") { Menu.propTypes = { children: index.default.oneOfType([index.default.func, index.default.node]) }; } //////////////////////////////////////////////////////////////////////////////// // MenuButton var MenuButton = React.forwardRef(function MenuButton(_ref2, forwardedRef) { var onKeyDown = _ref2.onKeyDown, onMouseDown = _ref2.onMouseDown, id = _ref2.id, props = _objectWithoutPropertiesLoose(_ref2, ["onKeyDown", "onMouseDown", "id"]); var _useMenuContext = useMenuContext(), buttonRef = _useMenuContext.buttonRef, menuId = _useMenuContext.menuId, _useMenuContext$state = _useMenuContext.state, buttonId = _useMenuContext$state.buttonId, isOpen = _useMenuContext$state.isOpen, dispatch = _useMenuContext.dispatch; var ref = index$2.useForkedRef(buttonRef, forwardedRef); React.useEffect(function () { var newButtonId = id != null ? id : index$2.makeId("menu-button", menuId); if (buttonId !== newButtonId) { dispatch({ type: SET_BUTTON_ID, payload: newButtonId }); } }, [buttonId, dispatch, id, menuId]); function handleKeyDown(event) { switch (event.key) { case "ArrowDown": case "ArrowUp": event.preventDefault(); // prevent scroll dispatch({ type: OPEN_MENU_AT_FIRST_ITEM }); break; case "Enter": case " ": dispatch({ type: OPEN_MENU_AT_FIRST_ITEM }); break; } } function handleMouseDown() { dispatch({ type: isOpen ? CLOSE_MENU : OPEN_MENU_AT_FIRST_ITEM }); } return React__default.createElement("button", _extends({}, props, { ref: ref, "data-reach-menu-button": "", "aria-expanded": isOpen, "aria-haspopup": "menu", id: buttonId, onKeyDown: index$2.wrapEvent(onKeyDown, handleKeyDown), onMouseDown: index$2.wrapEvent(onMouseDown, handleMouseDown), type: "button" })); }); MenuButton.displayName = "MenuButton"; if (process.env.NODE_ENV !== "production") { MenuButton.propTypes = { children: index.default.node }; } //////////////////////////////////////////////////////////////////////////////// // MenuItemImpl // MenuItem and MenuLink share most of the same functionality captured here. var MenuItemImpl = React.forwardRef(function MenuItemImpl(_ref3, forwardedRef) { var Comp = _ref3.as, indexProp = _ref3.index, _ref3$isLink = _ref3.isLink, isLink = _ref3$isLink === void 0 ? false : _ref3$isLink, onClick = _ref3.onClick, onDragStart = _ref3.onDragStart, onKeyDown = _ref3.onKeyDown, onMouseDown = _ref3.onMouseDown, onMouseEnter = _ref3.onMouseEnter, onMouseLeave = _ref3.onMouseLeave, onMouseMove = _ref3.onMouseMove, onMouseUp = _ref3.onMouseUp, onSelect = _ref3.onSelect, valueTextProp = _ref3.valueText, props = _objectWithoutPropertiesLoose(_ref3, ["as", "index", "isLink", "onClick", "onDragStart", "onKeyDown", "onMouseDown", "onMouseEnter", "onMouseLeave", "onMouseMove", "onMouseUp", "onSelect", "valueText"]); var _useMenuContext2 = useMenuContext(), buttonRef = _useMenuContext2.buttonRef, dispatch = _useMenuContext2.dispatch, menuRef = _useMenuContext2.menuRef, _useMenuContext2$stat = _useMenuContext2.state, isOpen = _useMenuContext2$stat.isOpen, selectionIndex = _useMenuContext2$stat.selectionIndex; var ownRef = React.useRef(null); /* * After the ref is mounted to the DOM node, we check to see if we have an * explicit valueText prop before looking for the node's textContent for * typeahead functionality. */ var _useState = React.useState(valueTextProp || ""), valueText = _useState[0], setValueText = _useState[1]; var setValueTextFromDom = React.useCallback(function (node) { if (node) { ownRef.current = node; if (!valueTextProp || node.textContent && valueText !== node.textContent) { setValueText(node.textContent); } } }, [valueText, valueTextProp]); var ref = index$2.useForkedRef(forwardedRef, setValueTextFromDom); var mouseEventStarted = React.useRef(false); /* * By default, we assume valueText is a unique value for all menu items, so it * should be sufficient as an unique identifier we can use to find our index. * However there may be some use cases where this is not the case and an * explicit unique index may be provided by the app. */ var key = indexProp !== null && indexProp !== void 0 ? indexProp : valueText; var index = useDescendant(key, ownRef); var isSelected = index === selectionIndex; function select() { dispatch({ type: CLICK_MENU_ITEM, payload: { buttonRef: buttonRef, callback: onSelect } }); } function handleClick(event) { if (isLink && !isRightClick(event.nativeEvent)) { select(); } } function handleDragStart(event) { /* * Because we don't preventDefault on mousedown for links (we need the * native click event), clicking and holding on a link triggers a dragstart * which we don't want. */ if (isLink) { event.preventDefault(); } } function handleKeyDown(event) { if (event.key === "Enter" || event.key === " ") { /* * For links, the Enter key will trigger a click by default, but for * consistent behavior across menu items we'll trigger a click when the * spacebar is pressed. */ if (isLink) { if (event.key === " " && ownRef.current) { ownRef.current.click(); } } else { event.preventDefault(); select(); } } } function handleMouseDown(event) { if (isRightClick(event.nativeEvent)) return; if (isLink) { /* * Signal that the mouse is down so we can react call the right function * if the user is clicking on a link. */ mouseEventStarted.current = true; } else { event.preventDefault(); } } function handleMouseEnter(event) { if (!isSelected && index != null) { dispatch({ type: SELECT_ITEM_AT_INDEX, payload: { index: index } }); } } function handleMouseLeave(event) { // Clear out selection when mouse over a non-menu item child. dispatch({ type: CLEAR_SELECTION_INDEX }); } function handleMouseMove(event) { if (!isSelected && index != null) { dispatch({ type: SELECT_ITEM_AT_INDEX, payload: { index: index } }); } } function handleMouseUp(event) { if (isRightClick(event.nativeEvent)) return; if (isLink) { /* * If a mousedown event was initiated on a menu link followed be a mouseup * event on the same link, we do nothing; a click event will come next and * handle selection. Otherwise, we trigger a click event imperatively. */ if (mouseEventStarted.current) { mouseEventStarted.current = false; } else if (ownRef.current) { ownRef.current.click(); } } else { select(); } } /* * Any time a mouseup event occurs anywhere in the document, we reset the * mouseEventStarted ref so we can check it again when needed. */ React.useEffect(function () { var listener = function listener() { return mouseEventStarted.current = false; }; document.addEventListener("mouseup", listener); return function () { return document.removeEventListener("mouseup", listener); }; }, []); /** * When a new selection is made the item should receive focus. When no item is * selected, focus is placed on the menu itself so that keyboard navigation is * still possible. */ React.useEffect(function () { if (isOpen) { window.__REACH_DISABLE_TOOLTIPS = true; window.requestAnimationFrame(function () { if (selectionIndex !== -1) { /* * We haven't measured the popover yet, so give it a frame otherwise * we'll scroll to the bottom of the page >.< */ if (ownRef.current && index === selectionIndex) { ownRef.current.focus(); } } else { /* * Clear highlight when mousing over non-menu items, but focus the * menu so the the keyboard will work after a mouseover. */ menuRef.current && menuRef.current.focus(); } }); } else { /* * We want to ignore the immediate focus of a tooltip so it doesn't pop * up again when the menu closes, only pops up when focus returns again * to the tooltip (like native OS tooltips). */ window.__REACH_DISABLE_TOOLTIPS = false; } }, [index, isOpen, menuRef, selectionIndex]); return React__default.createElement(Comp, _extends({}, props, { ref: ref, "data-reach-menu-item": "", "data-selected": isSelected ? "" : undefined, "data-valuetext": valueText, onClick: index$2.wrapEvent(onClick, handleClick), onDragStart: index$2.wrapEvent(onDragStart, handleDragStart), onKeyDown: index$2.wrapEvent(onKeyDown, handleKeyDown), onMouseDown: index$2.wrapEvent(onMouseDown, handleMouseDown), onMouseEnter: index$2.wrapEvent(onMouseEnter, handleMouseEnter), onMouseLeave: index$2.wrapEvent(onMouseLeave, handleMouseLeave), onMouseMove: index$2.wrapEvent(onMouseMove, handleMouseMove), onMouseUp: index$2.wrapEvent(onMouseUp, handleMouseUp), role: "menuitem", tabIndex: -1 })); }); //////////////////////////////////////////////////////////////////////////////// // MenuItem var MenuItem = React.forwardRef(function MenuItem(_ref4, forwardedRef) { var _ref4$as = _ref4.as, as = _ref4$as === void 0 ? "div" : _ref4$as, props = _objectWithoutPropertiesLoose(_ref4, ["as"]); return React__default.createElement(MenuItemImpl, _extends({}, props, { ref: forwardedRef, as: as })); }); MenuItem.displayName = "MenuItem"; if (process.env.NODE_ENV !== "production") { MenuItem.propTypes = { as: index.default.any, onSelect: index.default.func.isRequired }; } //////////////////////////////////////////////////////////////////////////////// // MenuItems var MenuItems = React.forwardRef(function MenuItems(_ref5, forwardedRef) { var children = _ref5.children, onKeyDown = _ref5.onKeyDown, onBlur = _ref5.onBlur, props = _objectWithoutPropertiesLoose(_ref5, ["children", "onKeyDown", "onBlur"]); var _useMenuContext3 = useMenuContext(), dispatch = _useMenuContext3.dispatch, buttonRef = _useMenuContext3.buttonRef, menuRef = _useMenuContext3.menuRef, _useMenuContext3$stat = _useMenuContext3.state, isOpen = _useMenuContext3$stat.isOpen, buttonId = _useMenuContext3$stat.buttonId, selectionIndex = _useMenuContext3$stat.selectionIndex, typeaheadQuery = _useMenuContext3$stat.typeaheadQuery; var _useDescendantContext = useDescendantContext(), menuItems = _useDescendantContext.descendants; var ref = index$2.useForkedRef(menuRef, forwardedRef); React.useEffect(function () { // Respond to user char key input with typeahead var match = findItemFromTypeahead(menuItems, typeaheadQuery); if (typeaheadQuery && match != null) { dispatch({ type: SELECT_ITEM_AT_INDEX, payload: { index: match } }); } var timeout = window.setTimeout(function () { return typeaheadQuery && dispatch({ type: SEARCH_FOR_ITEM, payload: "" }); }, 1000); return function () { return window.clearTimeout(timeout); }; }, [dispatch, menuItems, typeaheadQuery]); var prevMenuItemsLength = index$2.usePrevious(menuItems.length); var prevSelected = index$2.usePrevious(menuItems[selectionIndex]); var prevSelectionIndex = index$2.usePrevious(selectionIndex); React.useEffect(function () { if (selectionIndex > menuItems.length - 1) { /* * If for some reason our selection index is larger than our possible * index range (let's say the last item is selected and the list * dynamically updates), we need to select the last item in the list. */ dispatch({ type: SELECT_ITEM_AT_INDEX, payload: { index: menuItems.length - 1 } }); } else if ( /* * Checks if * - menu length has changed * - selection index has not changed BUT selected item has changed * * This prevents any dynamic adding/removing of menu items from actually * changing a user's expected selection. */ prevMenuItemsLength !== menuItems.length && selectionIndex > -1 && prevSelected && prevSelectionIndex === selectionIndex && menuItems[selectionIndex] !== prevSelected) { dispatch({ type: SELECT_ITEM_AT_INDEX, payload: { index: menuItems.findIndex(function (i) { return i.key === prevSelected.key; }) } }); } }, [dispatch, menuItems, prevMenuItemsLength, prevSelected, prevSelectionIndex, selectionIndex]); function handleKeyDown(event) { var key = event.key; if (!isOpen) { return; } switch (key) { case "Escape": dispatch({ type: CLOSE_MENU, payload: { buttonRef: buttonRef } }); break; case "Home": // prevent window scroll event.preventDefault(); dispatch({ type: SELECT_ITEM_AT_INDEX, payload: { index: 0 } }); break; case "End": // prevent window scroll event.preventDefault(); dispatch({ type: SELECT_ITEM_AT_INDEX, payload: { index: menuItems.length - 1 } }); break; case "ArrowDown": // prevent window scroll event.preventDefault(); var nextIndex = Math.min(selectionIndex + 1, menuItems.length - 1); dispatch({ type: SELECT_ITEM_AT_INDEX, payload: { index: nextIndex } }); break; case "ArrowUp": // prevent window scroll event.preventDefault(); var prevIndex = Math.max(selectionIndex - 1, 0); dispatch({ type: SELECT_ITEM_AT_INDEX, payload: { index: prevIndex } }); break; case "Tab": // prevent leaving event.preventDefault(); break; default: /* * Check if a user is typing some char keys and respond by setting the * query state. */ if (typeof key === "string" && key.length === 1) { var query = typeaheadQuery + key.toLowerCase(); dispatch({ type: SEARCH_FOR_ITEM, payload: query }); } break; } } return React__default.createElement("div", _extends({}, props, { ref: ref, "data-reach-menu-items": "", "aria-labelledby": buttonId, onKeyDown: index$2.wrapEvent(onKeyDown, handleKeyDown), role: "menu", tabIndex: -1 }), children); }); MenuItems.displayName = "MenuItems"; if (process.env.NODE_ENV !== "production") { MenuItems.propTypes = { children: index.default.node }; } //////////////////////////////////////////////////////////////////////////////// // MenuLink var MenuLink = React.forwardRef(function MenuLink(_ref6, forwardedRef) { var _ref6$as = _ref6.as, as = _ref6$as === void 0 ? "a" : _ref6$as, component = _ref6.component, props = _objectWithoutPropertiesLoose(_ref6, ["as", "component"]); if (component) { console.warn("[@reach/menu-button]: Please use the `as` prop instead of `component`."); } return React__default.createElement("div", { role: "none", tabIndex: -1 }, React__default.createElement(MenuItemImpl, _extends({}, props, { ref: forwardedRef, "data-reach-menu-link": "", as: component || as, isLink: true }))); }); MenuLink.displayName = "MenuLink"; if (process.env.NODE_ENV !== "production") { MenuLink.propTypes = { as: index.default.any, component: index.default.any, onSelect: index.default.func }; } //////////////////////////////////////////////////////////////////////////////// // MenuList var MenuList = React.forwardRef(function MenuList(props, forwardedRef) { return React__default.createElement(MenuPopover, null, React__default.createElement(MenuItems, _extends({}, props, { ref: forwardedRef, "data-reach-menu-list": "" }))); }); MenuList.displayName = "MenuList"; if (process.env.NODE_ENV !== "production") { MenuList.propTypes = { children: index.default.node.isRequired }; } //////////////////////////////////////////////////////////////////////////////// // MenuPopover var MenuPopover = React.forwardRef(function MenuPopover(_ref7, forwardedRef) { var children = _ref7.children, onBlur = _ref7.onBlur, style = _ref7.style, props = _objectWithoutPropertiesLoose(_ref7, ["children", "onBlur", "style"]); var _useMenuContext4 = useMenuContext(), buttonRef = _useMenuContext4.buttonRef, dispatch = _useMenuContext4.dispatch, menuRef = _useMenuContext4.menuRef, popoverRef = _useMenuContext4.popoverRef, isOpen = _useMenuContext4.state.isOpen; var ref = index$2.useForkedRef(popoverRef, forwardedRef); function handleBlur(event) { var relatedTarget = event.relatedTarget; requestAnimationFrame(function () { // We on want to close only if focus rests outside the menu if (document.activeElement !== menuRef.current && document.activeElement !== buttonRef.current && popoverRef.current) { if (!popoverRef.current.contains(relatedTarget || document.activeElement)) { dispatch({ type: CLOSE_MENU }); } } }); } return isOpen ? React__default.createElement(index$5.default, _extends({}, props, { ref: ref, "data-reach-menu": "" // deprecate for naming consistency? , "data-reach-menu-popover": "", onBlur: index$2.wrapEvent(onBlur, handleBlur), targetRef: buttonRef }), children) : null; }); MenuPopover.displayName = "MenuPopover"; if (process.env.NODE_ENV !== "production") { MenuPopover.propTypes = { children: index.default.node }; } //////////////////////////////////////////////////////////////////////////////// /** * This hook registers our menu item by passing it into an array. We can then * search that array by a unique key to find its index. We use this for focus * management and keyboard navigation. */ function useDescendant(key, ref) { // If the key is a number, it's coming from an index prop. var indexProp = typeof key === "number" ? key : undefined; var _useState2 = React.useState(indexProp !== null && indexProp !== void 0 ? indexProp : -1), index = _useState2[0], setIndex = _useState2[1]; var _useDescendantContext2 = useDescendantContext(), descendants = _useDescendantContext2.descendants, registerDescendant = _useDescendantContext2.registerDescendant, deregisterDescendant = _useDescendantContext2.deregisterDescendant; React.useEffect(function () { // Descendants require a unique key. Skip updates if none exists. if (key == null) { return; } registerDescendant(key, ref); return function () { return void deregisterDescendant(key); }; }, [ref, registerDescendant, deregisterDescendant, key]); React.useEffect(function () { if (indexProp == null) { var newIndex = descendants.findIndex(function (i) { return i.key === key; }); if (newIndex !== index) { setIndex(newIndex); } } }, [descendants, key, index, indexProp]); if (indexProp != null && indexProp !== index) { setIndex(indexProp); } return index; } function useDescendants() { return React.useState([]); } function DescendantProvider(_ref8) { var children = _ref8.children, descendants = _ref8.descendants, set = _ref8.set; var registerDescendant = React.useCallback(function (key, ref) { set(function (items) { var newItem = { key: key, ref: ref }; /* * When registering a descendant, we need to make sure we insert in into * the array in the same order that it appears in the DOM. So as new * descendants are added or maybe some are removed, we always know that * the array is up-to-date and correct. * * So here we look at our registered descendants and see if the new * element we are adding appears earlier than an existing descendant's DOM * node via `node.compareDocumentPosition`. If it does, we insert the new * element at this index. Because `registerDescendant` will be called in * an effect every time the descendants state value changes, we should be * sure that this index is accurate when descendent elements come or go * from our component. */ var index = items.findIndex(function (el) { if (!el.ref.current || !ref.current) { return false; } /* * Does this element's DOM node appear before another item in the array * in our DOM tree? If so, return true to grab the index at this point * in the array so we know where to insert the new element. */ return Boolean(el.ref.current.compareDocumentPosition(ref.current) & Node.DOCUMENT_POSITION_PRECEDING); }); // If an index is not found we will push the element to the end. if (index === -1) { return [].concat(items, [newItem]); } return [].concat(items.slice(0, index), [newItem], items.slice(index)); }); }, [set]); var deregisterDescendant = React.useCallback(function (key) { set(function (items) { return items.filter(function (el) { return el.key !== key; }); }); }, [set]); return React__default.createElement(DescendantContext.Provider, { value: { descendants: descendants, registerDescendant: registerDescendant, deregisterDescendant: deregisterDescendant } }, children); } //////////////////////////////////////////////////////////////////////////////// /** * When a user's typed input matches the string displayed in a menu item, it is * expected that the matching menu item is selected. This is our matching * function. */ function findItemFromTypeahead(items, string) { if (string === void 0) { string = ""; } if (!string) { return null; } var found = items.find(function (_ref9) { var _ref$current, _ref$current$dataset, _ref$current$dataset$; var ref = _ref9.ref; return ref === null || ref === void 0 ? void 0 : (_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : (_ref$current$dataset = _ref$current.dataset) === null || _ref$current$dataset === void 0 ? void 0 : (_ref$current$dataset$ = _ref$current$dataset.valuetext) === null || _ref$current$dataset$ === void 0 ? void 0 : _ref$current$dataset$.toLowerCase().startsWith(string); }); return found ? items.indexOf(found) : null; } function isRightClick(nativeEvent) { if ("which" in nativeEvent) { return nativeEvent.which === 3; } else if ("button" in nativeEvent) { return nativeEvent.button === 2; } return false; } function reducer(state, action) { if (action === void 0) { action = {}; } var _action = action, payload = _action.payload, actionType = _action.type; switch (actionType) { case CLICK_MENU_ITEM: /* * Focus the button first by default when an item is selected. We fire the * onSelect callback next so the app can manage focus if needed. */ if (payload && payload.buttonRef && payload.buttonRef.current) { payload.buttonRef.current.focus(); } if (payload && payload.callback) { payload.callback(); } return _extends({}, state, { isOpen: false, selectionIndex: -1 }); case CLOSE_MENU: if (payload && payload.buttonRef && payload.buttonRef.current) { payload.buttonRef.current.focus(); } return _extends({}, state, { isOpen: false, selectionIndex: -1 }); case OPEN_MENU_AT_FIRST_ITEM: return _extends({}, state, { isOpen: true, selectionIndex: 0 }); case SELECT_ITEM_AT_INDEX: if (payload != null && payload.index >= 0) { return _extends({}, state, { selectionIndex: payload.max ? Math.min(Math.max(payload.index, 0), payload.max) : Math.max(payload.index, 0) }); } return state; case CLEAR_SELECTION_INDEX: return _extends({}, state, { selectionIndex: -1 }); case SET_BUTTON_ID: return _extends({}, state, { buttonId: payload }); case SEARCH_FOR_ITEM: if (typeof payload !== "undefined") { return _extends({}, state, { typeaheadQuery: payload }); } return state; default: return state; } } exports.Menu = Menu; exports.MenuButton = MenuButton; exports.MenuItem = MenuItem; exports.MenuItems = MenuItems; exports.MenuLink = MenuLink; exports.MenuList = MenuList; exports.MenuPopover = MenuPopover;