UNPKG

@atlaskit/editor-core

Version:

A package contains Atlassian editor core functionality

139 lines 5.85 kB
import * as tslib_1 from "tslib"; import * as React from 'react'; import * as ReactDOM from 'react-dom'; import { PureComponent } from 'react'; import { analyticsDecorator as analytics } from '../../analytics'; import EmojiIcon from '@atlaskit/icon/glyph/editor/emoji'; import { EmojiPicker as AkEmojiPicker, emojiPickerWidth } from '@atlaskit/emoji'; import Layer from '@atlaskit/layer'; import ToolbarButton from '../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 -(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(AkEmojiPicker, { 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, { selected: isOpen, disabled: disabled, onClick: this.toggleOpen, iconBefore: React.createElement(EmojiIcon, { 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, { content: content, position: "top left", offset: offset }, trigger)); }; return ToolbarEmojiPicker; }(PureComponent)); export default ToolbarEmojiPicker; tslib_1.__decorate([ analytics('atlassian.editor.emoji.button') ], ToolbarEmojiPicker.prototype, "handleSelectedEmoji", void 0); //# sourceMappingURL=index.js.map