bigbluebutton-Github/bigbluebutton-html5/imports/ui/components/common/menu/component.jsx

196 lines
5.1 KiB
React
Raw Normal View History

2021-07-08 19:41:03 +08:00
import React from "react";
import PropTypes from "prop-types";
import { defineMessages, injectIntl } from "react-intl";
import Menu from "@material-ui/core/Menu";
import { Divider } from "@material-ui/core";
2022-02-15 22:51:51 +08:00
import Icon from "/imports/ui/components/common/icon/component";
2021-07-08 19:41:03 +08:00
2021-11-06 03:59:01 +08:00
import { ENTER } from "/imports/utils/keyCodes";
2021-11-06 03:59:01 +08:00
import Styled from './styles';
2021-07-08 19:41:03 +08:00
const intlMessages = defineMessages({
close: {
id: 'app.dropdown.close',
description: 'Close button label',
},
});
//Used to switch to mobile view
2021-07-08 19:41:03 +08:00
const MAX_WIDTH = 640;
class BBBMenu extends React.Component {
constructor(props) {
super(props);
this.state = {
anchorEl: null,
};
this.opts = props.opts;
this.autoFocus = false;
2021-07-08 19:41:03 +08:00
this.handleClick = this.handleClick.bind(this);
this.handleClose = this.handleClose.bind(this);
}
handleClick(event) {
this.setState({ anchorEl: event.currentTarget });
2021-07-08 19:41:03 +08:00
};
handleClose(event) {
2021-07-08 19:41:03 +08:00
const { onCloseCallback } = this.props;
this.setState({ anchorEl: null }, onCloseCallback());
if (event) {
event.persist();
if (event.type === 'click') {
setTimeout(() => {
document.activeElement.blur();
}, 0);
}
}
2021-07-08 19:41:03 +08:00
};
makeMenuItems() {
const { actions, selectedEmoji } = this.props;
2021-07-08 19:41:03 +08:00
return actions?.map(a => {
const { dataTest, label, onClick, key, disabled } = a;
2021-11-06 03:59:01 +08:00
const emojiSelected = key?.toLowerCase()?.includes(selectedEmoji?.toLowerCase());
let customStyles = {
paddingLeft: '4px',
paddingRight: '4px',
paddingTop: '8px',
paddingBottom: '8px',
marginLeft: '4px',
marginRight: '4px'
};
if (a.customStyles) {
customStyles = { ...customStyles, ...a.customStyles };
}
return [
a.dividerTop && <Divider disabled />,
2021-11-06 03:59:01 +08:00
<Styled.BBBMenuItem
2021-11-11 21:36:00 +08:00
emoji={emojiSelected ? 'yes' : 'no'}
key={label}
data-test={dataTest || key}
disableRipple={true}
disableGutters={true}
disabled={disabled}
style={customStyles}
onClick={(event) => {
onClick();
const close = !key.includes('setstatus') && !key.includes('back');
// prevent menu close for sub menu actions
if (close) this.handleClose(event);
}}>
<div style={{ display: 'flex', flexFlow: 'row', width: '100%' }}>
2021-07-08 19:41:03 +08:00
{a.icon ? <Icon iconName={a.icon} key="icon" /> : null}
2021-11-06 03:59:01 +08:00
<Styled.Option>{label}</Styled.Option>
{a.iconRight ? <Styled.IconRight iconName={a.iconRight} key="iconRight" /> : null}
2021-07-08 19:41:03 +08:00
</div>
2021-11-06 03:59:01 +08:00
</Styled.BBBMenuItem>,
a.divider && <Divider disabled />
];
2021-07-08 19:41:03 +08:00
});
}
2021-07-08 19:41:03 +08:00
render() {
const { anchorEl } = this.state;
const { trigger, intl, customStyles, dataTest } = this.props;
2021-07-08 19:41:03 +08:00
const actionsItems = this.makeMenuItems();
let menuStyles = { zIndex: 9999 };
if (customStyles) {
menuStyles = { ...menuStyles, ...customStyles };
}
2021-07-08 19:41:03 +08:00
return (
<>
<div
onClick={(e) => {
e.persist();
2021-09-02 20:37:04 +08:00
this.opts.autoFocus = !(['mouse', 'touch'].includes(e.nativeEvent.pointerType));
this.handleClick(e);
}}
onKeyPress={(e) => {
e.persist();
if (e.which !== ENTER) return null;
this.handleClick(e);
}}
accessKey={this.props?.accessKey}
>
{trigger}
</div>
2021-07-08 19:41:03 +08:00
<Menu
{...this.opts}
2021-07-08 19:41:03 +08:00
anchorEl={anchorEl}
open={Boolean(anchorEl)}
onClose={this.handleClose}
style={menuStyles}
2022-01-29 03:52:22 +08:00
data-test={dataTest}
2021-07-08 19:41:03 +08:00
>
{actionsItems}
{anchorEl && window.innerWidth < MAX_WIDTH &&
2021-11-06 03:59:01 +08:00
<Styled.CloseButton
2021-07-08 19:41:03 +08:00
label={intl.formatMessage(intlMessages.close)}
size="lg"
color="default"
onClick={this.handleClose}
/>
}
</Menu>
</>
2021-07-08 19:41:03 +08:00
);
}
}
export default injectIntl(BBBMenu);
BBBMenu.defaultProps = {
opts: {
id: "default-dropdown-menu",
autoFocus: false,
2021-07-08 19:41:03 +08:00
keepMounted: true,
transitionDuration: 0,
elevation: 3,
getContentAnchorEl: null,
fullwidth: "true",
anchorOrigin: { vertical: 'top', horizontal: 'right' },
transformorigin: { vertical: 'top', horizontal: 'right' },
2021-07-08 19:41:03 +08:00
},
onCloseCallback: () => { },
2021-07-08 19:41:03 +08:00
};
BBBMenu.propTypes = {
intl: PropTypes.shape({
formatMessage: PropTypes.func.isRequired,
}).isRequired,
trigger: PropTypes.element.isRequired,
actions: PropTypes.arrayOf(PropTypes.shape({
key: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
onClick: PropTypes.func,
2021-07-08 19:41:03 +08:00
icon: PropTypes.string,
iconRight: PropTypes.string,
disabled: PropTypes.bool,
2021-07-08 19:41:03 +08:00
divider: PropTypes.bool,
dividerTop: PropTypes.bool,
2021-08-09 01:22:01 +08:00
accessKey: PropTypes.string,
2021-07-08 19:41:03 +08:00
})).isRequired,
onCloseCallback: PropTypes.func,
2022-01-29 03:52:22 +08:00
dataTest: PropTypes.string,
2021-07-08 19:41:03 +08:00
};