Merge pull request #23300 from overleaf/mj-ide-menu-hover

[web] Introduce menu bar shared component

GitOrigin-RevId: c304cc4e1e5961fe4ef7d2112e8d9f91c47dd0ec
This commit is contained in:
David
2025-02-07 09:06:26 +00:00
committed by Copybot
parent b5c11370d6
commit bd76193eb5
10 changed files with 199 additions and 45 deletions
@@ -0,0 +1,53 @@
import {
Dropdown,
DropdownMenu,
DropdownToggle,
} from '@/features/ui/components/bootstrap-5/dropdown-menu'
import { FC, useCallback } from 'react'
import classNames from 'classnames'
import { useMenuBar } from '@/shared/hooks/use-menu-bar'
type MenuBarDropdownProps = {
title: string
id: string
className?: string
}
export const MenuBarDropdown: FC<MenuBarDropdownProps> = ({
title,
children,
id,
className,
}) => {
const { menuId, selected, setSelected } = useMenuBar()
const onToggle = useCallback(
show => {
setSelected(show ? id : null)
},
[id, setSelected]
)
const onHover = useCallback(() => {
setSelected(prev => {
if (prev === null) {
return null
}
return id
})
}, [id, setSelected])
return (
<Dropdown show={selected === id} align="start" onToggle={onToggle}>
<DropdownToggle
id={`${menuId}-${id}`}
variant="secondary"
className={classNames(className, 'menu-bar-toggle')}
onMouseEnter={onHover}
>
{title}
</DropdownToggle>
<DropdownMenu renderOnMount>{children}</DropdownMenu>
</Dropdown>
)
}
@@ -0,0 +1,15 @@
import DropdownListItem from '@/features/ui/components/bootstrap-5/dropdown-list-item'
import { DropdownItem } from '@/features/ui/components/bootstrap-5/dropdown-menu'
type MenuBarOptionProps = {
title: string
onClick?: () => void
}
export const MenuBarOption = ({ title, onClick }: MenuBarOptionProps) => {
return (
<DropdownListItem>
<DropdownItem onClick={onClick}>{title}</DropdownItem>
</DropdownListItem>
)
}
@@ -0,0 +1,17 @@
import { MenuBarContext } from '@/shared/context/menu-bar-context'
import { FC, HTMLProps, useState } from 'react'
export const MenuBar: FC<HTMLProps<HTMLDivElement> & { id: string }> = ({
children,
id,
...props
}) => {
const [selected, setSelected] = useState<string | null>(null)
return (
<div {...props}>
<MenuBarContext.Provider value={{ selected, setSelected, menuId: id }}>
{children}
</MenuBarContext.Provider>
</div>
)
}