bigbluebutton-Github/bigbluebutton-html5/imports/ui/components/dropdown/component.jsx

232 lines
6.7 KiB
React
Raw Normal View History

2016-08-20 05:20:17 +08:00
import React, { Component, PropTyes } from 'react';
import ReactDOM from 'react-dom';
import Icon from '/imports/ui/components/icon/component';
import Button from '/imports/ui/components/button/component';
import classNames from 'classnames';
import styles from './styles';
2016-08-24 06:19:13 +08:00
import { FormattedMessage } from 'react-intl';
import SettingsModal from '../modals/settings/SettingsModal';
import SessionMenu from '../modals/settings/submenus/SessionMenu';
import Dropdown from './dropdown-menu/component';
import DropdownTrigger from './dropdown-trigger/component';
import DropdownContent from './dropdown-content/component';
2016-08-20 05:20:17 +08:00
export default class SettingsDropdown extends Component {
constructor(props) {
super(props);
this.menus = [];
2016-08-24 06:19:13 +08:00
this.openWithKey = this.openWithKey.bind(this);
2016-08-20 05:20:17 +08:00
}
componentWillMount() {
2016-08-24 06:19:13 +08:00
this.setState({ activeMenu: -1, focusedMenu: 0, });
2016-08-20 05:20:17 +08:00
this.menus.push({ className: '',
2016-08-24 06:19:13 +08:00
props: { title: 'Fullscreen', prependIconName: 'icon-', icon: 'bbb-full-screen', },
tabIndex: 1, });
2016-08-20 05:20:17 +08:00
this.menus.push({ className: SettingsModal,
2016-08-25 01:49:57 +08:00
props: { title: 'Settings', prependIconName: 'icon-', icon: 'bbb-more', },
2016-08-24 06:19:13 +08:00
tabIndex: 2, });
2016-08-20 05:20:17 +08:00
this.menus.push({ className: SessionMenu,
2016-08-24 06:19:13 +08:00
props: { title: 'Leave Session', prependIconName: 'icon-', icon: 'bbb-logout', },
tabIndex: 3, });
2016-08-20 05:20:17 +08:00
}
componentWillUpdate() {
2016-08-24 06:19:13 +08:00
const DROPDOWN = this.refs.dropdown;
if (DROPDOWN.state.isMenuOpen && this.state.activeMenu >= 0) {
this.setState({ activeMenu: -1, focusedMenu: 0, });
2016-08-20 05:20:17 +08:00
}
}
setFocus() {
2016-08-24 06:19:13 +08:00
ReactDOM.findDOMNode(this.refs[`menu${this.state.focusedMenu}`]).focus();
2016-08-20 05:20:17 +08:00
}
handleListKeyDown(event) {
const pressedKey = event.keyCode;
2016-08-24 06:19:13 +08:00
let numOfMenus = this.menus.length - 1;
2016-08-20 05:20:17 +08:00
2016-08-24 06:19:13 +08:00
// User pressed tab
2016-08-20 05:20:17 +08:00
if (pressedKey === 9) {
let newIndex = 0;
2016-08-24 06:19:13 +08:00
if (this.state.focusedMenu >= numOfMenus) { // Checks if at end of menu
2016-08-20 05:20:17 +08:00
newIndex = 0;
2016-08-24 06:19:13 +08:00
if (!event.shiftKey) {
2016-08-23 22:05:54 +08:00
this.refs.dropdown.hideMenu();
}
2016-08-20 05:20:17 +08:00
} else {
2016-08-24 06:19:13 +08:00
newIndex = this.state.focusedMenu;
2016-08-20 05:20:17 +08:00
}
2016-08-24 06:19:13 +08:00
this.setState({ focusedMenu: newIndex, });
2016-08-20 05:20:17 +08:00
return;
}
2016-08-24 06:19:13 +08:00
// User pressed shift + tab
2016-08-20 05:20:17 +08:00
if (event.shiftKey && pressedKey === 9) {
let newIndex = 0;
2016-08-24 06:19:13 +08:00
if (this.state.focusedMenu <= 0) { // Checks if at beginning of menu
newIndex = numOfMenus;
2016-08-20 05:20:17 +08:00
} else {
2016-08-24 06:19:13 +08:00
newIndex = this.state.focusedMenu - 1;
2016-08-20 05:20:17 +08:00
}
2016-08-24 06:19:13 +08:00
this.setState({ focusedMenu: newIndex, });
2016-08-20 05:20:17 +08:00
return;
}
2016-08-24 06:19:13 +08:00
// User pressed up key
2016-08-20 05:20:17 +08:00
if (pressedKey === 38) {
2016-08-24 06:19:13 +08:00
if (this.state.focusedMenu <= 0) { // Checks if at beginning of menu
this.setState({ focusedMenu: numOfMenus, },
2016-08-20 05:20:17 +08:00
() => { this.setFocus(); });
} else {
2016-08-24 06:19:13 +08:00
this.setState({ focusedMenu: this.state.focusedMenu - 1, },
2016-08-20 05:20:17 +08:00
() => { this.setFocus(); });
}
return;
}
2016-08-24 06:19:13 +08:00
// User pressed down key
2016-08-23 22:05:54 +08:00
if (pressedKey === 40) {
2016-08-24 06:19:13 +08:00
if (this.state.focusedMenu >= numOfMenus) { // Checks if at end of menu
this.setState({ focusedMenu: 0, },
2016-08-23 22:05:54 +08:00
() => { this.setFocus(); });
} else {
2016-08-24 06:19:13 +08:00
this.setState({ focusedMenu: this.state.focusedMenu + 1, },
2016-08-23 22:05:54 +08:00
() => { this.setFocus(); });
}
return;
}
2016-08-24 06:19:13 +08:00
// User pressed enter and spaceBar
2016-08-20 05:20:17 +08:00
if (pressedKey === 13 || pressedKey === 32) {
2016-08-24 06:19:13 +08:00
this.clickMenu(this.state.focusedMenu);
2016-08-20 05:20:17 +08:00
return;
}
2016-08-24 06:19:13 +08:00
//User pressed ESC
2016-08-20 05:20:17 +08:00
if (pressedKey == 27) {
2016-08-24 06:19:13 +08:00
this.setState({ activeMenu: -1, focusedMenu: 0, });
2016-08-20 05:20:17 +08:00
this.refs.dropdown.hideMenu();
}
2016-08-24 06:19:13 +08:00
return;
2016-08-20 05:20:17 +08:00
}
handleFocus(index) {
2016-08-24 06:19:13 +08:00
this.setState({ focusedMenu: index, },
2016-08-20 05:20:17 +08:00
() => { this.setFocus(); });
}
clickMenu(i) {
2016-08-24 06:19:13 +08:00
this.setState({ activeMenu: i, });
2016-08-20 05:20:17 +08:00
this.refs.dropdown.hideMenu();
}
createMenu() {
const curr = this.state.activeMenu;
2016-08-24 06:19:13 +08:00
switch (curr) {
case 0:
console.log(this.menus[curr].props.title);
break;
case 1:
return <SettingsModal />;
break;
case 2:
return <SessionMenu />;
break;
default:
return;
2016-08-20 05:20:17 +08:00
}
}
openWithKey(event) {
2016-08-24 06:19:13 +08:00
// Focus first menu option
2016-08-20 05:20:17 +08:00
if (event.keyCode === 9) {
event.preventDefault();
event.stopPropagation();
}
2016-08-24 06:19:13 +08:00
this.setState({ focusedMenu: 0 }, () => { this.setFocus(); });
}
renderAriaLabelsDescs() {
return (
<div>
<p id="fullScreen" hidden>
<FormattedMessage
id="app.modals.dropdown.fullScreen"
description="Aria label for fullscreen"
defaultMessage="Make fullscreen"
/>
2016-08-24 06:19:13 +08:00
</p>
<p id="settingsModal" hidden>
<FormattedMessage
id="app.modals.dropdown.settingsModal"
2016-08-25 01:49:57 +08:00
description="Aria label for settings"
defaultMessage="Open Settings"
2016-08-24 06:19:13 +08:00
/>
</p>
<p id="leaveSession" hidden>
<FormattedMessage
id="app.modals.dropdown.leaveSession"
2016-08-25 01:49:57 +08:00
description="Aria label for logout"
2016-08-24 06:19:13 +08:00
defaultMessage="Logout"
/>
</p>
</div>
);
2016-08-24 06:19:13 +08:00
2016-08-20 05:20:17 +08:00
}
render() {
2016-08-24 06:19:13 +08:00
2016-08-20 05:20:17 +08:00
return (
<div>
2016-08-24 06:19:13 +08:00
<Dropdown ref='dropdown' focusMenu={this.openWithKey}>
2016-08-20 05:20:17 +08:00
<DropdownTrigger labelBtn='setting' iconBtn='more' />
2016-08-24 06:19:13 +08:00
<DropdownContent>
2016-08-20 05:20:17 +08:00
<div className={styles.triangleOnDropdown}></div>
2016-08-24 06:19:13 +08:00
<div className={styles.dropdownActiveContent}>
<ul className={styles.menuList} role="menu">
{this.menus.map((value, index) => (
<li
key={index}
role='menuitem'
tabIndex={value.tabIndex}
onClick={this.clickMenu.bind(this, index)}
onKeyDown={this.handleListKeyDown.bind(this)}
onFocus={this.handleFocus.bind(this, index)}
ref={'menu' + index}
className={styles.settingsMenuItem}>
<Icon
key={index}
prependIconName={value.props.prependIconName}
iconName={value.props.icon}
title={value.props.title}
className={styles.iconColor}/>
<span className={styles.settingsMenuItemText}>{value.props.title}</span>
{index == '0' ? <hr className={styles.hrDropdown}/> : null}
</li>
))}
</ul>
{this.renderAriaLabelsDescs()}
2016-08-20 05:20:17 +08:00
</div>
</DropdownContent>
</Dropdown>
2016-08-24 03:18:49 +08:00
<div role='presentation'>{this.createMenu()}</div>
2016-08-24 06:19:13 +08:00
<p id="settingsDropdown" hidden>
<FormattedMessage
id="app.modals.dropdown.settingsDropdown"
2016-08-25 01:49:57 +08:00
description="Aria label for Options"
defaultMessage="Options"
2016-08-24 06:19:13 +08:00
/>
</p>
2016-08-20 05:20:17 +08:00
</div>
);
}
}