@mantine/core
Version:
React components library focused on usability, accessibility and developer experience
113 lines (112 loc) • 3.97 kB
JavaScript
"use client";
import { useProps } from "../../../core/MantineProvider/use-props/use-props.mjs";
import { useDirection } from "../../../core/DirectionProvider/DirectionProvider.mjs";
import { getFloatingPosition } from "../../../utils/Floating/get-floating-position/get-floating-position.mjs";
import { Popover } from "../../Popover/Popover.mjs";
import { useMenuContext } from "../Menu.context.mjs";
import { SubMenuContext } from "./MenuSub.context.mjs";
import { MenuSubDropdown } from "../MenuSubDropdown/MenuSubDropdown.mjs";
import { MenuSubItem } from "../MenuSubItem/MenuSubItem.mjs";
import { MenuSubTarget } from "../MenuSubTarget/MenuSubTarget.mjs";
import { use, useCallback, useEffect, useRef } from "react";
import { useId as useId$1, useUncontrolled } from "@mantine/hooks";
import { jsx } from "react/jsx-runtime";
import { safePolygon, useFloating, useHover, useInteractions } from "@floating-ui/react";
//#region packages/@mantine/core/src/components/Menu/MenuSub/MenuSub.tsx
const defaultProps = {
offset: 0,
position: "right-start",
safeAreaPolygon: true,
transitionProps: { duration: 0 },
openDelay: 0,
middlewares: { shift: { crossAxis: true } }
};
function MenuSub(_props) {
const { children, closeDelay, openDelay, position, safeAreaPolygon, opened: openedProp, onChange, ...others } = useProps("MenuSub", defaultProps, _props);
const id = useId$1();
const [opened, setOpened] = useUncontrolled({
value: openedProp,
finalValue: false,
onChange
});
const parentSubCtx = use(SubMenuContext);
const menuCtx = useMenuContext();
const { dir } = useDirection();
const resolvedPosition = getFloatingPosition(dir, position);
const levelRegister = parentSubCtx?.registerOpenSub ?? menuCtx.registerOpenSub;
const activeChildCloseRef = useRef(null);
const registerOpenSub = useCallback((closeFn) => {
const prev = activeChildCloseRef.current;
if (prev && prev !== closeFn) prev();
activeChildCloseRef.current = closeFn;
return () => {
if (activeChildCloseRef.current === closeFn) activeChildCloseRef.current = null;
};
}, []);
const setOpenedRef = useRef(setOpened);
setOpenedRef.current = setOpened;
const handleOpen = useCallback(() => setOpenedRef.current(true), []);
const handleClose = useCallback(() => setOpenedRef.current(false), []);
useEffect(() => {
if (!opened) return;
return levelRegister(handleClose);
}, [
opened,
levelRegister,
handleClose
]);
const { context, refs } = useFloating({
placement: resolvedPosition,
open: opened,
onOpenChange: (nextOpen) => {
if (nextOpen) handleOpen();
else handleClose();
}
});
const { getReferenceProps, getFloatingProps } = useInteractions([useHover(context, {
handleClose: safeAreaPolygon ? safePolygon(typeof safeAreaPolygon === "object" ? safeAreaPolygon : void 0) : void 0,
delay: {
open: openDelay,
close: closeDelay
}
})]);
const focusFirstItem = () => window.setTimeout(() => {
document.getElementById(`${id}-dropdown`)?.querySelectorAll("[data-menu-item]:not([data-disabled])")[0]?.focus();
}, 16);
const focusParentItem = () => window.setTimeout(() => {
document.getElementById(`${id}-target`)?.focus();
}, 16);
return /* @__PURE__ */ jsx(SubMenuContext, {
value: {
opened,
close: handleClose,
open: handleOpen,
focusFirstItem,
focusParentItem,
parentContext: parentSubCtx,
setReference: refs.setReference,
setFloating: refs.setFloating,
getReferenceProps,
getFloatingProps,
registerOpenSub
},
children: /* @__PURE__ */ jsx(Popover, {
opened,
onChange: (nextOpened) => nextOpened ? handleOpen() : handleClose(),
withinPortal: false,
withArrow: false,
id,
position,
...others,
children
})
});
}
MenuSub.extend = (input) => input;
MenuSub.displayName = "@mantine/core/MenuSub";
MenuSub.Target = MenuSubTarget;
MenuSub.Dropdown = MenuSubDropdown;
MenuSub.Item = MenuSubItem;
//#endregion
export { MenuSub };
//# sourceMappingURL=MenuSub.mjs.map