Merge pull request #3269 from JaeeunCho/dropdown
HTML5 dropdown for settings menu
This commit is contained in:
commit
4811b521a6
@ -57,7 +57,6 @@ modules-runtime@0.7.6
|
|||||||
mongo@1.1.11
|
mongo@1.1.11
|
||||||
mongo-id@1.0.5
|
mongo-id@1.0.5
|
||||||
mrt:external-file-loader@0.1.4
|
mrt:external-file-loader@0.1.4
|
||||||
mrt:redis@0.1.3
|
|
||||||
nathantreid:css-modules@2.2.2
|
nathantreid:css-modules@2.2.2
|
||||||
nathantreid:css-modules-import-path-helpers@0.1.4
|
nathantreid:css-modules-import-path-helpers@0.1.4
|
||||||
npm-mongo@1.5.46
|
npm-mongo@1.5.46
|
||||||
|
@ -25,5 +25,12 @@
|
|||||||
"app.whiteboard.slideControls.zoomDescrip": "Change the zoom level of the presentation",
|
"app.whiteboard.slideControls.zoomDescrip": "Change the zoom level of the presentation",
|
||||||
"app.failedMessage": "Apologies, trouble connecting to the server.",
|
"app.failedMessage": "Apologies, trouble connecting to the server.",
|
||||||
"app.connectingMessage": "Connecting...",
|
"app.connectingMessage": "Connecting...",
|
||||||
"app.waitingMessage": "Disconnected. Trying to reconnect in {seconds} seconds..."
|
"app.waitingMessage": "Disconnected. Trying to reconnect in {seconds} seconds...",
|
||||||
|
"app.dropdown.options": "Options",
|
||||||
|
"app.dropdown.fullscreenLabel": "Make fullscreen",
|
||||||
|
"app.dropdown.settingsLabel": "Open settings",
|
||||||
|
"app.dropdown.leaveSessionLabel": "Logout",
|
||||||
|
"app.dropdown.fullscreenDesc": "Make the settings menu fullscreen",
|
||||||
|
"app.dropdown.settingsDesc": "Change the general settings",
|
||||||
|
"app.dropdown.leaveSessionDesc": "Leave the meeting"
|
||||||
}
|
}
|
||||||
|
@ -5,14 +5,12 @@ import { subscribeForData, wasUserKicked, redirectToLogoutUrl } from './service'
|
|||||||
import NavBarContainer from '../nav-bar/container';
|
import NavBarContainer from '../nav-bar/container';
|
||||||
import ActionsBarContainer from '../actions-bar/container';
|
import ActionsBarContainer from '../actions-bar/container';
|
||||||
import MediaContainer from '../media/container';
|
import MediaContainer from '../media/container';
|
||||||
import SettingsModal from '../modals/settings/SettingsModal';
|
|
||||||
import ClosedCaptionsContainer from '../closed-captions/container';
|
import ClosedCaptionsContainer from '../closed-captions/container';
|
||||||
|
|
||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
navbar: <NavBarContainer />,
|
navbar: <NavBarContainer />,
|
||||||
actionsbar: <ActionsBarContainer />,
|
actionsbar: <ActionsBarContainer />,
|
||||||
media: <MediaContainer />,
|
media: <MediaContainer />,
|
||||||
settings: <SettingsModal />,
|
|
||||||
|
|
||||||
//CCs UI is commented till the next pull request
|
//CCs UI is commented till the next pull request
|
||||||
//captions: <ClosedCaptionsContainer />,
|
//captions: <ClosedCaptionsContainer />,
|
||||||
|
@ -55,7 +55,7 @@ export default class ButtonBase extends Component {
|
|||||||
this.internalKeyUpHandler = this.internalKeyUpHandler.bind(this);
|
this.internalKeyUpHandler = this.internalKeyUpHandler.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
validateDisabled(eventHandler, args) {
|
validateDisabled(eventHandler, ...args) {
|
||||||
if (!this.props.disabled && typeof eventHandler === 'function') {
|
if (!this.props.disabled && typeof eventHandler === 'function') {
|
||||||
return eventHandler(...args);
|
return eventHandler(...args);
|
||||||
}
|
}
|
||||||
|
264
bigbluebutton-html5/imports/ui/components/dropdown/component.jsx
Executable file
264
bigbluebutton-html5/imports/ui/components/dropdown/component.jsx
Executable file
@ -0,0 +1,264 @@
|
|||||||
|
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';
|
||||||
|
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';
|
||||||
|
|
||||||
|
export default class SettingsDropdown extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.menus = [];
|
||||||
|
this.openWithKey = this.openWithKey.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillMount() {
|
||||||
|
this.setState({ activeMenu: -1, focusedMenu: 0, });
|
||||||
|
this.menus.push({ className: '',
|
||||||
|
props: { title: 'Fullscreen', prependIconName: 'icon-', icon: 'bbb-full-screen',
|
||||||
|
ariaLabelleby: 'fullscreenLabel', ariaDescribedby:'fullscreenDesc', },
|
||||||
|
tabIndex: 1, });
|
||||||
|
this.menus.push({ className: SettingsModal,
|
||||||
|
props: { title: 'Settings', prependIconName: 'icon-', icon: 'bbb-more',
|
||||||
|
ariaLabelleby: 'settingsLabel', ariaDescribedby:'settingsDesc', },
|
||||||
|
tabIndex: 2, });
|
||||||
|
this.menus.push({ className: SessionMenu,
|
||||||
|
props: { title: 'Leave Session', prependIconName: 'icon-', icon: 'bbb-logout',
|
||||||
|
ariaLabelleby: 'leaveSessionLabel', ariaDescribedby:'leaveSessionDesc', },
|
||||||
|
tabIndex: 3, });
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUpdate() {
|
||||||
|
const DROPDOWN = this.refs.dropdown;
|
||||||
|
if (DROPDOWN.state.isMenuOpen && this.state.activeMenu >= 0) {
|
||||||
|
this.setState({ activeMenu: -1, focusedMenu: 0, });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setFocus() {
|
||||||
|
ReactDOM.findDOMNode(this.refs[`menu${this.state.focusedMenu}`]).focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
handleListKeyDown(event) {
|
||||||
|
const pressedKey = event.keyCode;
|
||||||
|
let numOfMenus = this.menus.length - 1;
|
||||||
|
|
||||||
|
// User pressed tab
|
||||||
|
if (pressedKey === 9) {
|
||||||
|
let newIndex = 0;
|
||||||
|
if (this.state.focusedMenu >= numOfMenus) { // Checks if at end of menu
|
||||||
|
newIndex = 0;
|
||||||
|
if (!event.shiftKey) {
|
||||||
|
this.refs.dropdown.hideMenu();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
newIndex = this.state.focusedMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({ focusedMenu: newIndex, });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// User pressed shift + tab
|
||||||
|
if (event.shiftKey && pressedKey === 9) {
|
||||||
|
let newIndex = 0;
|
||||||
|
if (this.state.focusedMenu <= 0) { // Checks if at beginning of menu
|
||||||
|
newIndex = numOfMenus;
|
||||||
|
} else {
|
||||||
|
newIndex = this.state.focusedMenu - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({ focusedMenu: newIndex, });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// User pressed up key
|
||||||
|
if (pressedKey === 38) {
|
||||||
|
if (this.state.focusedMenu <= 0) { // Checks if at beginning of menu
|
||||||
|
this.setState({ focusedMenu: numOfMenus, },
|
||||||
|
() => { this.setFocus(); });
|
||||||
|
} else {
|
||||||
|
this.setState({ focusedMenu: this.state.focusedMenu - 1, },
|
||||||
|
() => { this.setFocus(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// User pressed down key
|
||||||
|
if (pressedKey === 40) {
|
||||||
|
if (this.state.focusedMenu >= numOfMenus) { // Checks if at end of menu
|
||||||
|
this.setState({ focusedMenu: 0, },
|
||||||
|
() => { this.setFocus(); });
|
||||||
|
} else {
|
||||||
|
this.setState({ focusedMenu: this.state.focusedMenu + 1, },
|
||||||
|
() => { this.setFocus(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// User pressed enter and spaceBar
|
||||||
|
if (pressedKey === 13 || pressedKey === 32) {
|
||||||
|
this.clickMenu(this.state.focusedMenu);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//User pressed ESC
|
||||||
|
if (pressedKey == 27) {
|
||||||
|
this.setState({ activeMenu: -1, focusedMenu: 0, });
|
||||||
|
this.refs.dropdown.hideMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleFocus(index) {
|
||||||
|
this.setState({ focusedMenu: index, },
|
||||||
|
() => { this.setFocus(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
clickMenu(i) {
|
||||||
|
this.setState({ activeMenu: i, });
|
||||||
|
this.refs.dropdown.hideMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
createMenu() {
|
||||||
|
const curr = this.state.activeMenu;
|
||||||
|
|
||||||
|
switch (curr) {
|
||||||
|
case 0:
|
||||||
|
console.log(this.menus[curr].props.title);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
return <SettingsModal />;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
return <SessionMenu />;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
openWithKey(event) {
|
||||||
|
// Focus first menu option
|
||||||
|
if (event.keyCode === 9) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({ focusedMenu: 0 }, () => { this.setFocus(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
renderAriaLabelsDescs() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
|
||||||
|
{/* aria-labelledby */}
|
||||||
|
<p id="fullscreenLabel" hidden>
|
||||||
|
<FormattedMessage
|
||||||
|
id="app.dropdown.fullscreenLabel"
|
||||||
|
description="Aria label for fullscreen"
|
||||||
|
defaultMessage="Make fullscreen"
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
<p id="settingsLabel" hidden>
|
||||||
|
<FormattedMessage
|
||||||
|
id="app.dropdown.settingsLabel"
|
||||||
|
description="Aria label for settings"
|
||||||
|
defaultMessage="Open Settings"
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
<p id="leaveSessionLabel" hidden>
|
||||||
|
<FormattedMessage
|
||||||
|
id="app.dropdown.leaveSessionLabel"
|
||||||
|
description="Aria label for logout"
|
||||||
|
defaultMessage="Logout"
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{/* aria-describedby */}
|
||||||
|
<p id="fullscreenDesc" hidden>
|
||||||
|
<FormattedMessage
|
||||||
|
id="app.dropdown.fullscreenDesc"
|
||||||
|
description="Aria label for fullscreen"
|
||||||
|
defaultMessage="Make the settings menu fullscreen"
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
<p id="settingsDesc" hidden>
|
||||||
|
<FormattedMessage
|
||||||
|
id="app.dropdown.settingsDesc"
|
||||||
|
description="Aria label for settings"
|
||||||
|
defaultMessage="Change the general settings"
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
<p id="leaveSessionDesc" hidden>
|
||||||
|
<FormattedMessage
|
||||||
|
id="app.dropdown.leaveSessionDesc"
|
||||||
|
description="Aria label for logout"
|
||||||
|
defaultMessage="Leave the meeting"
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Dropdown ref='dropdown' focusMenu={this.openWithKey}>
|
||||||
|
<DropdownTrigger labelBtn='setting' iconBtn='more' />
|
||||||
|
<DropdownContent>
|
||||||
|
<div className={styles.triangleOnDropdown}></div>
|
||||||
|
<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}
|
||||||
|
aria-labelledby={value.props.ariaLabelleby}
|
||||||
|
aria-describedby={value.props.ariaDescribedby}>
|
||||||
|
|
||||||
|
<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()}
|
||||||
|
</div>
|
||||||
|
</DropdownContent>
|
||||||
|
</Dropdown>
|
||||||
|
<div role='presentation'>{this.createMenu()}</div>
|
||||||
|
<p id="settingsDropdown" hidden>
|
||||||
|
<FormattedMessage
|
||||||
|
id="app.dropdown.options"
|
||||||
|
description="Aria label for Options"
|
||||||
|
defaultMessage="Options"
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
import styles from '../styles';
|
||||||
|
|
||||||
|
export default class DropdownContent extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return <div>{this.props.children}</div>;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,89 @@
|
|||||||
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
import { findDOMNode } from 'react-dom';
|
||||||
|
import styles from '../styles';
|
||||||
|
import DropdownTrigger from '../dropdown-trigger/component';
|
||||||
|
|
||||||
|
export default class Dropdown extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = { isMenuOpen: false, };
|
||||||
|
this.showMenu = this.showMenu.bind(this);
|
||||||
|
this.hideMenu = this.hideMenu.bind(this);
|
||||||
|
this.toggle = this.toggle.bind(this);
|
||||||
|
this.onWindowClick = this.onWindowClick.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
showMenu(event) {
|
||||||
|
let pressedKey = event.keyCode;
|
||||||
|
this.setState({ isMenuOpen: true, });
|
||||||
|
|
||||||
|
// User pressed tab
|
||||||
|
if (pressedKey === 9) {
|
||||||
|
this.hideMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
// User pressed down arrow or enter or space
|
||||||
|
if (pressedKey === 40 || pressedKey === 13 || pressedKey === 32) {
|
||||||
|
this.props.focusMenu(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hideMenu() {
|
||||||
|
this.setState({ isMenuOpen: false, });
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount () {
|
||||||
|
const { addEventListener } = window;
|
||||||
|
addEventListener('click', this.onWindowClick, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount () {
|
||||||
|
const { removeEventListener } = window;
|
||||||
|
removeEventListener('click', this.onWindowClick, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
onWindowClick(event) {
|
||||||
|
const dropdownElement = findDOMNode(this);
|
||||||
|
const shouldUpdateState = event.target !== dropdownElement &&
|
||||||
|
!dropdownElement.contains(event.target) &&
|
||||||
|
this.state.isMenuOpen;
|
||||||
|
|
||||||
|
if (shouldUpdateState) {
|
||||||
|
this.hideMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toggle(event) {
|
||||||
|
if (this.state.isMenuOpen) {
|
||||||
|
this.hideMenu();
|
||||||
|
} else {
|
||||||
|
this.showMenu(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const toggle = this.toggle;
|
||||||
|
|
||||||
|
// stick callback on trigger element
|
||||||
|
const boundChildren = React.Children.map(this.props.children, (child) => {
|
||||||
|
if (child.type === DropdownTrigger) {
|
||||||
|
child = React.cloneElement(child, {
|
||||||
|
toggle: toggle,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return child;
|
||||||
|
});
|
||||||
|
|
||||||
|
let trigger = boundChildren[0];
|
||||||
|
let content = boundChildren[1];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.dropdown}>
|
||||||
|
{trigger}
|
||||||
|
{this.state.isMenuOpen ?
|
||||||
|
content : null}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
import Button from '/imports/ui/components/button/component';
|
||||||
|
import styles from '../styles';
|
||||||
|
|
||||||
|
export default class DropdownTrigger extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.toggle = this.props.toggle.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { labelBtn, iconBtn } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
className={styles.settingBtn}
|
||||||
|
role='button'
|
||||||
|
label={labelBtn}
|
||||||
|
icon={iconBtn}
|
||||||
|
ghost={true}
|
||||||
|
circle={true}
|
||||||
|
hideLabel={true}
|
||||||
|
onClick={this.toggle}
|
||||||
|
onKeyDown={this.toggle}
|
||||||
|
aria-haspopup={'true'}/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
67
bigbluebutton-html5/imports/ui/components/dropdown/styles.scss
Executable file
67
bigbluebutton-html5/imports/ui/components/dropdown/styles.scss
Executable file
@ -0,0 +1,67 @@
|
|||||||
|
@import "../../stylesheets/variables/_all";
|
||||||
|
|
||||||
|
.settingsMenuItem {
|
||||||
|
padding-top:20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settingsMenuItemText {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menuList {
|
||||||
|
list-style-type: none;
|
||||||
|
padding-left: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settingBtn {
|
||||||
|
-ms-transform: rotate( 90deg ); /* IE 9 */
|
||||||
|
-webkit-transform: rotate( 90deg ); /* Safari */
|
||||||
|
transform: rotate( 90deg );
|
||||||
|
color: #ffffff;
|
||||||
|
span {
|
||||||
|
border: 0px solid;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.hrDropdown {
|
||||||
|
border: 0.3px solid $color-gray-light;
|
||||||
|
width: 165px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdownActiveContent {
|
||||||
|
margin-top: 14px;
|
||||||
|
margin-right: -3px;
|
||||||
|
padding-left: 15px;
|
||||||
|
height: auto;
|
||||||
|
width: 190px;
|
||||||
|
display: block;
|
||||||
|
background-color: #ffffff;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
text-align: left;
|
||||||
|
font-size: $font-size-base;
|
||||||
|
border-radius: 3%;
|
||||||
|
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.triangleOnDropdown {
|
||||||
|
position: absolute;
|
||||||
|
margin-top: 5px;
|
||||||
|
margin-left: -2px;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-left: 18px solid transparent;
|
||||||
|
border-right: 18px solid transparent;
|
||||||
|
border-bottom: 18px solid #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconColor {
|
||||||
|
font-size: $font-size-base;
|
||||||
|
color: $color-gray-light;
|
||||||
|
}
|
@ -23,15 +23,13 @@ export default class BaseModal extends React.Component {
|
|||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
modalIsOpen: false,
|
// You need to set isOpen={true} on the modal component for it to render its children.
|
||||||
|
modalIsOpen: true,
|
||||||
title: props.title || 'title',
|
title: props.title || 'title',
|
||||||
content: <div>hello</div>,
|
content: <div>hello</div>,
|
||||||
};
|
};
|
||||||
this.openModal = this.openModal.bind(this);
|
this.openModal = this.openModal.bind(this);
|
||||||
this.closeModal = this.closeModal.bind(this);
|
this.closeModal = this.closeModal.bind(this);
|
||||||
this.handleModalCloseRequest = this.handleModalCloseRequest.bind(this);
|
|
||||||
this.handleSaveClicked = this.handleSaveClicked.bind(this);
|
|
||||||
this.afterOpenModal = this.afterOpenModal.bind(this);
|
|
||||||
this.setTitle = this.setTitle.bind(this);
|
this.setTitle = this.setTitle.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,18 +45,6 @@ export default class BaseModal extends React.Component {
|
|||||||
this.setState({ modalIsOpen: false });
|
this.setState({ modalIsOpen: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
afterOpenModal() {}
|
|
||||||
|
|
||||||
handleModalCloseRequest() {
|
|
||||||
// opportunity to validate something and keep the modal open even if it
|
|
||||||
// requested to be closed
|
|
||||||
this.setState({ modalIsOpen: false });
|
|
||||||
}
|
|
||||||
|
|
||||||
handleSaveClicked(e) {
|
|
||||||
alert('Save button was clicked');
|
|
||||||
}
|
|
||||||
|
|
||||||
getContent() {
|
getContent() {
|
||||||
return (<div>parent content</div>);
|
return (<div>parent content</div>);
|
||||||
}
|
}
|
||||||
@ -68,11 +54,8 @@ export default class BaseModal extends React.Component {
|
|||||||
<span>
|
<span>
|
||||||
<Modal
|
<Modal
|
||||||
isOpen={this.state.modalIsOpen}
|
isOpen={this.state.modalIsOpen}
|
||||||
onAfterOpen={this.afterOpenModal}
|
|
||||||
onRequestClose={this.closeModal}
|
onRequestClose={this.closeModal}
|
||||||
shouldCloseOnOverlayClick={false}
|
|
||||||
style={customStyles} >
|
style={customStyles} >
|
||||||
|
|
||||||
<span className={classNames(styles.modalHeaderTitle, 'largeFont')}>
|
<span className={classNames(styles.modalHeaderTitle, 'largeFont')}>
|
||||||
{this.state.title}
|
{this.state.title}
|
||||||
</span>
|
</span>
|
||||||
|
@ -19,7 +19,6 @@ export default class SettingsModal extends BaseModal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
this.setState({ activeSubmenu: 0 });
|
|
||||||
this.submenus.push({ className: AudioMenu,
|
this.submenus.push({ className: AudioMenu,
|
||||||
props: { title: 'Audio', prependIconName: 'ion-', icon: 'ios-mic-outline', }, });
|
props: { title: 'Audio', prependIconName: 'ion-', icon: 'ios-mic-outline', }, });
|
||||||
this.submenus.push({ className: VideoMenu,
|
this.submenus.push({ className: VideoMenu,
|
||||||
@ -33,11 +32,7 @@ export default class SettingsModal extends BaseModal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
ReactDOM.render(
|
return (<div onClick={this.openModal}></div>);
|
||||||
<Button componentClass='button' style={{ width: '30px', height: '30px', float: 'right' }}
|
|
||||||
onClick={this.openModal} i_class='icon ion-gear-b' rel='tooltip' title='Settings'>
|
|
||||||
<Icon iconName='icon ion-gear-b' className='mediumFont icon ion-gear-b'/>
|
|
||||||
</Button>, document.getElementById('settingsButtonPlaceHolder'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
createMenu() {
|
createMenu() {
|
||||||
@ -54,17 +49,9 @@ export default class SettingsModal extends BaseModal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
clickSubmenu(i) {
|
clickSubmenu(i) {
|
||||||
if (this.submenus[i].className != SessionMenu) {
|
this.setState({ activeSubmenu: i });
|
||||||
this.setState({ activeSubmenu: i });
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
doubleClickSubmenu(i) {
|
|
||||||
if (this.submenus[i].className == SessionMenu) {
|
|
||||||
this.setState({ activeSubmenu: i });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getContent() {
|
getContent() {
|
||||||
return (
|
return (
|
||||||
<div style={{ clear: 'both' }}>
|
<div style={{ clear: 'both' }}>
|
||||||
@ -72,7 +59,6 @@ export default class SettingsModal extends BaseModal {
|
|||||||
<ul style={{ listStyleType: 'none' }}>
|
<ul style={{ listStyleType: 'none' }}>
|
||||||
{this.submenus.map((value, index) => (
|
{this.submenus.map((value, index) => (
|
||||||
<li key={index} onClick={this.clickSubmenu.bind(this, index)}
|
<li key={index} onClick={this.clickSubmenu.bind(this, index)}
|
||||||
onDoubleClick={this.doubleClickSubmenu.bind(this, index)}
|
|
||||||
className={classNames(styles.settingsSubmenuItem,
|
className={classNames(styles.settingsSubmenuItem,
|
||||||
index == this.state.activeSubmenu ? styles.settingsSubmenuItemActive : null)}>
|
index == this.state.activeSubmenu ? styles.settingsSubmenuItemActive : null)}>
|
||||||
<Icon key={index} prependIconName={value.props.prependIconName}
|
<Icon key={index} prependIconName={value.props.prependIconName}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import React from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
import ReactDOM from 'react-dom';
|
||||||
import Modal from 'react-modal';
|
import Modal from 'react-modal';
|
||||||
import Button from '/imports/ui/components/button/component';
|
import Button from '/imports/ui/components/button/component';
|
||||||
import BaseMenu from './BaseMenu';
|
import BaseMenu from './BaseMenu';
|
||||||
@ -40,18 +41,24 @@ export default class SessionMenu extends BaseMenu {
|
|||||||
<span>
|
<span>
|
||||||
<Modal
|
<Modal
|
||||||
isOpen={this.state.openConfirm}
|
isOpen={this.state.openConfirm}
|
||||||
style={customModal} >
|
style={customModal}
|
||||||
|
onRequestClose={this.closeLogout}
|
||||||
|
tabIndex="-1">
|
||||||
<span className={classNames(styles.modalHeaderTitle, 'largeFont')}> Leave Session</span>
|
<span className={classNames(styles.modalHeaderTitle, 'largeFont')}> Leave Session</span>
|
||||||
<hr className={styles.modalHorizontalRule} />
|
<hr className={styles.modalHorizontalRule} />
|
||||||
<span>Do you want to leave this meeting?</span>
|
<span>Do you want to leave this meeting?</span>
|
||||||
<br />
|
<br />
|
||||||
<button onClick={Auth.completeLogout}
|
<button onClick={Auth.completeLogout}
|
||||||
className={classNames(styles.modalButton, styles.done)}
|
className={classNames(styles.modalButton, styles.done)}
|
||||||
tabindex="0"
|
tabIndex='8'
|
||||||
|
aria-labelledby="logout_okay"
|
||||||
|
aria-describedby="logout_okay"
|
||||||
role="button">Yes</button>
|
role="button">Yes</button>
|
||||||
<button onClick={this.closeLogout}
|
<button onClick={this.closeLogout}
|
||||||
className={classNames(styles.modalButton, styles.close)}
|
className={classNames(styles.modalButton, styles.close)}
|
||||||
tabindex="1"
|
tabIndex='9'
|
||||||
|
aria-labelledby="logout_cancel"
|
||||||
|
aria-describedby="logout_cancel"
|
||||||
role="button">No</button>
|
role="button">No</button>
|
||||||
</Modal>
|
</Modal>
|
||||||
</span>
|
</span>
|
||||||
|
@ -2,6 +2,7 @@ import React, { Component, PropTypes } from 'react';
|
|||||||
import styles from './styles.scss';
|
import styles from './styles.scss';
|
||||||
import Button from '../button/component';
|
import Button from '../button/component';
|
||||||
import RecordButton from './recordbutton/component';
|
import RecordButton from './recordbutton/component';
|
||||||
|
import SettingsDropdown from '../dropdown/component';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
presentationTitle: PropTypes.string.isRequired,
|
presentationTitle: PropTypes.string.isRequired,
|
||||||
@ -51,7 +52,7 @@ class NavBar extends Component {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.right}>
|
<div className={styles.right}>
|
||||||
<span id="settingsButtonPlaceHolder"></span>
|
<SettingsDropdown />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user