UNPKG

@atlaskit/editor-core

Version:

A package contains Atlassian editor core functionality

141 lines • 5.94 kB
"use strict"; 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