jobiqo-cl
Version:
[](https://circleci.com/gh/jobiqo/jobiqo-cl)
953 lines (823 loc) • 29.2 kB
JavaScript
;
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;