You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Toolbar.web.js 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /* @flow */
  2. import React, { Component } from 'react';
  3. import { connect } from 'react-redux';
  4. import {
  5. setToolbarHovered
  6. } from '../actions';
  7. import ToolbarButton from './ToolbarButton';
  8. declare var APP: Object;
  9. declare var config: Object;
  10. declare var interfaceConfig: Object;
  11. /**
  12. * Implements a toolbar in React/Web. It is a strip that contains a set of
  13. * toolbar items such as buttons. Toolbar is commonly placed inside of a
  14. * Toolbox.
  15. *
  16. * @class Toolbar
  17. * @extends Component
  18. */
  19. class Toolbar extends Component {
  20. _renderToolbarButton: Function;
  21. /**
  22. * Base toolbar component's property types.
  23. *
  24. * @static
  25. */
  26. static propTypes = {
  27. /**
  28. * Handler for mouse out event.
  29. */
  30. _onMouseOut: React.PropTypes.func,
  31. /**
  32. * Handler for mouse over event.
  33. */
  34. _onMouseOver: React.PropTypes.func,
  35. /**
  36. * Contains button handlers.
  37. */
  38. buttonHandlers: React.PropTypes.object,
  39. /**
  40. * Children of current React component.
  41. */
  42. children: React.PropTypes.element,
  43. /**
  44. * Toolbar's class name.
  45. */
  46. className: React.PropTypes.string,
  47. /**
  48. * If the toolbar requires splitter this property defines splitter
  49. * index.
  50. */
  51. splitterIndex: React.PropTypes.number,
  52. /**
  53. * Map with toolbar buttons.
  54. */
  55. toolbarButtons: React.PropTypes.instanceOf(Map)
  56. };
  57. /**
  58. * Constructor of Primary toolbar class.
  59. *
  60. * @param {Object} props - Object containing React component properties.
  61. */
  62. constructor(props) {
  63. super(props);
  64. this._setButtonHandlers();
  65. // Bind methods to save the context
  66. this._renderToolbarButton = this._renderToolbarButton.bind(this);
  67. }
  68. /**
  69. * Implements React's {@link Component#render()}.
  70. *
  71. * @inheritdoc
  72. * @returns {ReactElement}
  73. */
  74. render(): ReactElement<*> {
  75. const { className } = this.props;
  76. return (
  77. <div
  78. className = { `toolbar ${className}` }
  79. onMouseOut = { this.props._onMouseOut }
  80. onMouseOver = { this.props._onMouseOver }>
  81. {
  82. [ ...this.props.toolbarButtons.entries() ]
  83. .reduce(this._renderToolbarButton, [])
  84. }
  85. {
  86. this.props.children
  87. }
  88. </div>
  89. );
  90. }
  91. /**
  92. * Renders toolbar button. Method is passed to reduce function.
  93. *
  94. * @param {Array} acc - Toolbar buttons array.
  95. * @param {Array} keyValuePair - Key value pair containing button and its
  96. * key.
  97. * @param {number} index - Index of the key value pair in the array.
  98. * @returns {Array} Array of toolbar buttons and splitter if it's on.
  99. * @private
  100. */
  101. _renderToolbarButton(acc: Array<*>, keyValuePair: Array<*>,
  102. index: number): Array<ReactElement<*>> {
  103. const [ key, button ] = keyValuePair;
  104. const { splitterIndex } = this.props;
  105. if (splitterIndex && index === splitterIndex) {
  106. const splitter = <span className = 'toolbar__splitter' />;
  107. acc.push(splitter);
  108. }
  109. const { onClick, onMount, onUnmount } = button;
  110. acc.push(
  111. <ToolbarButton
  112. button = { button }
  113. key = { key }
  114. onClick = { onClick }
  115. onMount = { onMount }
  116. onUnmount = { onUnmount } />
  117. );
  118. return acc;
  119. }
  120. /**
  121. * Sets handlers for some of the buttons.
  122. *
  123. * @private
  124. * @returns {void}
  125. */
  126. _setButtonHandlers(): void {
  127. const {
  128. buttonHandlers,
  129. toolbarButtons
  130. } = this.props;
  131. Object.keys(buttonHandlers).forEach(key => {
  132. let button = toolbarButtons.get(key);
  133. if (button) {
  134. button = {
  135. ...button,
  136. ...buttonHandlers[key]
  137. };
  138. toolbarButtons.set(key, button);
  139. }
  140. });
  141. }
  142. }
  143. /**
  144. * Maps part of Redux actions to component's props.
  145. *
  146. * @param {Function} dispatch - Redux action dispatcher.
  147. * @returns {Object}
  148. * @private
  149. */
  150. function _mapDispatchToProps(dispatch: Function): Object {
  151. return {
  152. /**
  153. * Dispatches an action signalling that toolbar is no being hovered.
  154. *
  155. * @protected
  156. * @returns {Object} Dispatched action.
  157. */
  158. _onMouseOut() {
  159. return dispatch(setToolbarHovered(false));
  160. },
  161. /**
  162. * Dispatches an action signalling that toolbar is now being hovered.
  163. *
  164. * @protected
  165. * @returns {Object} Dispatched action.
  166. */
  167. _onMouseOver() {
  168. return dispatch(setToolbarHovered(true));
  169. }
  170. };
  171. }
  172. export default connect(null, _mapDispatchToProps)(Toolbar);