@atlaskit/editor-core
Version:
A package contains Atlassian editor core functionality
141 lines • 5.94 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var React = require("react");
var ReactDOM = require("react-dom");
var react_1 = require("react");
var analytics_1 = require("../../analytics");
var emoji_1 = require("@atlaskit/icon/glyph/editor/emoji");
var emoji_2 = require("@atlaskit/emoji");
var layer_1 = require("@atlaskit/layer");
var ToolbarButton_1 = require("../ToolbarButton");
/**
* Checks if an element is detached (i.e. not in the current document)
*/
var isDetachedElement = function (el) { return !document.contains(el); };
var ToolbarEmojiPicker = (function (_super) {
tslib_1.__extends(ToolbarEmojiPicker, _super);
function ToolbarEmojiPicker() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.state = {
isOpen: false,
};
_this.handlePluginStateChange = function (pluginState) {
_this.setState({
disabled: !pluginState.enabled
});
};
_this.handleButtonRef = function (ref) {
if (ref) {
_this.buttonRef = ref;
}
else {
_this.buttonRef = null;
}
};
_this.onPickerRef = function (ref) {
if (ref) {
document.addEventListener('click', _this.handleClickOutside);
}
else {
document.removeEventListener('click', _this.handleClickOutside);
}
_this.pickerRef = ref;
};
_this.close = function () {
_this.setState({
isOpen: false,
});
};
_this.toggleOpen = function () {
var isOpen = _this.state.isOpen;
_this.setState({
isOpen: !isOpen,
});
};
_this.handleClickOutside = function (e) {
var picker = ReactDOM.findDOMNode(_this.pickerRef);
// Ignore click events for detached elements.
// Workaround for FS-1322 - where two onClicks fire - one when the upload button is
// still in the document, and one once it's detached. Does not always occur, and
// may be a side effect of a react render optimisation
if (!picker || (!isDetachedElement(e.target) && !picker.contains(e.target))) {
_this.close();
}
};
_this.getOffsetX = function (buttonRect) {
return -(emoji_2.emojiPickerWidth - _this.props.numFollowingButtons * buttonRect.width);
};
_this.handleSelectedEmoji = function (emojiId, emoji) {
if (_this.state.isOpen && _this.pluginState) {
_this.pluginState.insertEmoji(emojiId);
_this.close();
return true;
}
return false;
};
return _this;
}
ToolbarEmojiPicker.prototype.componentWillMount = function () {
this.setPluginState(this.props);
};
ToolbarEmojiPicker.prototype.componentDidMount = function () {
this.state.button = ReactDOM.findDOMNode(this.buttonRef);
if (this.pluginState) {
this.pluginState.subscribe(this.handlePluginStateChange);
}
};
ToolbarEmojiPicker.prototype.componentDidUpdate = function () {
var button = this.state.button;
if (!button || !button.getBoundingClientRect().width) {
this.state.button = ReactDOM.findDOMNode(this.buttonRef);
}
};
ToolbarEmojiPicker.prototype.componentWillUnmount = function () {
if (this.pluginState) {
this.pluginState.unsubscribe(this.handlePluginStateChange);
}
};
ToolbarEmojiPicker.prototype.setPluginState = function (props) {
var editorView = props.editorView, pluginKey = props.pluginKey;
if (!editorView) {
return;
}
var pluginState = pluginKey.getState(editorView.state);
if (pluginState) {
this.pluginState = pluginState;
pluginState.subscribe(this.handlePluginStateChange);
}
};
ToolbarEmojiPicker.prototype.renderPopup = function () {
var _a = this.state, disabled = _a.disabled, isOpen = _a.isOpen;
if (disabled || !isOpen) {
return null;
}
return (React.createElement("div", null,
React.createElement(emoji_2.EmojiPicker, { emojiProvider: this.props.emojiProvider, onSelection: this.handleSelectedEmoji, onPickerRef: this.onPickerRef })));
};
ToolbarEmojiPicker.prototype.render = function () {
var _a = this.state, isOpen = _a.isOpen, disabled = _a.disabled, button = _a.button;
var toolbarButton = (React.createElement(ToolbarButton_1.default, { selected: isOpen, disabled: disabled, onClick: this.toggleOpen, iconBefore: React.createElement(emoji_1.default, { label: "Insert emoji (:)" }), ref: this.handleButtonRef, title: "Insert emoji (:)" }));
if (!button) {
return toolbarButton;
}
return (React.createElement("div", null, this.renderTrigger(this.renderPopup(), toolbarButton)));
};
ToolbarEmojiPicker.prototype.renderTrigger = function (content, trigger) {
var button = this.state.button;
// Check already occurs in render() but needed for typescript
if (!button) {
return null;
}
var offset = this.getOffsetX(button.getBoundingClientRect()) + " 0";
return (React.createElement(layer_1.default, { content: content, position: "top left", offset: offset }, trigger));
};
return ToolbarEmojiPicker;
}(react_1.PureComponent));
tslib_1.__decorate([
analytics_1.analyticsDecorator('atlassian.editor.emoji.button')
], ToolbarEmojiPicker.prototype, "handleSelectedEmoji", void 0);
exports.default = ToolbarEmojiPicker;
//# sourceMappingURL=index.js.map