| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 | 
							- // @flow
 - 
 - import PropTypes from 'prop-types';
 - import React, { Component } from 'react';
 - import { connect } from 'react-redux';
 - 
 - import { setToolbarHovered } from '../actions';
 - 
 - import StatelessToolbar from './StatelessToolbar';
 - import ToolbarButton from './ToolbarButton';
 - 
 - /**
 -  * 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.
 -  *
 -  * @class Toolbar
 -  * @extends Component
 -  */
 - class Toolbar extends Component<*> {
 -     /**
 -      * Base toolbar component's property types.
 -      *
 -      * @static
 -      */
 -     static propTypes = {
 -         /**
 -          * Children of current React component.
 -          */
 -         children: PropTypes.element,
 - 
 -         /**
 -          * Toolbar's class name.
 -          */
 -         className: PropTypes.string,
 - 
 -         /**
 -          * Used to dispatch an action when a button is clicked or on mouse
 -          * out/in event.
 -          */
 -         dispatch: PropTypes.func,
 - 
 -         /**
 -          * Map with toolbar buttons.
 -          */
 -         toolbarButtons: PropTypes.instanceOf(Map),
 - 
 -         /**
 -          * Indicates the position of the tooltip.
 -          */
 -         tooltipPosition: PropTypes.oneOf([ 'bottom', 'left', 'right', 'top' ])
 -     };
 - 
 -     /**
 -      * Constructor of Primary toolbar class.
 -      *
 -      * @param {Object} props - Object containing React component properties.
 -      */
 -     constructor(props: Object) {
 -         super(props);
 - 
 -         // Bind callbacks to preverse this.
 -         this._onMouseOut = this._onMouseOut.bind(this);
 -         this._onMouseOver = this._onMouseOver.bind(this);
 -         this._renderToolbarButton = this._renderToolbarButton.bind(this);
 -     }
 - 
 -     /**
 -      * Implements React's {@link Component#render()}.
 -      *
 -      * @inheritdoc
 -      * @returns {ReactElement}
 -      */
 -     render(): React$Element<*> {
 -         const props = {
 -             className: this.props.className,
 -             onMouseOut: this._onMouseOut,
 -             onMouseOver: this._onMouseOver
 -         };
 - 
 -         return (
 -             <StatelessToolbar { ...props }>
 -                 {
 -                     [ ...this.props.toolbarButtons.entries() ]
 -                         .map(this._renderToolbarButton)
 -                 }
 -                 {
 -                     this.props.children
 -                 }
 -             </StatelessToolbar>
 -         );
 -     }
 - 
 -     _onMouseOut: () => void;
 - 
 -     /**
 -      * Dispatches an action signalling that toolbar is no being hovered.
 -      *
 -      * @protected
 -      * @returns {void}
 -      */
 -     _onMouseOut() {
 -         this.props.dispatch(setToolbarHovered(false));
 -     }
 - 
 -     _onMouseOver: () => void;
 - 
 -     /**
 -      * Dispatches an action signalling that toolbar is now being hovered.
 -      *
 -      * @protected
 -      * @returns {void}
 -      */
 -     _onMouseOver() {
 -         this.props.dispatch(setToolbarHovered(true));
 -     }
 - 
 -     _renderToolbarButton: (Array<*>) => React$Element<*>;
 - 
 -     /**
 -      * Renders toolbar button. Method is passed to map function.
 -      *
 -      * @param {Array} keyValuePair - Key value pair containing button and its
 -      * key.
 -      * @private
 -      * @returns {ReactElement} A toolbar button.
 -      */
 -     _renderToolbarButton([ key, button ]): React$Element<*> {
 -         const { tooltipPosition } = this.props;
 - 
 -         if (button.component) {
 -             return (
 -                 <button.component
 -                     key = { key }
 -                     toggled = { button.toggled }
 -                     tooltipPosition = { tooltipPosition } />
 -             );
 -         }
 - 
 -         const {
 -             childComponent: ChildComponent,
 -             onClick,
 -             onMount,
 -             onUnmount
 -         } = button;
 -         const onClickWithDispatch = (...args) =>
 -             onClick && onClick(this.props.dispatch, ...args);
 - 
 -         return (
 -             <ToolbarButton
 -                 button = { button }
 -                 key = { key }
 - 
 -                 // TODO The following disables an eslint error alerting about a
 -                 // known potential/theoretical performance pernalty:
 -                 //
 -                 // A bind call or arrow function in a JSX prop will create a
 -                 // brand new function on every single render. This is bad for
 -                 // performance, as it will result in the garbage collector being
 -                 // invoked way more than is necessary. It may also cause
 -                 // unnecessary re-renders if a brand new function is passed as a
 -                 // prop to a component that uses reference equality check on the
 -                 // prop to determine if it should update.
 -                 //
 -                 // I'm not addressing the potential/theoretical performance
 -                 // penalty at the time of this writing because I don't know for
 -                 // a fact that it's a practical performance penalty in the case.
 -                 //
 -                 // eslint-disable-next-line react/jsx-no-bind
 -                 onClick = { onClickWithDispatch }
 -                 onMount = { onMount }
 -                 onUnmount = { onUnmount }
 -                 tooltipPosition = { tooltipPosition }>
 -                 { button.html || null }
 -                 { ChildComponent ? <ChildComponent /> : null }
 -             </ToolbarButton>
 -         );
 -     }
 - }
 - 
 - export default connect()(Toolbar);
 
 
  |