jiti-meet/react/features/toolbox/components/Toolbar.web.js

220 lines
5.6 KiB
JavaScript
Raw Normal View History

2017-02-16 23:02:40 +00:00
/* @flow */
import React, { Component } from 'react';
import { connect } from 'react-redux';
import {
setToolbarHovered
} from '../actions';
import ToolbarButton from './ToolbarButton';
/**
2017-04-01 05:52:40 +00:00
* Implements a toolbar in React/Web. It is a strip that contains a set of
* toolbar items such as buttons. Toolbar is commonly placed inside of a
* Toolbox.
2017-02-16 23:02:40 +00:00
*
2017-04-01 05:52:40 +00:00
* @class Toolbar
2017-02-16 23:02:40 +00:00
* @extends Component
*/
2017-04-01 05:52:40 +00:00
class Toolbar extends Component {
2017-02-16 23:02:40 +00:00
_renderToolbarButton: Function;
/**
* Base toolbar component's property types.
*
* @static
*/
static propTypes = {
/**
* Handler for mouse out event.
*/
_onMouseOut: React.PropTypes.func,
/**
* Handler for mouse over event.
*/
_onMouseOver: React.PropTypes.func,
/**
* Contains button handlers.
*/
buttonHandlers: React.PropTypes.object,
/**
* Children of current React component.
*/
children: React.PropTypes.element,
/**
* Toolbar's class name.
*/
className: React.PropTypes.string,
/**
* If the toolbar requires splitter this property defines splitter
* index.
*/
splitterIndex: React.PropTypes.number,
/**
* Map with toolbar buttons.
*/
2017-04-06 22:40:10 +00:00
toolbarButtons: React.PropTypes.instanceOf(Map),
/**
* Indicates the position of the tooltip.
*/
tooltipPosition:
React.PropTypes.oneOf([ 'bottom', 'left', 'right', 'top' ])
2017-02-16 23:02:40 +00:00
};
/**
* Constructor of Primary toolbar class.
*
* @param {Object} props - Object containing React component properties.
*/
constructor(props) {
super(props);
this._setButtonHandlers();
2017-04-06 22:40:10 +00:00
// Bind callbacks to preverse this.
2017-02-16 23:02:40 +00:00
this._renderToolbarButton = this._renderToolbarButton.bind(this);
}
/**
* Implements React's {@link Component#render()}.
*
* @inheritdoc
* @returns {ReactElement}
*/
render(): ReactElement<*> {
const { className } = this.props;
return (
<div
className = { `toolbar ${className}` }
onMouseOut = { this.props._onMouseOut }
onMouseOver = { this.props._onMouseOver }>
{
[ ...this.props.toolbarButtons.entries() ]
.reduce(this._renderToolbarButton, [])
}
{
this.props.children
}
</div>
);
}
/**
* Renders toolbar button. Method is passed to reduce function.
*
* @param {Array} acc - Toolbar buttons array.
* @param {Array} keyValuePair - Key value pair containing button and its
* key.
* @param {number} index - Index of the key value pair in the array.
* @returns {Array} Array of toolbar buttons and splitter if it's on.
* @private
*/
_renderToolbarButton(acc: Array<*>, keyValuePair: Array<*>,
index: number): Array<ReactElement<*>> {
const [ key, button ] = keyValuePair;
if (button.component) {
acc.push(
<button.component
key = { key }
tooltipPosition = { this.props.tooltipPosition } />
);
return acc;
}
2017-04-06 22:40:10 +00:00
const { splitterIndex, tooltipPosition } = this.props;
2017-02-16 23:02:40 +00:00
if (splitterIndex && index === splitterIndex) {
const splitter = <span className = 'toolbar__splitter' />;
acc.push(splitter);
}
const { onClick, onMount, onUnmount } = button;
acc.push(
<ToolbarButton
button = { button }
key = { key }
onClick = { onClick }
onMount = { onMount }
2017-04-06 22:40:10 +00:00
onUnmount = { onUnmount }
tooltipPosition = { tooltipPosition } />
2017-02-16 23:02:40 +00:00
);
return acc;
}
/**
* Sets handlers for some of the buttons.
*
* @private
* @returns {void}
*/
_setButtonHandlers(): void {
const {
buttonHandlers,
toolbarButtons
} = this.props;
2017-04-06 22:40:10 +00:00
// Only a few buttons have buttonHandlers defined, so it may be
// undefined or empty depending on the buttons rendered.
// TODO Merge the buttonHandlers and onClick properties and come up with
// a consistent event handling property.
buttonHandlers && Object.keys(buttonHandlers).forEach(key => {
2017-02-16 23:02:40 +00:00
let button = toolbarButtons.get(key);
if (button) {
button = {
...button,
...buttonHandlers[key]
};
toolbarButtons.set(key, button);
}
});
}
}
/**
* Maps part of Redux actions to component's props.
*
* @param {Function} dispatch - Redux action dispatcher.
* @returns {Object}
* @private
*/
function _mapDispatchToProps(dispatch: Function): Object {
return {
/**
* Dispatches an action signalling that toolbar is no being hovered.
*
* @protected
* @returns {Object} Dispatched action.
*/
_onMouseOut() {
return dispatch(setToolbarHovered(false));
},
/**
* Dispatches an action signalling that toolbar is now being hovered.
*
* @protected
* @returns {Object} Dispatched action.
*/
_onMouseOver() {
return dispatch(setToolbarHovered(true));
}
};
}
2017-04-01 05:52:40 +00:00
export default connect(null, _mapDispatchToProps)(Toolbar);