2017-02-16 23:02:40 +00:00
|
|
|
/* @flow */
|
|
|
|
|
2017-10-06 16:14:45 +00:00
|
|
|
import InlineDialog from '@atlaskit/inline-dialog';
|
|
|
|
import Tooltip from '@atlaskit/tooltip';
|
2017-09-27 21:23:31 +00:00
|
|
|
import PropTypes from 'prop-types';
|
2017-07-31 08:02:41 +00:00
|
|
|
import React, { Component } from 'react';
|
2017-02-16 23:02:40 +00:00
|
|
|
|
|
|
|
import { translate } from '../../base/i18n';
|
|
|
|
|
2017-09-29 20:27:23 +00:00
|
|
|
import { TOOLTIP_TO_POPUP_POSITION } from '../constants';
|
2017-07-31 08:02:41 +00:00
|
|
|
import StatelessToolbarButton from './StatelessToolbarButton';
|
2017-02-16 23:02:40 +00:00
|
|
|
|
|
|
|
declare var APP: Object;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Represents a button in Toolbar on React.
|
|
|
|
*
|
|
|
|
* @class ToolbarButton
|
|
|
|
* @extends AbstractToolbarButton
|
|
|
|
*/
|
2017-10-24 22:26:56 +00:00
|
|
|
class ToolbarButton extends Component<*> {
|
2017-07-31 08:02:41 +00:00
|
|
|
button: Object;
|
2017-02-16 23:02:40 +00:00
|
|
|
|
2017-08-15 22:39:42 +00:00
|
|
|
_onClick: Function;
|
|
|
|
|
2017-02-16 23:02:40 +00:00
|
|
|
/**
|
|
|
|
* Toolbar button component's property types.
|
|
|
|
*
|
|
|
|
* @static
|
|
|
|
*/
|
|
|
|
static propTypes = {
|
2017-07-31 08:02:41 +00:00
|
|
|
...StatelessToolbarButton.propTypes,
|
2017-02-16 23:02:40 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Object describing button.
|
|
|
|
*/
|
2017-09-27 21:23:31 +00:00
|
|
|
button: PropTypes.object.isRequired,
|
2017-02-16 23:02:40 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Handler for component mount.
|
|
|
|
*/
|
2017-09-27 21:23:31 +00:00
|
|
|
onMount: PropTypes.func,
|
2017-02-16 23:02:40 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Handler for component unmount.
|
|
|
|
*/
|
2017-09-27 21:23:31 +00:00
|
|
|
onUnmount: PropTypes.func,
|
2017-02-16 23:02:40 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Translation helper function.
|
|
|
|
*/
|
2017-09-27 21:23:31 +00:00
|
|
|
t: PropTypes.func,
|
2017-04-06 22:40:10 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Indicates the position of the tooltip.
|
|
|
|
*/
|
2017-09-27 21:23:31 +00:00
|
|
|
tooltipPosition: PropTypes.oneOf([ 'bottom', 'left', 'right', 'top' ])
|
2017-02-16 23:02:40 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Initializes new ToolbarButton instance.
|
|
|
|
*
|
|
|
|
* @param {Object} props - The read-only properties with which the new
|
|
|
|
* instance is to be initialized.
|
|
|
|
*/
|
|
|
|
constructor(props: Object) {
|
|
|
|
super(props);
|
|
|
|
|
|
|
|
// Bind methods to save the context
|
2017-08-15 22:39:42 +00:00
|
|
|
this._onClick = this._onClick.bind(this);
|
2017-02-16 23:02:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets shortcut/tooltip
|
|
|
|
* after mounting of the component.
|
|
|
|
*
|
|
|
|
* @inheritdoc
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
|
|
|
componentDidMount(): void {
|
2017-08-15 22:39:42 +00:00
|
|
|
this._setShortcut();
|
2017-02-16 23:02:40 +00:00
|
|
|
|
|
|
|
if (this.props.onMount) {
|
|
|
|
this.props.onMount();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Invokes on unmount handler if it was passed to the props.
|
|
|
|
*
|
|
|
|
* @inheritdoc
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
|
|
|
componentWillUnmount(): void {
|
|
|
|
if (this.props.onUnmount) {
|
|
|
|
this.props.onUnmount();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Implements React's {@link Component#render()}.
|
|
|
|
*
|
|
|
|
* @inheritdoc
|
|
|
|
* @returns {ReactElement}
|
|
|
|
*/
|
2017-10-24 22:26:56 +00:00
|
|
|
render(): React$Element<*> {
|
2017-08-15 22:39:42 +00:00
|
|
|
const { button, t, tooltipPosition } = this.props;
|
2017-07-31 08:02:41 +00:00
|
|
|
const props = {
|
|
|
|
...this.props,
|
2017-09-22 22:02:34 +00:00
|
|
|
onClick: this._onClick
|
2017-07-31 08:02:41 +00:00
|
|
|
};
|
|
|
|
|
2017-08-15 23:52:42 +00:00
|
|
|
const buttonComponent = ( // eslint-disable-line no-extra-parens
|
2017-08-15 22:39:42 +00:00
|
|
|
<Tooltip
|
|
|
|
description = { button.tooltipText || t(button.tooltipKey) }
|
2017-10-06 16:14:45 +00:00
|
|
|
position = { tooltipPosition }>
|
2017-09-22 22:02:34 +00:00
|
|
|
<StatelessToolbarButton { ...props }>
|
|
|
|
{ this.props.children }
|
|
|
|
</StatelessToolbarButton>
|
2017-08-15 22:39:42 +00:00
|
|
|
</Tooltip>
|
2017-02-16 23:02:40 +00:00
|
|
|
);
|
2017-08-29 23:38:13 +00:00
|
|
|
let children = buttonComponent;
|
2017-08-15 23:52:42 +00:00
|
|
|
|
|
|
|
const popupConfig = this._getPopupDisplayConfiguration();
|
|
|
|
|
|
|
|
if (popupConfig) {
|
|
|
|
const { dataAttr, dataInterpolate, position } = popupConfig;
|
|
|
|
|
2017-08-29 23:38:13 +00:00
|
|
|
children = ( // eslint-disable-line no-extra-parens
|
2017-10-06 16:14:45 +00:00
|
|
|
<InlineDialog
|
2017-10-24 19:24:15 +00:00
|
|
|
content = {
|
|
|
|
<div className = 'button-popover-message'>
|
|
|
|
{ t(dataAttr, dataInterpolate) }
|
|
|
|
</div>
|
|
|
|
}
|
2017-08-15 23:52:42 +00:00
|
|
|
isOpen = { Boolean(popupConfig) }
|
|
|
|
position = { position }>
|
|
|
|
{ buttonComponent }
|
2017-10-06 16:14:45 +00:00
|
|
|
</InlineDialog>
|
2017-08-15 23:52:42 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2017-12-26 20:28:32 +00:00
|
|
|
return (
|
|
|
|
<div className = { `toolbar-button-wrapper ${button.id}-wrapper` }>
|
|
|
|
{ children }
|
|
|
|
</div>
|
|
|
|
);
|
2017-02-16 23:02:40 +00:00
|
|
|
}
|
|
|
|
|
2017-08-15 22:39:42 +00:00
|
|
|
/**
|
|
|
|
* Wrapper on on click handler props for current button.
|
|
|
|
*
|
|
|
|
* @param {Event} event - Click event object.
|
|
|
|
* @returns {void}
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
_onClick(event) {
|
|
|
|
this.props.onClick(event);
|
|
|
|
}
|
|
|
|
|
2017-02-16 23:02:40 +00:00
|
|
|
/**
|
2017-08-15 23:52:42 +00:00
|
|
|
* Parses the props and state to find any popup that should be displayed
|
|
|
|
* and returns an object describing how the popup should display.
|
2017-02-16 23:02:40 +00:00
|
|
|
*
|
|
|
|
* @private
|
2017-08-15 23:52:42 +00:00
|
|
|
* @returns {Object|null}
|
2017-02-16 23:02:40 +00:00
|
|
|
*/
|
2017-08-15 23:52:42 +00:00
|
|
|
_getPopupDisplayConfiguration() {
|
|
|
|
const { button, tooltipPosition } = this.props;
|
|
|
|
const { popups, popupDisplay } = button;
|
|
|
|
|
|
|
|
if (!popups || !popupDisplay) {
|
|
|
|
return null;
|
2017-02-16 23:02:40 +00:00
|
|
|
}
|
|
|
|
|
2017-08-15 23:52:42 +00:00
|
|
|
const { popupID } = popupDisplay;
|
|
|
|
const currentPopup = popups.find(popup => popup.id === popupID);
|
|
|
|
|
|
|
|
return Object.assign(
|
|
|
|
{},
|
|
|
|
currentPopup || {},
|
|
|
|
{
|
|
|
|
position: TOOLTIP_TO_POPUP_POSITION[tooltipPosition]
|
|
|
|
});
|
2017-02-16 23:02:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets shortcut and tooltip for current toolbar button.
|
|
|
|
*
|
|
|
|
* @private
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
2017-08-15 22:39:42 +00:00
|
|
|
_setShortcut(): void {
|
|
|
|
const { button } = this.props;
|
2017-07-26 21:21:52 +00:00
|
|
|
|
|
|
|
if (button.shortcut && APP && APP.keyboardshortcut) {
|
|
|
|
APP.keyboardshortcut.registerShortcut(
|
|
|
|
button.shortcut,
|
|
|
|
button.shortcutAttr,
|
|
|
|
button.shortcutFunc,
|
|
|
|
button.shortcutDescription
|
|
|
|
);
|
|
|
|
}
|
2017-02-16 23:02:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-26 20:47:53 +00:00
|
|
|
export default translate(ToolbarButton);
|