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.

ToolbarButton.web.js 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /* @flow */
  2. import React, { Component } from 'react';
  3. import { translate } from '../../base/i18n';
  4. import {
  5. setTooltip,
  6. setTooltipText
  7. } from '../../../../modules/UI/util/Tooltip';
  8. import StatelessToolbarButton from './StatelessToolbarButton';
  9. declare var APP: Object;
  10. /**
  11. * Represents a button in Toolbar on React.
  12. *
  13. * @class ToolbarButton
  14. * @extends AbstractToolbarButton
  15. */
  16. class ToolbarButton extends Component {
  17. button: Object;
  18. _createRefToButton: Function;
  19. /**
  20. * Toolbar button component's property types.
  21. *
  22. * @static
  23. */
  24. static propTypes = {
  25. ...StatelessToolbarButton.propTypes,
  26. /**
  27. * Object describing button.
  28. */
  29. button: React.PropTypes.object.isRequired,
  30. /**
  31. * Handler for component mount.
  32. */
  33. onMount: React.PropTypes.func,
  34. /**
  35. * Handler for component unmount.
  36. */
  37. onUnmount: React.PropTypes.func,
  38. /**
  39. * Translation helper function.
  40. */
  41. t: React.PropTypes.func,
  42. /**
  43. * Indicates the position of the tooltip.
  44. */
  45. tooltipPosition:
  46. React.PropTypes.oneOf([ 'bottom', 'left', 'right', 'top' ])
  47. };
  48. /**
  49. * Initializes new ToolbarButton instance.
  50. *
  51. * @param {Object} props - The read-only properties with which the new
  52. * instance is to be initialized.
  53. */
  54. constructor(props: Object) {
  55. super(props);
  56. // Bind methods to save the context
  57. this._createRefToButton = this._createRefToButton.bind(this);
  58. }
  59. /**
  60. * Sets shortcut/tooltip
  61. * after mounting of the component.
  62. *
  63. * @inheritdoc
  64. * @returns {void}
  65. */
  66. componentDidMount(): void {
  67. this._setShortcutAndTooltip();
  68. if (this.props.onMount) {
  69. this.props.onMount();
  70. }
  71. }
  72. /**
  73. * Invokes on unmount handler if it was passed to the props.
  74. *
  75. * @inheritdoc
  76. * @returns {void}
  77. */
  78. componentWillUnmount(): void {
  79. if (this.props.onUnmount) {
  80. this.props.onUnmount();
  81. }
  82. }
  83. /**
  84. * Implements React's {@link Component#render()}.
  85. *
  86. * @inheritdoc
  87. * @returns {ReactElement}
  88. */
  89. render(): ReactElement<*> {
  90. const { button } = this.props;
  91. const popups = button.popups || [];
  92. const props = {
  93. ...this.props,
  94. createRefToButton: this._createRefToButton
  95. };
  96. return (
  97. <StatelessToolbarButton { ...props }>
  98. { this._renderPopups(popups) }
  99. </StatelessToolbarButton>
  100. );
  101. }
  102. /**
  103. * Creates reference to current toolbar button.
  104. *
  105. * @param {HTMLElement} element - HTMLElement representing the toolbar
  106. * button.
  107. * @returns {void}
  108. * @private
  109. */
  110. _createRefToButton(element: HTMLElement): void {
  111. this.button = element;
  112. }
  113. /**
  114. * If toolbar button should contain children elements
  115. * renders them.
  116. *
  117. * @returns {ReactElement|null}
  118. * @private
  119. */
  120. _renderInnerElementsIfRequired(): ReactElement<*> | null {
  121. if (this.props.button.html) {
  122. return this.props.button.html;
  123. }
  124. return null;
  125. }
  126. /**
  127. * Renders popup element for toolbar button.
  128. *
  129. * @param {Array} popups - Array of popup objects.
  130. * @returns {Array}
  131. * @private
  132. */
  133. _renderPopups(popups: Array<*> = []): Array<*> {
  134. return popups.map(popup => {
  135. let gravity = 'n';
  136. if (popup.dataAttrPosition) {
  137. gravity = popup.dataAttrPosition;
  138. }
  139. const title = this.props.t(popup.dataAttr, popup.dataInterpolate);
  140. return (
  141. <div
  142. className = { popup.className }
  143. data-popup = { gravity }
  144. id = { popup.id }
  145. key = { popup.id }
  146. title = { title } />
  147. );
  148. });
  149. }
  150. /**
  151. * Sets shortcut and tooltip for current toolbar button.
  152. *
  153. * @private
  154. * @returns {void}
  155. */
  156. _setShortcutAndTooltip(): void {
  157. const { button, tooltipPosition } = this.props;
  158. if (!button.unclickable) {
  159. if (button.tooltipText) {
  160. setTooltipText(this.button,
  161. button.tooltipText,
  162. tooltipPosition);
  163. } else {
  164. setTooltip(this.button,
  165. button.tooltipKey,
  166. tooltipPosition);
  167. }
  168. }
  169. if (button.shortcut && APP && APP.keyboardshortcut) {
  170. APP.keyboardshortcut.registerShortcut(
  171. button.shortcut,
  172. button.shortcutAttr,
  173. button.shortcutFunc,
  174. button.shortcutDescription
  175. );
  176. }
  177. }
  178. }
  179. export default translate(ToolbarButton);