'use client'
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var src_exports = {};
__export(src_exports, {
Menu: () => Menu,
MenuButton: () => MenuButton,
MenuCommand: () => MenuCommand,
MenuDescendantsProvider: () => MenuDescendantsProvider,
MenuDivider: () => MenuDivider,
MenuGroup: () => MenuGroup,
MenuIcon: () => MenuIcon,
MenuItem: () => MenuItem,
MenuItemOption: () => MenuItemOption,
MenuList: () => MenuList,
MenuOptionGroup: () => MenuOptionGroup,
MenuProvider: () => MenuProvider,
useMenu: () => useMenu,
useMenuButton: () => useMenuButton,
useMenuContext: () => useMenuContext,
useMenuDescendant: () => useMenuDescendant,
useMenuDescendants: () => useMenuDescendants,
useMenuDescendantsContext: () => useMenuDescendantsContext,
useMenuItem: () => useMenuItem,
useMenuList: () => useMenuList,
useMenuOption: () => useMenuOption,
useMenuOptionGroup: () => useMenuOptionGroup,
useMenuPositioner: () => useMenuPositioner,
useMenuState: () => useMenuState,
useMenuStyles: () => useMenuStyles
});
module.exports = __toCommonJS(src_exports);
// src/menu.tsx
var import_react_context2 = require("@chakra-ui/react-context");
var import_system = require("@chakra-ui/system");
var import_shared_utils2 = require("@chakra-ui/shared-utils");
var import_react3 = require("react");
// src/use-menu.ts
var import_clickable = require("@chakra-ui/clickable");
var import_descendant = require("@chakra-ui/descendant");
var import_react_use_focus_effect = require("@chakra-ui/react-use-focus-effect");
var import_popper = require("@chakra-ui/popper");
var import_react_use_disclosure = require("@chakra-ui/react-use-disclosure");
var import_react_use_outside_click = require("@chakra-ui/react-use-outside-click");
var import_react_use_animation_state = require("@chakra-ui/react-use-animation-state");
var import_react_context = require("@chakra-ui/react-context");
var import_react_children_utils = require("@chakra-ui/react-children-utils");
var import_react_use_controllable_state = require("@chakra-ui/react-use-controllable-state");
var import_react_use_update_effect = require("@chakra-ui/react-use-update-effect");
var import_react_use_merge_refs = require("@chakra-ui/react-use-merge-refs");
var import_shared_utils = require("@chakra-ui/shared-utils");
var import_lazy_utils = require("@chakra-ui/lazy-utils");
var import_react2 = require("react");
// src/use-shortcut.ts
var import_react = require("react");
function isPrintableCharacter(event) {
const { key } = event;
return key.length === 1 || key.length > 1 && /[^a-zA-Z0-9]/.test(key);
}
function useShortcut(props = {}) {
const { timeout = 300, preventDefault = () => true } = props;
const [keys, setKeys] = (0, import_react.useState)([]);
const timeoutRef = (0, import_react.useRef)();
const flush = () => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
timeoutRef.current = null;
}
};
const clearKeysAfterDelay = () => {
flush();
timeoutRef.current = setTimeout(() => {
setKeys([]);
timeoutRef.current = null;
}, timeout);
};
(0, import_react.useEffect)(() => flush, []);
function onKeyDown(fn) {
return (event) => {
if (event.key === "Backspace") {
const keysCopy = [...keys];
keysCopy.pop();
setKeys(keysCopy);
return;
}
if (isPrintableCharacter(event)) {
const keysCopy = keys.concat(event.key);
if (preventDefault(event)) {
event.preventDefault();
event.stopPropagation();
}
setKeys(keysCopy);
fn(keysCopy.join(""));
clearKeysAfterDelay();
}
};
}
return onKeyDown;
}
// src/get-next-item-from-search.ts
function getNextItemFromSearch(items, searchString, itemToString, currentItem) {
if (searchString == null) {
return currentItem;
}
if (!currentItem) {
const foundItem = items.find(
(item) => itemToString(item).toLowerCase().startsWith(searchString.toLowerCase())
);
return foundItem;
}
const matchingItems = items.filter(
(item) => itemToString(item).toLowerCase().startsWith(searchString.toLowerCase())
);
if (matchingItems.length > 0) {
let nextIndex;
if (matchingItems.includes(currentItem)) {
const currentIndex = matchingItems.indexOf(currentItem);
nextIndex = currentIndex + 1;
if (nextIndex === matchingItems.length) {
nextIndex = 0;
}
return matchingItems[nextIndex];
}
nextIndex = items.indexOf(matchingItems[0]);
return items[nextIndex];
}
return currentItem;
}
// src/use-menu.ts
var [
MenuDescendantsProvider,
useMenuDescendantsContext,
useMenuDescendants,
useMenuDescendant
] = (0, import_descendant.createDescendantContext)();
var [MenuProvider, useMenuContext] = (0, import_react_context.createContext)({
strict: false,
name: "MenuContext"
});
function useIds(idProp, ...prefixes) {
const reactId = (0, import_react2.useId)();
const id = idProp || reactId;
return (0, import_react2.useMemo)(() => {
return prefixes.map((prefix) => `${prefix}-${id}`);
}, [id, prefixes]);
}
function getOwnerDocument(node) {
var _a;
return (_a = node == null ? void 0 : node.ownerDocument) != null ? _a : document;
}
function isActiveElement(element) {
const doc = getOwnerDocument(element);
return doc.activeElement === element;
}
function useMenu(props = {}) {
const {
id,
closeOnSelect = true,
closeOnBlur = true,
initialFocusRef,
autoSelect = true,
isLazy,
isOpen: isOpenProp,
defaultIsOpen,
onClose: onCloseProp,
onOpen: onOpenProp,
placement = "bottom-start",
lazyBehavior = "unmount",
direction,
computePositionOnMount = false,
...popperProps
} = props;
const menuRef = (0, import_react2.useRef)(null);
const buttonRef = (0, import_react2.useRef)(null);
const descendants = useMenuDescendants();
const focusMenu = (0, import_react2.useCallback)(() => {
requestAnimationFrame(() => {
var _a;
(_a = menuRef.current) == null ? void 0 : _a.focus({ preventScroll: false });
});
}, []);
const focusFirstItem = (0, import_react2.useCallback)(() => {
const id2 = setTimeout(() => {
var _a;
if (initialFocusRef) {
(_a = initialFocusRef.current) == null ? void 0 : _a.focus();
} else {
const first = descendants.firstEnabled();
if (first)
setFocusedIndex(first.index);
}
});
timeoutIds.current.add(id2);
}, [descendants, initialFocusRef]);
const focusLastItem = (0, import_react2.useCallback)(() => {
const id2 = setTimeout(() => {
const last = descendants.lastEnabled();
if (last)
setFocusedIndex(last.index);
});
timeoutIds.current.add(id2);
}, [descendants]);
const onOpenInternal = (0, import_react2.useCallback)(() => {
onOpenProp == null ? void 0 : onOpenProp();
if (autoSelect) {
focusFirstItem();
} else {
focusMenu();
}
}, [autoSelect, focusFirstItem, focusMenu, onOpenProp]);
const { isOpen, onOpen, onClose, onToggle } = (0, import_react_use_disclosure.useDisclosure)({
isOpen: isOpenProp,
defaultIsOpen,
onClose: onCloseProp,
onOpen: onOpenInternal
});
(0, import_react_use_outside_click.useOutsideClick)({
enabled: isOpen && closeOnBlur,
ref: menuRef,
handler: (event) => {
var _a;
if (!((_a = buttonRef.current) == null ? void 0 : _a.contains(event.target))) {
onClose();
}
}
});
const popper = (0, import_popper.usePopper)({
...popperProps,
enabled: isOpen || computePositionOnMount,
placement,
direction
});
const [focusedIndex, setFocusedIndex] = (0, import_react2.useState)(-1);
(0, import_react_use_update_effect.useUpdateEffect)(() => {
if (!isOpen) {
setFocusedIndex(-1);
}
}, [isOpen]);
(0, import_react_use_focus_effect.useFocusOnHide)(menuRef, {
focusRef: buttonRef,
visible: isOpen,
shouldFocus: true
});
const animationState = (0, import_react_use_animation_state.useAnimationState)({ isOpen, ref: menuRef });
const [buttonId, menuId] = useIds(id, `menu-button`, `menu-list`);
const openAndFocusMenu = (0, import_react2.useCallback)(() => {
onOpen();
focusMenu();
}, [onOpen, focusMenu]);
const timeoutIds = (0, import_react2.useRef)(/* @__PURE__ */ new Set([]));
(0, import_react2.useEffect)(() => {
const ids = timeoutIds.current;
return () => {
ids.forEach((id2) => clearTimeout(id2));
ids.clear();
};
}, []);
const openAndFocusFirstItem = (0, import_react2.useCallback)(() => {
onOpen();
focusFirstItem();
}, [focusFirstItem, onOpen]);
const openAndFocusLastItem = (0, import_react2.useCallback)(() => {
onOpen();
focusLastItem();
}, [onOpen, focusLastItem]);
const refocus = (0, import_react2.useCallback)(() => {
var _a, _b;
const doc = getOwnerDocument(menuRef.current);
const hasFocusWithin = (_a = menuRef.current) == null ? void 0 : _a.contains(doc.activeElement);
const shouldRefocus = isOpen && !hasFocusWithin;
if (!shouldRefocus)
return;
const node = (_b = descendants.item(focusedIndex)) == null ? void 0 : _b.node;
node == null ? void 0 : node.focus({ preventScroll: true });
}, [isOpen, focusedIndex, descendants]);
const rafId = (0, import_react2.useRef)(null);
return {
openAndFocusMenu,
openAndFocusFirstItem,
openAndFocusLastItem,
onTransitionEnd: refocus,
unstable__animationState: animationState,
descendants,
popper,
buttonId,
menuId,
forceUpdate: popper.forceUpdate,
orientation: "vertical",
isOpen,
onToggle,
onOpen,
onClose,
menuRef,
buttonRef,
focusedIndex,
closeOnSelect,
closeOnBlur,
autoSelect,
setFocusedIndex,
isLazy,
lazyBehavior,
initialFocusRef,
rafId
};
}
function useMenuButton(props = {}, externalRef = null) {
const menu = useMenuContext();
const { onToggle, popper, openAndFocusFirstItem, openAndFocusLastItem } = menu;
const onKeyDown = (0, import_react2.useCallback)(
(event) => {
const eventKey = event.key;
const keyMap = {
Enter: openAndFocusFirstItem,
ArrowDown: openAndFocusFirstItem,
ArrowUp: openAndFocusLastItem
};
const action = keyMap[eventKey];
if (action) {
event.preventDefault();
event.stopPropagation();
action(event);
}
},
[openAndFocusFirstItem, openAndFocusLastItem]
);
return {
...props,
ref: (0, import_react_use_merge_refs.mergeRefs)(menu.buttonRef, externalRef, popper.referenceRef),
id: menu.buttonId,
"data-active": (0, import_shared_utils.dataAttr)(menu.isOpen),
"aria-expanded": menu.isOpen,
"aria-haspopup": "menu",
"aria-controls": menu.menuId,
onClick: (0, import_shared_utils.callAllHandlers)(props.onClick, onToggle),
onKeyDown: (0, import_shared_utils.callAllHandlers)(props.onKeyDown, onKeyDown)
};
}
function isTargetMenuItem(target) {
var _a;
return isHTMLElement(target) && !!((_a = target == null ? void 0 : target.getAttribute("role")) == null ? void 0 : _a.startsWith("menuitem"));
}
function useMenuList(props = {}, ref = null) {
const menu = useMenuContext();
if (!menu) {
throw new Error(
`useMenuContext: context is undefined. Seems you forgot to wrap component within