ref(overflow-menu) Use ContextMenu component (#11282)
refactor overflow menu to use ContextMenu component refactor toolboxItem to use ContextMenuItem when needed
This commit is contained in:
parent
14597e835b
commit
ed9b85f287
|
@ -28,7 +28,7 @@
|
|||
/**
|
||||
* Keep overflow menu within screen vertical bounds and make it scrollable.
|
||||
*/
|
||||
.toolbox-button-wth-dialog > div:nth-child(2) {
|
||||
.toolbox-button-wth-dialog > div:nth-child(2) {
|
||||
background: $menuBG;
|
||||
max-height: calc(100vh - #{$newToolbarSizeWithPadding} - 46px);
|
||||
margin-bottom: 4px;
|
||||
|
@ -36,6 +36,15 @@
|
|||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove background color and box-shadow for the context menu container.
|
||||
*/
|
||||
.toolbox-button-wth-dialog.context-menu > div:nth-child(2) {
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
overflow-y: initial;
|
||||
}
|
||||
|
||||
.audio-preview > div:nth-child(2),
|
||||
.video-preview > div:nth-child(2),
|
||||
.reactions-menu-popup > div:nth-child(2) {
|
||||
|
|
|
@ -11,6 +11,11 @@ import participantsPaneTheme from '../themes/participantsPaneTheme.json';
|
|||
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* Accessibility label for menu container.
|
||||
*/
|
||||
accessibilityLabel?: string,
|
||||
|
||||
/**
|
||||
* Children of the context menu.
|
||||
*/
|
||||
|
@ -51,6 +56,11 @@ type Props = {
|
|||
*/
|
||||
onClick?: Function,
|
||||
|
||||
/**
|
||||
* Keydown handler.
|
||||
*/
|
||||
onKeyDown?: Function,
|
||||
|
||||
/**
|
||||
* Callback for drawer close.
|
||||
*/
|
||||
|
@ -111,6 +121,7 @@ const useStyles = makeStyles(theme => {
|
|||
});
|
||||
|
||||
const ContextMenu = ({
|
||||
accessibilityLabel,
|
||||
children,
|
||||
className,
|
||||
entity,
|
||||
|
@ -119,6 +130,7 @@ const ContextMenu = ({
|
|||
isDrawerOpen,
|
||||
offsetTarget,
|
||||
onClick,
|
||||
onKeyDown,
|
||||
onDrawerClose,
|
||||
onMouseEnter,
|
||||
onMouseLeave
|
||||
|
@ -179,12 +191,14 @@ const ContextMenu = ({
|
|||
</Drawer>
|
||||
</JitsiPortal>
|
||||
: <div
|
||||
aria-label = { accessibilityLabel }
|
||||
className = { clsx(participantsPaneTheme.ignoredChildClassName,
|
||||
styles.contextMenu,
|
||||
isHidden && styles.contextMenuHidden,
|
||||
className
|
||||
) }
|
||||
onClick = { onClick }
|
||||
onKeyDown = { onKeyDown }
|
||||
onMouseEnter = { onMouseEnter }
|
||||
onMouseLeave = { onMouseLeave }
|
||||
ref = { containerRef }>
|
||||
|
|
|
@ -46,6 +46,16 @@ export type Props = {
|
|||
*/
|
||||
onClick?: Function,
|
||||
|
||||
/**
|
||||
* Keydown handler.
|
||||
*/
|
||||
onKeyDown?: Function,
|
||||
|
||||
/**
|
||||
* Keypress handler.
|
||||
*/
|
||||
onKeyPress?: Function,
|
||||
|
||||
/**
|
||||
* Action text.
|
||||
*/
|
||||
|
@ -100,6 +110,8 @@ const ContextMenuItem = ({
|
|||
id,
|
||||
icon,
|
||||
onClick,
|
||||
onKeyDown,
|
||||
onKeyPress,
|
||||
text,
|
||||
textClassName }: Props) => {
|
||||
const styles = useStyles();
|
||||
|
@ -107,6 +119,7 @@ const ContextMenuItem = ({
|
|||
|
||||
return (
|
||||
<div
|
||||
aria-disabled = { disabled }
|
||||
aria-label = { accessibilityLabel }
|
||||
className = { clsx(styles.contextMenuItem,
|
||||
_overflowDrawer && styles.contextMenuItemDrawer,
|
||||
|
@ -115,7 +128,9 @@ const ContextMenuItem = ({
|
|||
) }
|
||||
id = { id }
|
||||
key = { text }
|
||||
onClick = { onClick }>
|
||||
onClick = { disabled ? undefined : onClick }
|
||||
onKeyDown = { disabled ? undefined : onKeyDown }
|
||||
onKeyPress = { disabled ? undefined : onKeyPress }>
|
||||
{customIcon ? customIcon
|
||||
: icon && <Icon
|
||||
className = { styles.contextMenuItemIcon }
|
||||
|
|
|
@ -20,6 +20,11 @@ export type Props = {|
|
|||
*/
|
||||
buttonKey?: string,
|
||||
|
||||
/**
|
||||
* Whether or not the button is displayed in a context menu.
|
||||
*/
|
||||
contextMenu?: boolean,
|
||||
|
||||
/**
|
||||
* An extra class name to be added at the end of the element's class name
|
||||
* in order to enable custom styling.
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import React, { Fragment } from 'react';
|
||||
|
||||
import ContextMenuItem from '../../components/context-menu/ContextMenuItem';
|
||||
import { Icon } from '../../icons';
|
||||
import { Tooltip } from '../../tooltip';
|
||||
|
||||
|
@ -10,6 +11,11 @@ import type { Props as AbstractToolboxItemProps } from './AbstractToolboxItem';
|
|||
|
||||
type Props = AbstractToolboxItemProps & {
|
||||
|
||||
/**
|
||||
* Whether or not the item is displayed in a context menu.
|
||||
*/
|
||||
contextMenu?: boolean,
|
||||
|
||||
/**
|
||||
* On key down handler.
|
||||
*/
|
||||
|
@ -58,8 +64,10 @@ export default class ToolboxItem extends AbstractToolboxItem<Props> {
|
|||
*/
|
||||
_renderItem() {
|
||||
const {
|
||||
contextMenu,
|
||||
disabled,
|
||||
elementAfter,
|
||||
icon,
|
||||
onClick,
|
||||
onKeyDown,
|
||||
showLabel,
|
||||
|
@ -81,6 +89,17 @@ export default class ToolboxItem extends AbstractToolboxItem<Props> {
|
|||
|
||||
const elementType = showLabel ? 'li' : 'div';
|
||||
const useTooltip = this.tooltip && this.tooltip.length > 0;
|
||||
|
||||
if (contextMenu) {
|
||||
return (<ContextMenuItem
|
||||
accessibilityLabel = { this.accessibilityLabel }
|
||||
disabled = { disabled }
|
||||
icon = { icon }
|
||||
onClick = { onClick }
|
||||
onKeyDown = { onKeyDown }
|
||||
onKeyPress = { this._onKeyPress }
|
||||
text = { this.label } />);
|
||||
}
|
||||
let children = (
|
||||
<Fragment>
|
||||
{ this._renderIcon() }
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
/* @flow */
|
||||
|
||||
import InlineDialog from '@atlaskit/inline-dialog';
|
||||
import { withStyles } from '@material-ui/styles';
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import { createToolbarEvent, sendAnalytics } from '../../../analytics';
|
||||
import { translate } from '../../../base/i18n';
|
||||
import { connect } from '../../../base/redux';
|
||||
import { ReactionEmoji, ReactionsMenu } from '../../../reactions/components';
|
||||
import { type ReactionEmojiProps } from '../../../reactions/constants';
|
||||
import { type ReactionEmojiProps, REACTIONS_MENU_HEIGHT } from '../../../reactions/constants';
|
||||
import { getReactionsQueue } from '../../../reactions/functions.any';
|
||||
import { DRAWER_MAX_HEIGHT } from '../../constants';
|
||||
|
||||
import Drawer from './Drawer';
|
||||
import JitsiPortal from './JitsiPortal';
|
||||
|
@ -29,6 +31,11 @@ type Props = {
|
|||
*/
|
||||
children: React$Node,
|
||||
|
||||
/**
|
||||
* An object containing the CSS classes.
|
||||
*/
|
||||
classes: Object,
|
||||
|
||||
/**
|
||||
* Whether or not the OverflowMenu popover should display.
|
||||
*/
|
||||
|
@ -60,6 +67,15 @@ type Props = {
|
|||
showMobileReactions: boolean
|
||||
};
|
||||
|
||||
const styles = () => {
|
||||
return {
|
||||
overflowMenuDrawer: {
|
||||
overflowY: 'auto',
|
||||
height: `calc(${DRAWER_MAX_HEIGHT} - ${REACTIONS_MENU_HEIGHT}px - 16px)`
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* A React {@code Component} for opening or closing the {@code OverflowMenu}.
|
||||
*
|
||||
|
@ -105,10 +121,10 @@ class OverflowMenuButton extends Component<Props> {
|
|||
* @returns {ReactElement}
|
||||
*/
|
||||
render() {
|
||||
const { children, isOpen, overflowDrawer, reactionsQueue, showMobileReactions } = this.props;
|
||||
const { children, classes, isOpen, overflowDrawer, reactionsQueue, showMobileReactions } = this.props;
|
||||
|
||||
return (
|
||||
<div className = 'toolbox-button-wth-dialog'>
|
||||
<div className = 'toolbox-button-wth-dialog context-menu'>
|
||||
{
|
||||
overflowDrawer ? (
|
||||
<>
|
||||
|
@ -120,7 +136,9 @@ class OverflowMenuButton extends Component<Props> {
|
|||
<Drawer
|
||||
isOpen = { isOpen }
|
||||
onClose = { this._onCloseDialog }>
|
||||
{children}
|
||||
<div className = { classes.overflowMenuDrawer }>
|
||||
{children}
|
||||
</div>
|
||||
{showMobileReactions && <ReactionsMenu overflowMenu = { true } />}
|
||||
</Drawer>
|
||||
{showMobileReactions && <div className = 'reactions-animations-container'>
|
||||
|
@ -194,4 +212,4 @@ function mapStateToProps(state) {
|
|||
};
|
||||
}
|
||||
|
||||
export default translate(connect(mapStateToProps)(OverflowMenuButton));
|
||||
export default withStyles(styles)(translate(connect(mapStateToProps)(OverflowMenuButton)));
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
// @flow
|
||||
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import clsx from 'clsx';
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import React, { Component } from 'react';
|
||||
import { batch } from 'react-redux';
|
||||
|
||||
import keyboardShortcut from '../../../../../modules/keyboardshortcut/keyboardshortcut';
|
||||
|
@ -12,6 +11,7 @@ import {
|
|||
createToolbarEvent,
|
||||
sendAnalytics
|
||||
} from '../../../analytics';
|
||||
import { ContextMenu, ContextMenuItemGroup } from '../../../base/components';
|
||||
import { getToolbarButtons } from '../../../base/config';
|
||||
import { isToolbarButtonEnabled } from '../../../base/config/functions.web';
|
||||
import { openDialog, toggleDialog } from '../../../base/dialog';
|
||||
|
@ -46,7 +46,7 @@ import { getParticipantsPaneOpen } from '../../../participants-pane/functions';
|
|||
import { addReactionToBuffer } from '../../../reactions/actions.any';
|
||||
import { toggleReactionsMenuVisibility } from '../../../reactions/actions.web';
|
||||
import { ReactionsMenuButton } from '../../../reactions/components';
|
||||
import { REACTIONS, REACTIONS_MENU_HEIGHT } from '../../../reactions/constants';
|
||||
import { REACTIONS } from '../../../reactions/constants';
|
||||
import { isReactionsEnabled } from '../../../reactions/functions.any';
|
||||
import {
|
||||
LiveStreamButton,
|
||||
|
@ -80,7 +80,7 @@ import {
|
|||
setToolbarHovered,
|
||||
showToolbox
|
||||
} from '../../actions';
|
||||
import { THRESHOLDS, NOT_APPLICABLE, DRAWER_MAX_HEIGHT, NOTIFY_CLICK_MODE } from '../../constants';
|
||||
import { THRESHOLDS, NOT_APPLICABLE, NOTIFY_CLICK_MODE } from '../../constants';
|
||||
import { isDesktopShareButtonDisabled, isToolboxVisible } from '../../functions';
|
||||
import DownloadButton from '../DownloadButton';
|
||||
import HangupButton from '../HangupButton';
|
||||
|
@ -284,18 +284,13 @@ type Props = {
|
|||
|
||||
declare var APP: Object;
|
||||
|
||||
const styles = theme => {
|
||||
const styles = () => {
|
||||
return {
|
||||
overflowMenu: {
|
||||
fontSize: 14,
|
||||
listStyleType: 'none',
|
||||
padding: '8px 0',
|
||||
backgroundColor: theme.palette.ui03
|
||||
},
|
||||
|
||||
overflowMenuDrawer: {
|
||||
overflowY: 'auto',
|
||||
height: `calc(${DRAWER_MAX_HEIGHT} - ${REACTIONS_MENU_HEIGHT}px - 16px)`
|
||||
contextMenu: {
|
||||
position: 'relative',
|
||||
right: 'auto',
|
||||
maxHeight: 'inherit',
|
||||
margin: 0
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -1337,29 +1332,39 @@ class Toolbox extends Component<Props> {
|
|||
showMobileReactions = {
|
||||
_reactionsEnabled && overflowMenuButtons.find(({ key }) => key === 'raisehand')
|
||||
}>
|
||||
<ul
|
||||
aria-label = { t(toolbarAccLabel) }
|
||||
className = { clsx(classes.overflowMenu,
|
||||
_overflowDrawer && classes.overflowMenuDrawer)
|
||||
}
|
||||
id = 'overflow-menu'
|
||||
onKeyDown = { this._onEscKey }
|
||||
role = 'menu'>
|
||||
{overflowMenuButtons.map(({ group, key, Content, ...rest }, index, arr) => {
|
||||
const showSeparator = index > 0 && arr[index - 1].group !== group;
|
||||
<ContextMenu
|
||||
accessibilityLabel = { t(toolbarAccLabel) }
|
||||
className = { classes.contextMenu }
|
||||
hidden = { false }
|
||||
inDrawer = { _overflowDrawer }
|
||||
onKeyDown = { this._onEscKey }>
|
||||
{overflowMenuButtons.reduce((acc, val) => {
|
||||
if (acc.length) {
|
||||
const prev = acc[acc.length - 1];
|
||||
const group = prev[prev.length - 1].group;
|
||||
|
||||
return (key !== 'raisehand' || !_reactionsEnabled)
|
||||
&& <Fragment key = { `f${key}` }>
|
||||
{showSeparator && <Separator key = { `hr${group}` } />}
|
||||
<Content
|
||||
if (group === val.group) {
|
||||
prev.push(val);
|
||||
} else {
|
||||
acc.push([ val ]);
|
||||
}
|
||||
} else {
|
||||
acc.push([ val ]);
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, []).map(buttonGroup => (
|
||||
<ContextMenuItemGroup key = { `group-${buttonGroup[0].group}` }>
|
||||
{buttonGroup.map(({ key, Content, ...rest }) => (
|
||||
key !== 'raisehand' || !_reactionsEnabled)
|
||||
&& <Content
|
||||
{ ...rest }
|
||||
buttonKey = { key }
|
||||
contextMenu = { true }
|
||||
key = { key }
|
||||
showLabel = { true } />
|
||||
</Fragment>
|
||||
;
|
||||
})}
|
||||
</ul>
|
||||
showLabel = { true } />)}
|
||||
</ContextMenuItemGroup>))}
|
||||
</ContextMenu>
|
||||
</OverflowMenuButton>
|
||||
)}
|
||||
|
||||
|
|
Loading…
Reference in New Issue