` element.
*
* Documentation: [Base UI Menu](https://base-ui.com/react/components/menu)
*/
var MenuViewport = /* @__PURE__ */ import_react.forwardRef(function MenuViewport(componentProps, forwardedRef) {
const { render, className, style, children, ...elementProps } = componentProps;
const { store } = useMenuRootContext();
const { side } = useMenuPositionerContext();
const instantType = store.useState("instantType");
const { children: childrenToRender, state: viewportState } = usePopupViewport({
store,
side,
cssVars: MenuViewportCssVars,
children
});
return useRenderElement("div", componentProps, {
state: {
activationDirection: viewportState.activationDirection,
transitioning: viewportState.transitioning,
instant: instantType
},
ref: forwardedRef,
props: [elementProps, { children: childrenToRender }],
stateAttributesMapping
});
});
MenuViewport.displayName = "MenuViewport";
//#endregion
//#region ../node_modules/@base-ui/utils/esm/isElementDisabled.js
function isElementDisabled(element) {
return element == null || element.hasAttribute("disabled") || element.getAttribute("aria-disabled") === "true";
}
//#endregion
//#region ../node_modules/@base-ui/react/esm/menu/submenu-trigger/MenuSubmenuTrigger.js
/**
* A menu item that opens a submenu.
* Renders a `
` element.
*
* Documentation: [Base UI Menu](https://base-ui.com/react/components/menu)
*/
var MenuSubmenuTrigger = /* @__PURE__ */ import_react.forwardRef(function MenuSubmenuTrigger(componentProps, forwardedRef) {
const { render, className, style, label, id: idProp, nativeButton = false, openOnHover = true, delay = 100, closeDelay = 0, disabled: disabledProp = false, ...elementProps } = componentProps;
const listItem = useCompositeListItem();
const menuPositionerContext = useMenuPositionerContext();
const { store } = useMenuRootContext();
const thisTriggerId = useBaseUiId(idProp);
const open = store.useState("open");
const floatingRootContext = store.useState("floatingRootContext");
const floatingTreeRoot = store.useState("floatingTreeRoot");
const popupId = store.useState("triggerPopupId", thisTriggerId);
const baseRegisterTrigger = useTriggerRegistration(thisTriggerId, store);
const registerTrigger = import_react.useCallback((element) => {
const cleanup = baseRegisterTrigger(element);
if (element !== null && store.select("open") && store.select("activeTriggerId") == null) store.update({
activeTriggerId: thisTriggerId,
activeTriggerElement: element,
closeDelay
});
return cleanup;
}, [
baseRegisterTrigger,
closeDelay,
store,
thisTriggerId
]);
const triggerElementRef = import_react.useRef(null);
const handleTriggerElementRef = import_react.useCallback((el) => {
triggerElementRef.current = el;
store.set("activeTriggerElement", el);
}, [store]);
useIsoLayoutEffect(() => {
const element = triggerElementRef.current;
if (element && isElementDisabled(element) && !disabledProp) warn(`A disabled element was detected on
. To properly disable the trigger, use the \`disabled\` prop on the component instead of setting it on the rendered element.${SafeReact.captureOwnerStack?.() || ""}`);
});
const submenuRootContext = useMenuSubmenuRootContext();
if (!submenuRootContext?.parentMenu) throw new Error("Base UI: must be placed in .");
store.useSyncedValue("closeDelay", closeDelay);
const parentMenuStore = submenuRootContext.parentMenu;
const itemProps = parentMenuStore.useState("itemProps");
const highlighted = parentMenuStore.useState("isActive", listItem.index);
const itemMetadata = import_react.useMemo(() => ({
type: "submenu-trigger",
setActive() {
parentMenuStore.set("activeIndex", listItem.index);
}
}), [parentMenuStore, listItem.index]);
const rootDisabled = store.useState("disabled");
const disabled = disabledProp || rootDisabled;
const { getItemProps, itemRef } = useMenuItem({
closeOnClick: false,
disabled,
highlighted,
id: thisTriggerId,
store,
typingRef: parentMenuStore.context.typingRef,
nativeButton,
itemMetadata,
nodeId: menuPositionerContext?.context.nodeId
});
const hoverEnabled = store.useState("hoverEnabled");
const allowMouseEnter = parentMenuStore.useState("allowMouseEnter");
const hoverProps = useHoverReferenceInteraction(floatingRootContext, {
enabled: hoverEnabled && openOnHover && !disabled,
handleClose: safePolygon({ blockPointerEvents: true }),
mouseOnly: true,
move: true,
restMs: delay,
delay: allowMouseEnter ? {
open: delay,
close: closeDelay
} : 0,
triggerElementRef,
externalTree: floatingTreeRoot,
isClosing: () => store.select("transitionStatus") === "ending"
});
const localInteractionProps = useClick(floatingRootContext, {
enabled: !disabled,
event: "mousedown",
toggle: !openOnHover,
ignoreMouse: openOnHover,
stickIfOpen: false
}).reference ?? EMPTY_OBJECT;
const rootTriggerProps = store.useState("triggerProps", true);
delete rootTriggerProps.id;
return useRenderElement("div", componentProps, {
state: {
disabled,
highlighted,
open
},
stateAttributesMapping: triggerOpenStateMapping,
props: [
localInteractionProps,
hoverProps,
rootTriggerProps,
itemProps,
{
"aria-controls": popupId,
tabIndex: open || highlighted ? 0 : -1,
onBlur() {
if (highlighted) parentMenuStore.set("activeIndex", null);
}
},
elementProps,
getItemProps
],
ref: [
forwardedRef,
listItem.ref,
itemRef,
registerTrigger,
handleTriggerElementRef
]
});
});
MenuSubmenuTrigger.displayName = "MenuSubmenuTrigger";
//#endregion
//#region ../node_modules/@base-ui/react/esm/menu/store/MenuHandle.js
var MenuHandle = class {
/**
* Internal store holding the menu's state.
* @internal
*/
constructor() {
this.store = new MenuStore();
}
/**
* Opens the menu and associates it with the trigger with the given id.
* The trigger must be a Menu.Trigger component with this handle passed as a prop.
*
* @param triggerId ID of the trigger to associate with the menu.
*/
open(triggerId) {
const triggerElement = triggerId ? this.store.context.triggerElements.getById(triggerId) : void 0;
if (triggerId && !triggerElement) throw new Error(`Base UI: MenuHandle.open: No trigger found with id "${triggerId}".`);
this.store.setOpen(true, createChangeEventDetails("imperative-action", void 0, triggerElement));
}
/**
* Closes the menu.
*/
close() {
this.store.setOpen(false, createChangeEventDetails("imperative-action", void 0, void 0));
}
/**
* Indicates whether the menu is currently open.
*/
get isOpen() {
return this.store.select("open");
}
};
/**
* Creates a new handle to connect a Menu.Root with detached Menu.Trigger components.
*/
function createMenuHandle() {
return new MenuHandle();
}
//#endregion
//#region ../node_modules/@base-ui/react/esm/menu/index.parts.js
var index_parts_exports = /* @__PURE__ */ __exportAll({
Arrow: () => MenuArrow,
Backdrop: () => MenuBackdrop,
CheckboxItem: () => MenuCheckboxItem,
CheckboxItemIndicator: () => MenuCheckboxItemIndicator,
Group: () => MenuGroup,
GroupLabel: () => MenuGroupLabel,
Handle: () => MenuHandle,
Item: () => MenuItem,
LinkItem: () => MenuLinkItem,
Popup: () => MenuPopup,
Portal: () => MenuPortal,
Positioner: () => MenuPositioner,
RadioGroup: () => MenuRadioGroup,
RadioItem: () => MenuRadioItem,
RadioItemIndicator: () => MenuRadioItemIndicator,
Root: () => MenuRoot,
Separator: () => Separator,
SubmenuRoot: () => MenuSubmenuRoot,
SubmenuTrigger: () => MenuSubmenuTrigger,
Trigger: () => MenuTrigger,
Viewport: () => MenuViewport,
createHandle: () => createMenuHandle
});
//#endregion
export { index_parts_exports as Menu };
//# sourceMappingURL=@base-ui_react_menu.js.map