Skip to content

Commit

Permalink
fix: Render submenus at the bottom when there isn't enough space
Browse files Browse the repository at this point in the history
  • Loading branch information
frankieyan committed Oct 8, 2024
1 parent 0eea18f commit 9dcc76a
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/menu/menu.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ be changed by passing `modal={false}` to `<MenuList>`

You may nest the `<SubMenu>` component within `<Menu>` to create submenus.

On smaller viewports where there isn't enough space to render the submenu on the side,it will be rendered under its parent menu item instead.

<Canvas>
<Story
name="SubMenu Story"
Expand Down
10 changes: 8 additions & 2 deletions src/menu/menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ const MenuContext = React.createContext<MenuContextState>({
setAnchorRect: () => undefined,
})

const SubMenuContext = React.createContext<{ isSubMenu: boolean }>({ isSubMenu: false })

//
// Menu
//
Expand Down Expand Up @@ -147,14 +149,16 @@ interface MenuListProps
* The dropdown menu itself, containing a list of menu items.
*/
const MenuList = React.forwardRef<HTMLDivElement, MenuListProps>(function MenuList(
{ exceptionallySetClassName, modal = true, ...props },
{ exceptionallySetClassName, modal = true, flip, ...props },
ref,
) {
const { menuStore, getAnchorRect } = React.useContext(MenuContext)
if (!menuStore) {
throw new Error('MenuList must be wrapped in <Menu/>')
}

const { isSubMenu } = React.useContext(SubMenuContext)

const isOpen = menuStore.useState('open')

return isOpen ? (
Expand All @@ -168,6 +172,7 @@ const MenuList = React.forwardRef<HTMLDivElement, MenuListProps>(function MenuLi
className={classNames('reactist_menulist', exceptionallySetClassName)}
getAnchorRect={getAnchorRect ?? undefined}
modal={modal}
flip={flip ?? (isSubMenu ? 'bottom' : undefined)}
/>
</Portal>
) : null
Expand Down Expand Up @@ -324,13 +329,14 @@ const SubMenu = React.forwardRef<HTMLDivElement, SubMenuProps>(function SubMenu(

const [button, list] = React.Children.toArray(children)
const buttonElement = button as React.ReactElement<MenuButtonProps>
const subMenuContextValue = React.useMemo(() => ({ isSubMenu: true }), [])

return (
<Menu onItemSelect={handleSubItemSelect}>
<AriakitMenuItem store={menuStore} ref={ref} hideOnClick={false} render={buttonElement}>
{buttonElement.props.children}
</AriakitMenuItem>
{list}
<SubMenuContext.Provider value={subMenuContextValue}>{list}</SubMenuContext.Provider>
</Menu>
)
})
Expand Down

0 comments on commit 9dcc76a

Please sign in to comment.