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

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