menu.tsx
TLDR
This file, menu.tsx
, is a module that defines the Menu
component. The Menu
component is a React class component that represents a menu with various options. It provides a way to display a menu with options and manage user interactions with the menu. The component includes methods for rendering the menu and handling cancellations.
Classes
Menu
The Menu
class is a React class component that represents a menu with various options. It provides the following features:
- Accepts a
children
prop to define the options to display within the menu. - Supports different positions for the menu (top, bottom, left, right, or auto).
- Option to fix the menu in place.
- Automatic positioning of the menu based on a parent reference.
- Renders the menu with options, separators, and labels.
- Provides a cancel option.
The Menu
component includes static properties for different types of menu options, such as color, submenu, switch, separator, text, and label.
Example:
import Menu from './menu'
const App = () => {
return (
<Menu position="bottom">
{/* Add menu options here */}
</Menu>
)
}
// 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
}
}