menu.tsx
TLDR
The provided file is a TypeScript file that contains the implementation of the Menu
component. It is a pure component that renders a menu with different options and styles based on the props passed to it.
Classes
Menu
The Menu
class is a React component that renders a menu with different options. It accepts the following props:
-
children
(React.ReactNode): The options to be rendered inside the menu. -
position
(optional, string): The position of the menu. It can be 'top', 'bottom', 'left', 'right', or 'auto'. -
fixed
(optional, boolean): If set to true, the menu will use a fixed position. -
parentRef
(optional, React.RefObject): A reference to the parent element.
The Menu
class provides the following static members:
-
Color
: A component for rendering a color option. -
SubMenu
: A component for rendering a submenu option. -
Switch
: A component for rendering a switch option. -
Separator
: A component for rendering a separator option. -
Text
: A component for rendering a text option. -
TextInput
: A component for rendering a text input option. -
Label
: A component for rendering a label option.
The Menu
class also defines an internal state with the following properties:
-
hovering
: The currently hovering child option. -
menuStyle
: The style to apply to the menu.
The Menu
class renders a <div>
element with the class "Menu" that contains the menu options and a cancel option. The style and position of the menu are determined by the props and the parent element reference.
END
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {CSSProperties} from 'react'
import SeparatorOption from './separatorOption'
import SwitchOption from './switchOption'
import TextOption from './textOption'
import ColorOption from './colorOption'
import SubMenuOption, {HoveringContext} from './subMenuOption'
import LabelOption from './labelOption'
import './menu.scss'
import textInputOption from './textInputOption'
import MenuUtil from './menuUtil'
type Props = {
children: React.ReactNode
position?: 'top' | 'bottom' | 'left' | 'right' | 'auto'
fixed?: boolean
parentRef?: React.RefObject<any>
}
export default class Menu extends React.PureComponent<Props> {
static Color = ColorOption
static SubMenu = SubMenuOption
static Switch = SwitchOption
static Separator = SeparatorOption
static Text = TextOption
static TextInput = textInputOption
static Label = LabelOption
menuRef: React.RefObject<HTMLDivElement>
constructor(props: Props) {
super(props)
this.menuRef = React.createRef<HTMLDivElement>()
}
public state = {
hovering: null,
menuStyle: {},
}
public render(): JSX.Element {
const {position, fixed, children} = this.props
let style: CSSProperties = {}
if (this.props.parentRef) {
const forceBottom = position ? ['bottom', 'left', 'right'].includes(position) : false
style = MenuUtil.openUp(this.props.parentRef, forceBottom).style
}
return (
<div
className={`Menu noselect ${position || 'bottom'} ${fixed ? ' fixed' : ''}`}
style={style}
ref={this.menuRef}
>
<div className='menu-contents'>
<div className='menu-options'>
{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'/>
<div className='menu-options hideOnWidescreen'>
<Menu.Text
id='menu-cancel'
name={'Cancel'}
className='menu-cancel'
onClick={this.onCancel}
/>
</div>
</div>
</div>
)
}
private onCancel = () => {
// No need to do anything, as click bubbled up to MenuWrapper, which closes
}
}