Skip to content

Commit

Permalink
feat(MenuItem): allow observing submenu content resize when a re-rend…
Browse files Browse the repository at this point in the history
…er isn't triggered
  • Loading branch information
YossiSaadi committed Jan 13, 2025
1 parent dedc9d4 commit 0c5e262
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 6 deletions.
8 changes: 8 additions & 0 deletions packages/core/src/components/Menu/MenuItem/MenuItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ export interface MenuItemProps extends VibeComponentProps {
splitMenuItem?: boolean;
"aria-label"?: AriaAttributes["aria-label"];
submenuPosition?: SubmenuPosition;
/**
* Enables the observation of content resize for the menu item's submenu.
* When set to `true`, a ResizeObserver is attached to the popper content,
* automatically triggering repositioning when the size of the submenu's content changes.
*
* This is useful for when submenu's content may grow or shrink without a re-render being triggered.
*/
observeContentResize?: boolean;
}

export interface MenuItemTitleComponentProps extends Omit<MenuItemProps, "title"> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ const MenuItemSubMenu = ({
autoFocusOnMount,
onClose,
children,
submenuPosition
submenuPosition,
observeContentResize
}: MenuItemSubMenuProps) => {
const childRef = useRef<HTMLDivElement>(null);
const popperElementRef = useRef<HTMLDivElement>(null);
Expand All @@ -36,7 +37,8 @@ const MenuItemSubMenu = ({
popperElementRef?.current,
{
isOpen: open,
placement: submenuPlacement
placement: submenuPlacement,
observeContentResize
}
);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React from "react";
import { CloseMenuOption, MenuChild } from "../../../Menu/MenuConstants";
import { SubmenuPosition } from "../../MenuItem.types";
import { MenuItemProps } from "../../MenuItem";

export interface MenuItemSubMenuProps {
export interface MenuItemSubMenuProps extends Pick<MenuItemProps, "observeContentResize"> {
/**
* Reference to the anchor element that the submenu is related to. This is used to position the submenu correctly relative to the parent menu item.
*/
Expand Down
10 changes: 7 additions & 3 deletions packages/core/src/hooks/usePopover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Placement } from "./popoverConstants";
import useIsomorphicLayoutEffect from "./ssr/useIsomorphicLayoutEffect";
import useForceUpdate from "./useForceUpdate";
import type { Options, State } from "@popperjs/core";
import { createObserveContentResizeModifier } from "../components/Dialog/modifiers/observeContentResizeModifier";

const { RIGHT_START, RIGHT_END, LEFT_START, LEFT_END } = Placement;

Expand All @@ -19,10 +20,12 @@ export default function usePopover(
popperElement: HTMLElement,
{
isOpen,
placement = RIGHT_START
placement = RIGHT_START,
observeContentResize
}: {
isOpen?: boolean;
placement?: Placement;
observeContentResize?: boolean;
}
) {
const forceUpdate = useForceUpdate();
Expand All @@ -46,10 +49,11 @@ export default function usePopover(
state.styles.popper.visibility = isOpen ? "visible" : "hidden";
return state;
}
}
},
createObserveContentResizeModifier(observeContentResize)
]
};
}, [isOpen, placement]);
}, [isOpen, placement, observeContentResize]);

const { styles, attributes } = usePopper(referenceElement, popperElement, popperOptions);

Expand Down

0 comments on commit 0c5e262

Please sign in to comment.