@lobehub/ui
Version:
Lobe UI is an open-source UI component library for building AIGC web apps
80 lines (77 loc) • 2.88 kB
JavaScript
'use client';
import { useNativeButton } from "../hooks/useNativeButton.mjs";
import { DropdownMenuPopup, DropdownMenuPortal, DropdownMenuPositioner, DropdownMenuTrigger } from "./atoms.mjs";
import { parseTrigger } from "../utils/parseTrigger.mjs";
import { renderDropdownMenuItems } from "./renderItems.mjs";
import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
import { jsx, jsxs } from "react/jsx-runtime";
import { Menu } from "@base-ui/react/menu";
//#region src/DropdownMenu/DropdownMenu.tsx
const DropdownMenu = memo(({ children, defaultOpen, iconSpaceMode, items, nativeButton, onOpenChange, onOpenChangeComplete, open, placement = "bottomLeft", popupProps, portalProps, positionerProps, trigger = "click", triggerProps, ...rest }) => {
const [uncontrolledOpen, setUncontrolledOpen] = useState(Boolean(defaultOpen));
const { openOnHover } = useMemo(() => parseTrigger(trigger), [trigger]);
useEffect(() => {
if (open === void 0) return;
setUncontrolledOpen(open);
}, [open]);
const handleOpenChange = useCallback((nextOpen, details) => {
onOpenChange?.(nextOpen, details);
if (open === void 0) setUncontrolledOpen(nextOpen);
}, [onOpenChange, open]);
const menuItemsRef = useRef(null);
const isOpen = open ?? uncontrolledOpen;
const menuItems = useMemo(() => {
if (isOpen) {
const renderedItems = renderDropdownMenuItems(typeof items === "function" ? items() : items, [], { iconSpaceMode });
menuItemsRef.current = renderedItems;
return renderedItems;
}
return menuItemsRef.current;
}, [
isOpen,
items,
iconSpaceMode
]);
const handleOpenChangeComplete = useCallback((nextOpen) => {
onOpenChangeComplete?.(nextOpen);
if (!nextOpen) menuItemsRef.current = null;
}, [onOpenChangeComplete]);
const { container: portalContainer, ...restPortalProps } = portalProps ?? {};
const { resolvedNativeButton } = useNativeButton({
children,
nativeButton,
triggerNativeButton: triggerProps?.nativeButton
});
const triggerElement = /* @__PURE__ */ jsx(DropdownMenuTrigger, {
...triggerProps,
nativeButton: resolvedNativeButton,
openOnHover,
children
});
return /* @__PURE__ */ jsxs(Menu.Root, {
...rest,
defaultOpen,
modal: false,
onOpenChange: handleOpenChange,
onOpenChangeComplete: handleOpenChangeComplete,
open,
children: [triggerElement, /* @__PURE__ */ jsx(DropdownMenuPortal, {
container: portalContainer,
...restPortalProps,
children: /* @__PURE__ */ jsx(DropdownMenuPositioner, {
...positionerProps,
hoverTrigger: openOnHover,
placement,
children: /* @__PURE__ */ jsx(DropdownMenuPopup, {
...popupProps,
children: menuItems
})
})
})]
});
});
DropdownMenu.displayName = "DropdownMenuV2";
var DropdownMenu_default = DropdownMenu;
//#endregion
export { DropdownMenu_default as default };
//# sourceMappingURL=DropdownMenu.mjs.map