@ariakit/react-core
Version:
Ariakit React core
226 lines (224 loc) • 7.51 kB
JavaScript
"use client";
import {
useMenuList
} from "../__chunks/W5BTY3ZG.js";
import {
useHovercard
} from "../__chunks/IUFFNNPK.js";
import "../__chunks/X7QOZUD3.js";
import {
useMenuProviderContext
} from "../__chunks/4QTMCR75.js";
import "../__chunks/JUCYQ5OS.js";
import "../__chunks/7Z7JH52O.js";
import "../__chunks/OYOFZOGB.js";
import "../__chunks/C6DAL6ZN.js";
import {
createDialogComponent
} from "../__chunks/CAGBPNDP.js";
import "../__chunks/M5DFOEFU.js";
import "../__chunks/AOQQTIBO.js";
import "../__chunks/5M6RIVE2.js";
import "../__chunks/S2F2XXEH.js";
import "../__chunks/DXGKYUAD.js";
import "../__chunks/LC6GJMGV.js";
import "../__chunks/6GXEOXGT.js";
import "../__chunks/JZEJYXOQ.js";
import "../__chunks/HLTQOHKZ.js";
import "../__chunks/PVECYOSC.js";
import "../__chunks/SOMPWLIQ.js";
import "../__chunks/W6WVJJEY.js";
import "../__chunks/CZ4GFWYL.js";
import "../__chunks/Z5GCVBAY.js";
import "../__chunks/IGR4SXG2.js";
import "../__chunks/677M2CI3.js";
import "../__chunks/S7U6BLGA.js";
import "../__chunks/FVE2C5B3.js";
import "../__chunks/3NDVDEB4.js";
import "../__chunks/AOUGVQZ3.js";
import "../__chunks/K2ZF5NU7.js";
import "../__chunks/63XF7ACK.js";
import "../__chunks/K4R5DNTX.js";
import "../__chunks/Y2U4BRIM.js";
import "../__chunks/T22PY7TE.js";
import "../__chunks/NSTBQJLB.js";
import "../__chunks/5VQZOHHZ.js";
import "../__chunks/QJ4LGO2N.js";
import "../__chunks/Y67KZUMI.js";
import "../__chunks/T2AZQXQU.js";
import "../__chunks/ABN76PSX.js";
import "../__chunks/APTFW6PT.js";
import "../__chunks/OE2EFRVA.js";
import "../__chunks/SWN3JYXT.js";
import {
useStoreState
} from "../__chunks/RTNCFSKZ.js";
import "../__chunks/5CPL3B7G.js";
import {
createElement,
createHook,
forwardRef
} from "../__chunks/VOQWLFSQ.js";
import {
useMergeRefs
} from "../__chunks/5GGHRIN3.js";
import "../__chunks/SK3NAZA3.js";
import {
__objRest,
__spreadProps,
__spreadValues
} from "../__chunks/3YLGPPWQ.js";
// src/menu/menu.tsx
import { fireEvent } from "@ariakit/core/utils/events";
import { hasFocusWithin } from "@ariakit/core/utils/focus";
import { invariant, isFalsyBooleanCallback } from "@ariakit/core/utils/misc";
import { createRef, useEffect, useMemo, useRef, useState } from "react";
var TagName = "div";
var useMenu = createHook(function useMenu2(_a) {
var _b = _a, {
store,
modal: modalProp = false,
portal = !!modalProp,
hideOnEscape = true,
autoFocusOnShow = true,
hideOnHoverOutside,
alwaysVisible
} = _b, props = __objRest(_b, [
"store",
"modal",
"portal",
"hideOnEscape",
"autoFocusOnShow",
"hideOnHoverOutside",
"alwaysVisible"
]);
const context = useMenuProviderContext();
store = store || context;
invariant(
store,
process.env.NODE_ENV !== "production" && "Menu must receive a `store` prop or be wrapped in a MenuProvider component."
);
const ref = useRef(null);
const parentMenu = store.parent;
const parentMenubar = store.menubar;
const hasParentMenu = !!parentMenu;
const parentIsMenubar = !!parentMenubar && !hasParentMenu;
props = __spreadProps(__spreadValues({}, props), {
ref: useMergeRefs(ref, props.ref)
});
const _a2 = useMenuList(__spreadValues({
store,
alwaysVisible
}, props)), { "aria-labelledby": ariaLabelledBy } = _a2, menuListProps = __objRest(_a2, ["aria-labelledby"]);
props = menuListProps;
const [initialFocusRef, setInitialFocusRef] = useState();
const autoFocusOnShowState = store.useState("autoFocusOnShow");
const initialFocus = store.useState("initialFocus");
const baseElement = store.useState("baseElement");
const items = store.useState("renderedItems");
useEffect(() => {
let cleaning = false;
setInitialFocusRef((prevInitialFocusRef) => {
var _a3, _b2, _c;
if (cleaning) return;
if (!autoFocusOnShowState) return;
if ((_a3 = prevInitialFocusRef == null ? void 0 : prevInitialFocusRef.current) == null ? void 0 : _a3.isConnected) return prevInitialFocusRef;
const ref2 = createRef();
switch (initialFocus) {
// TODO: Refactor
case "first":
ref2.current = ((_b2 = items.find((item) => !item.disabled && item.element)) == null ? void 0 : _b2.element) || null;
break;
case "last":
ref2.current = ((_c = [...items].reverse().find((item) => !item.disabled && item.element)) == null ? void 0 : _c.element) || null;
break;
default:
ref2.current = baseElement;
}
return ref2;
});
return () => {
cleaning = true;
};
}, [store, autoFocusOnShowState, initialFocus, items, baseElement]);
const modal = hasParentMenu ? false : modalProp;
const mayAutoFocusOnShow = !!autoFocusOnShow;
const canAutoFocusOnShow = !!initialFocusRef || !!props.initialFocus || !!modal;
const contentElement = useStoreState(
store.combobox || store,
"contentElement"
);
const parentContentElement = useStoreState(
(parentMenu == null ? void 0 : parentMenu.combobox) || parentMenu,
"contentElement"
);
const preserveTabOrderAnchor = useMemo(() => {
if (!parentContentElement) return;
if (!contentElement) return;
const role = contentElement.getAttribute("role");
const parentRole = parentContentElement.getAttribute("role");
const parentIsMenuOrMenubar = parentRole === "menu" || parentRole === "menubar";
if (parentIsMenuOrMenubar && role === "menu") return;
return parentContentElement;
}, [contentElement, parentContentElement]);
if (preserveTabOrderAnchor !== void 0) {
props = __spreadValues({
preserveTabOrderAnchor
}, props);
}
props = useHovercard(__spreadProps(__spreadValues({
store,
alwaysVisible,
initialFocus: initialFocusRef,
autoFocusOnShow: mayAutoFocusOnShow ? canAutoFocusOnShow && autoFocusOnShow : autoFocusOnShowState || !!modal
}, props), {
hideOnEscape(event) {
if (isFalsyBooleanCallback(hideOnEscape, event)) return false;
store == null ? void 0 : store.hideAll();
return true;
},
hideOnHoverOutside(event) {
const disclosureElement = store == null ? void 0 : store.getState().disclosureElement;
const getHideOnHoverOutside = () => {
if (typeof hideOnHoverOutside === "function") {
return hideOnHoverOutside(event);
}
if (hideOnHoverOutside != null) return hideOnHoverOutside;
if (hasParentMenu) return true;
if (!parentIsMenubar) return false;
if (!disclosureElement) return true;
if (hasFocusWithin(disclosureElement)) return false;
return true;
};
if (!getHideOnHoverOutside()) return false;
if (event.defaultPrevented) return true;
if (!hasParentMenu) return true;
if (!disclosureElement) return true;
fireEvent(disclosureElement, "mouseout", event);
if (!hasFocusWithin(disclosureElement)) return true;
requestAnimationFrame(() => {
if (hasFocusWithin(disclosureElement)) return;
store == null ? void 0 : store.hide();
});
return false;
},
modal,
portal,
backdrop: hasParentMenu ? false : props.backdrop
}));
props = __spreadValues({
"aria-labelledby": ariaLabelledBy
}, props);
return props;
});
var Menu = createDialogComponent(
forwardRef(function Menu2(props) {
const htmlProps = useMenu(props);
return createElement(TagName, htmlProps);
}),
useMenuProviderContext
);
export {
Menu,
useMenu
};