Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

ReactionButton.js 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /* @flow */
  2. import React from 'react';
  3. import Tooltip from '../../../base/tooltip/components/Tooltip';
  4. import AbstractToolbarButton from '../../../toolbox/components/AbstractToolbarButton';
  5. import type { Props as AbstractToolbarButtonProps } from '../../../toolbox/components/AbstractToolbarButton';
  6. /**
  7. * The type of the React {@code Component} props of {@link ReactionButton}.
  8. */
  9. type Props = AbstractToolbarButtonProps & {
  10. /**
  11. * Optional text to display in the tooltip.
  12. */
  13. tooltip?: string,
  14. /**
  15. * From which direction the tooltip should appear, relative to the
  16. * button.
  17. */
  18. tooltipPosition: string,
  19. /**
  20. * Optional label for the button.
  21. */
  22. label?: string
  23. };
  24. /**
  25. * The type of the React {@code Component} state of {@link ReactionButton}.
  26. */
  27. type State = {
  28. /**
  29. * Used to determine zoom level on reaction burst.
  30. */
  31. increaseLevel: number,
  32. /**
  33. * Timeout ID to reset reaction burst.
  34. */
  35. increaseTimeout: TimeoutID | null
  36. }
  37. /**
  38. * Represents a button in the reactions menu.
  39. *
  40. * @augments AbstractToolbarButton
  41. */
  42. class ReactionButton extends AbstractToolbarButton<Props, State> {
  43. /**
  44. * Default values for {@code ReactionButton} component's properties.
  45. *
  46. * @static
  47. */
  48. static defaultProps = {
  49. tooltipPosition: 'top'
  50. };
  51. /**
  52. * Initializes a new {@code ReactionButton} instance.
  53. *
  54. * @inheritdoc
  55. */
  56. constructor(props: Props) {
  57. super(props);
  58. this._onKeyDown = this._onKeyDown.bind(this);
  59. this._onClickHandler = this._onClickHandler.bind(this);
  60. this.state = {
  61. increaseLevel: 0,
  62. increaseTimeout: null
  63. };
  64. }
  65. _onKeyDown: (Object) => void;
  66. _onClickHandler: () => void;
  67. /**
  68. * Handles 'Enter' key on the button to trigger onClick for accessibility.
  69. * We should be handling Space onKeyUp but it conflicts with PTT.
  70. *
  71. * @param {Object} event - The key event.
  72. * @private
  73. * @returns {void}
  74. */
  75. _onKeyDown(event) {
  76. // If the event coming to the dialog has been subject to preventDefault
  77. // we don't handle it here.
  78. if (event.defaultPrevented) {
  79. return;
  80. }
  81. if (event.key === 'Enter') {
  82. event.preventDefault();
  83. event.stopPropagation();
  84. this.props.onClick();
  85. }
  86. }
  87. /**
  88. * Handles reaction button click.
  89. *
  90. * @returns {void}
  91. */
  92. _onClickHandler() {
  93. this.props.onClick();
  94. clearTimeout(this.state.increaseTimeout);
  95. const timeout = setTimeout(() => {
  96. this.setState({
  97. increaseLevel: 0
  98. });
  99. }, 500);
  100. this.setState(state => {
  101. return {
  102. increaseLevel: state.increaseLevel + 1,
  103. increaseTimeout: timeout
  104. };
  105. });
  106. }
  107. /**
  108. * Renders the button of this {@code ReactionButton}.
  109. *
  110. * @param {Object} children - The children, if any, to be rendered inside
  111. * the button. Presumably, contains the emoji of this {@code ReactionButton}.
  112. * @protected
  113. * @returns {ReactElement} The button of this {@code ReactionButton}.
  114. */
  115. _renderButton(children) {
  116. return (
  117. <div
  118. aria-label = { this.props.accessibilityLabel }
  119. aria-pressed = { this.props.toggled }
  120. className = 'toolbox-button'
  121. onClick = { this._onClickHandler }
  122. onKeyDown = { this._onKeyDown }
  123. role = 'button'
  124. tabIndex = { 0 }>
  125. { this.props.tooltip
  126. ? <Tooltip
  127. content = { this.props.tooltip }
  128. position = { this.props.tooltipPosition }>
  129. { children }
  130. </Tooltip>
  131. : children }
  132. </div>
  133. );
  134. }
  135. /**
  136. * Renders the icon (emoji) of this {@code reactionButton}.
  137. *
  138. * @inheritdoc
  139. */
  140. _renderIcon() {
  141. const { toggled, icon, label } = this.props;
  142. const { increaseLevel } = this.state;
  143. return (
  144. <div className = { `toolbox-icon ${toggled ? 'toggled' : ''}` }>
  145. <span className = { `emoji increase-${increaseLevel > 12 ? 12 : increaseLevel}` }>{icon}</span>
  146. {label && <span className = 'text'>{label}</span>}
  147. </div>
  148. );
  149. }
  150. }
  151. export default ReactionButton;