mirror of
https://github.com/mattermost/focalboard.git
synced 2024-12-12 09:04:14 +02:00
Fix hover menu behavior on ViewHeader component (#2662)
This commit is contained in:
parent
c58eee4d85
commit
a53ff91033
@ -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>
|
||||
)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user