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 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /* @flow */
  2. import PropTypes from 'prop-types';
  3. import React, { Component } from 'react';
  4. import { connect } from 'react-redux';
  5. import { setToolbarHovered } from '../actions';
  6. import StatelessToolbar from './StatelessToolbar';
  7. import ToolbarButton from './ToolbarButton';
  8. /**
  9. * Implements a toolbar in React/Web. It is a strip that contains a set of
  10. * toolbar items such as buttons. Toolbar is commonly placed inside of a
  11. * Toolbox.
  12. *
  13. * @class Toolbar
  14. * @extends Component
  15. */
  16. class Toolbar extends Component<*> {
  17. _onMouseOut: Function;
  18. _onMouseOver: Function;
  19. _renderToolbarButton: Function;
  20. /**
  21. * Base toolbar component's property types.
  22. *
  23. * @static
  24. */
  25. static propTypes = {
  26. /**
  27. * Children of current React component.
  28. */
  29. children: PropTypes.element,
  30. /**
  31. * Toolbar's class name.
  32. */
  33. className: PropTypes.string,
  34. /**
  35. * Used to dispatch an action when a button is clicked or on mouse
  36. * out/in event.
  37. */
  38. dispatch: PropTypes.func,
  39. /**
  40. * Map with toolbar buttons.
  41. */
  42. toolbarButtons: PropTypes.instanceOf(Map),
  43. /**
  44. * Indicates the position of the tooltip.
  45. */
  46. tooltipPosition: PropTypes.oneOf([ 'bottom', 'left', 'right', 'top' ])
  47. };
  48. /**
  49. * Constructor of Primary toolbar class.
  50. *
  51. * @param {Object} props - Object containing React component properties.
  52. */
  53. constructor(props: Object) {
  54. super(props);
  55. // Bind callbacks to preverse this.
  56. this._onMouseOut = this._onMouseOut.bind(this);
  57. this._onMouseOver = this._onMouseOver.bind(this);
  58. this._renderToolbarButton = this._renderToolbarButton.bind(this);
  59. }
  60. /**
  61. * Implements React's {@link Component#render()}.
  62. *
  63. * @inheritdoc
  64. * @returns {ReactElement}
  65. */
  66. render(): React$Element<*> {
  67. const props = {
  68. className: this.props.className,
  69. onMouseOut: this._onMouseOut,
  70. onMouseOver: this._onMouseOver
  71. };
  72. return (
  73. <StatelessToolbar { ...props }>
  74. {
  75. [ ...this.props.toolbarButtons.entries() ]
  76. .map(this._renderToolbarButton)
  77. }
  78. {
  79. this.props.children
  80. }
  81. </StatelessToolbar>
  82. );
  83. }
  84. /**
  85. * Dispatches an action signalling that toolbar is no being hovered.
  86. *
  87. * @protected
  88. * @returns {Object} Dispatched action.
  89. */
  90. _onMouseOut() {
  91. this.props.dispatch(setToolbarHovered(false));
  92. }
  93. /**
  94. * Dispatches an action signalling that toolbar is now being hovered.
  95. *
  96. * @protected
  97. * @returns {Object} Dispatched action.
  98. */
  99. _onMouseOver() {
  100. this.props.dispatch(setToolbarHovered(true));
  101. }
  102. /**
  103. * Renders toolbar button. Method is passed to map function.
  104. *
  105. * @param {Array} keyValuePair - Key value pair containing button and its
  106. * key.
  107. * @private
  108. * @returns {ReactElement} A toolbar button.
  109. */
  110. _renderToolbarButton(keyValuePair: Array<*>): React$Element<*> {
  111. const [ key, button ] = keyValuePair;
  112. if (button.component) {
  113. return (
  114. <button.component
  115. key = { key }
  116. toggled = { button.toggled }
  117. tooltipPosition = { this.props.tooltipPosition } />
  118. );
  119. }
  120. const { tooltipPosition } = this.props;
  121. const {
  122. childComponent: ChildComponent,
  123. onClick,
  124. onMount,
  125. onUnmount
  126. } = button;
  127. const onClickWithDispatch = (...args) =>
  128. onClick && onClick(this.props.dispatch, ...args);
  129. return (
  130. <ToolbarButton
  131. button = { button }
  132. key = { key }
  133. onClick = { onClickWithDispatch }
  134. onMount = { onMount }
  135. onUnmount = { onUnmount }
  136. tooltipPosition = { tooltipPosition }>
  137. { button.html || null }
  138. { ChildComponent ? <ChildComponent /> : null }
  139. </ToolbarButton>
  140. );
  141. }
  142. }
  143. export default connect()(Toolbar);