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.

StatelessToolbarButton.js 2.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /* @flow */
  2. import PropTypes from 'prop-types';
  3. import React from 'react';
  4. import AbstractToolbarButton from './AbstractToolbarButton';
  5. type MapOfAttributes = { [key: string]: * };
  6. /* eslint-disable flowtype/space-before-type-colon */
  7. /**
  8. * Takes toolbar button props and maps them to HTML attributes to set.
  9. *
  10. * @param {Object} props - Props set to the React component.
  11. * @returns {MapOfAttributes}
  12. */
  13. function getButtonAttributesByProps(props: Object = {})
  14. : MapOfAttributes {
  15. // XXX Make sure to not modify props.classNames because that'd be bad
  16. // practice.
  17. const classNames = (props.classNames && [ ...props.classNames ]) || [];
  18. props.toggled && classNames.push('toggled');
  19. props.unclickable && classNames.push('unclickable');
  20. const result: MapOfAttributes = {
  21. className: classNames.join(' '),
  22. 'data-container': 'body',
  23. 'data-placement': 'bottom',
  24. id: props.id
  25. };
  26. if (!props.enabled) {
  27. result.disabled = 'disabled';
  28. }
  29. if (props.hidden) {
  30. result.style = { display: 'none' };
  31. }
  32. if (props.tooltipText) {
  33. result.content = props.tooltipText;
  34. }
  35. return result;
  36. }
  37. /* eslint-enable flowtype/space-before-type-colon */
  38. /**
  39. * Represents a button in Toolbar on React.
  40. *
  41. * @class ToolbarButton
  42. * @extends AbstractToolbarButton
  43. */
  44. export default class StatelessToolbarButton extends AbstractToolbarButton {
  45. _onClick: Function;
  46. /**
  47. * Toolbar button component's property types.
  48. *
  49. * @static
  50. */
  51. static propTypes = {
  52. ...AbstractToolbarButton.propTypes,
  53. /**
  54. * Object describing button.
  55. */
  56. button: PropTypes.object.isRequired
  57. };
  58. /**
  59. * Initializes new ToolbarButton instance.
  60. *
  61. * @param {Object} props - The read-only properties with which the new
  62. * instance is to be initialized.
  63. */
  64. constructor(props: Object) {
  65. super(props);
  66. // Bind methods to save the context
  67. this._onClick = this._onClick.bind(this);
  68. }
  69. /**
  70. * Implements React's {@link Component#render()}.
  71. *
  72. * @inheritdoc
  73. * @returns {ReactElement}
  74. */
  75. render(): React$Element<*> {
  76. const { button } = this.props;
  77. const attributes = getButtonAttributesByProps(button);
  78. return (
  79. <a
  80. { ...attributes }
  81. onClick = { this._onClick }>
  82. { this.props.children }
  83. </a>
  84. );
  85. }
  86. /**
  87. * Wrapper on on click handler props for current button.
  88. *
  89. * @param {Event} event - Click event object.
  90. * @returns {void}
  91. * @private
  92. */
  93. _onClick(event: Event): void {
  94. const {
  95. button,
  96. onClick
  97. } = this.props;
  98. const {
  99. enabled,
  100. unclickable
  101. } = button;
  102. if (enabled && !unclickable && onClick) {
  103. onClick(event);
  104. }
  105. }
  106. }