Fix hover menu behavior on ViewHeader component (#2662)

This commit is contained in:
Jesús Espino 2022-03-29 13:59:28 +02:00 committed by GitHub
parent c58eee4d85
commit a53ff91033
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 49 deletions

View File

@ -253,23 +253,29 @@ const ViewMenu = (props: Props) => {
/>))}
<BoardPermissionGate permissions={[Permission.ManageBoardProperties]}>
<Menu.Separator/>
{!props.readonly &&
</BoardPermissionGate>
{!props.readonly &&
<BoardPermissionGate permissions={[Permission.ManageBoardProperties]}>
<Menu.Text
id='__duplicateView'
name={duplicateViewText}
icon={<DuplicateIcon/>}
onClick={handleDuplicateView}
/>
}
{!props.readonly && views.length > 1 &&
</BoardPermissionGate>
}
{!props.readonly && views.length > 1 &&
<BoardPermissionGate permissions={[Permission.ManageBoardProperties]}>
<Menu.Text
id='__deleteView'
name={deleteViewText}
icon={<DeleteIcon/>}
onClick={handleDeleteView}
/>
}
{!props.readonly &&
</BoardPermissionGate>
}
{!props.readonly &&
<BoardPermissionGate permissions={[Permission.ManageBoardProperties]}>
<Menu.SubMenu
id='__addView'
name={addViewText}
@ -300,8 +306,8 @@ const ViewMenu = (props: Props) => {
onClick={handleAddViewCalendar}
/>
</Menu.SubMenu>
}
</BoardPermissionGate>
</BoardPermissionGate>
}
</Menu>
)
}

View File

@ -6,7 +6,7 @@ import SeparatorOption from './separatorOption'
import SwitchOption from './switchOption'
import TextOption from './textOption'
import ColorOption from './colorOption'
import SubMenuOption from './subMenuOption'
import SubMenuOption, {HoveringContext} from './subMenuOption'
import LabelOption from './labelOption'
import './menu.scss'
@ -27,7 +27,7 @@ export default class Menu extends React.PureComponent<Props> {
static Label = LabelOption
public state = {
hoveringIdx: -1,
hovering: null,
}
public render(): JSX.Element {
@ -36,16 +36,14 @@ export default class Menu extends React.PureComponent<Props> {
<div className={'Menu noselect ' + (position || 'bottom')}>
<div className='menu-contents'>
<div className='menu-options'>
{React.Children.map(children, (child, i) => {
return addChildMenuItem({
child,
onMouseEnter: () =>
this.setState({
hoveringIdx: i,
}),
isHovering: () => i === this.state.hoveringIdx,
})
})}
{React.Children.map(children, (child) => (
<div
onMouseEnter={() => this.setState({hovering: child})}
>
<HoveringContext.Provider value={child == this.state.hovering}>
{child}
</HoveringContext.Provider>
</div>))}
</div>
<div className='menu-spacer hideOnWidescreen'/>
@ -67,28 +65,3 @@ export default class Menu extends React.PureComponent<Props> {
// No need to do anything, as click bubbled up to MenuWrapper, which closes
}
}
function addChildMenuItem(props: {child: React.ReactNode, onMouseEnter: () => void, isHovering: () => boolean}): JSX.Element | null {
const {child, onMouseEnter, isHovering} = props
if (child !== null) {
if (React.isValidElement(child)) {
const castedChild = child as React.ReactElement
return (
<div
onMouseEnter={onMouseEnter}
>
{castedChild.type === SubMenuOption ? (
<castedChild.type
{...castedChild.props}
isHovering={isHovering}
/>
) : (
<castedChild.type {...castedChild.props}/>
)}
</div>
)
}
}
return (null)
}

View File

@ -1,6 +1,6 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {useEffect, useState} from 'react'
import React, {useEffect, useState, useContext} from 'react'
import SubmenuTriangleIcon from '../icons/submenuTriangle'
@ -8,25 +8,27 @@ import Menu from '.'
import './subMenuOption.scss'
export const HoveringContext = React.createContext(false)
type SubMenuOptionProps = {
id: string
name: string
position?: 'bottom' | 'top' | 'left' | 'left-bottom'
icon?: React.ReactNode
children: React.ReactNode
isHovering?: boolean
}
function SubMenuOption(props: SubMenuOptionProps): JSX.Element {
const [isOpen, setIsOpen] = useState(false)
const isHovering = useContext(HoveringContext)
const openLeftClass = props.position === 'left' || props.position === 'left-bottom' ? ' open-left' : ''
useEffect(() => {
if (props.isHovering !== undefined) {
setIsOpen(props.isHovering)
if (isHovering !== undefined) {
setIsOpen(isHovering)
}
}, [props.isHovering])
}, [isHovering])
return (
<div