UNPKG

@atlaskit/editor-plugin-panel

Version:

Panel plugin for @atlaskit/editor-core.

144 lines (139 loc) 6.57 kB
import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import React from 'react'; // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead import uuid from 'uuid/v4'; import { PanelType } from '@atlaskit/adf-schema'; import { Emoji } from '@atlaskit/editor-common/emoji'; import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks'; import { PanelErrorIcon, PanelInfoIcon, PanelNoteIcon, PanelSuccessIcon, PanelWarningIcon } from '@atlaskit/editor-common/icons'; import { PanelSharedCssClassName } from '@atlaskit/editor-common/panel'; import { DOMSerializer } from '@atlaskit/editor-prosemirror/model'; import { akEditorCustomIconSize } from '@atlaskit/editor-shared-styles/consts'; import LightbulbIcon from '@atlaskit/icon/core/lightbulb'; import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals'; import { panelAttrsToDom } from '../pm-plugins/utils/utils'; import { renderPanelIcon } from '../ui/renderPanelIcon'; /* eslint-disable @atlaskit/editor/no-re-export */ // Mapping export export var panelIcons = { info: PanelInfoIcon, success: PanelSuccessIcon, note: PanelNoteIcon, tip: LightbulbIcon, warning: PanelWarningIcon, error: PanelErrorIcon, custom: PanelInfoIcon }; /* eslint-enable @atlaskit/editor/no-re-export */ var selector = function selector(states) { return { emojiState: states.emojiState }; }; export var PanelIcon = function PanelIcon(props) { var allowCustomPanel = props.allowCustomPanel, providerFactory = props.providerFactory, pluginInjectionApi = props.pluginInjectionApi, _props$panelAttribute = props.panelAttributes, panelType = _props$panelAttribute.panelType, panelIcon = _props$panelAttribute.panelIcon, panelIconId = _props$panelAttribute.panelIconId, panelIconText = _props$panelAttribute.panelIconText; var _useSharedPluginState = useSharedPluginStateWithSelector(pluginInjectionApi, ['emoji'], selector), emojiState = _useSharedPluginState.emojiState; var emojiProvider = emojiState === null || emojiState === void 0 ? void 0 : emojiState.emojiProvider; if (allowCustomPanel && panelIcon && panelType === PanelType.CUSTOM) { return /*#__PURE__*/React.createElement(Emoji, { emojiProvider: emojiProvider, providers: providerFactory, shortName: panelIcon, id: panelIconId, fallback: panelIconText, showTooltip: false, allowTextFallback: false, fitToHeight: akEditorCustomIconSize }); } var Icon = panelIcons[panelType]; return Icon ? /*#__PURE__*/React.createElement(Icon, { label: "".concat(panelType, " panel") }) : null; }; var PanelNodeView = /*#__PURE__*/function () { function PanelNodeView(node, view, getPos, pluginOptions, api, nodeViewPortalProviderAPI, providerFactory) { var _this = this; _classCallCheck(this, PanelNodeView); this.nodeViewPortalProviderAPI = nodeViewPortalProviderAPI; this.providerFactory = providerFactory; this.pluginOptions = pluginOptions; this.view = view; this.node = node; // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead this.key = uuid(); var _DOMSerializer$render = DOMSerializer.renderSpec(document, panelAttrsToDom(node.attrs, pluginOptions.allowCustomPanel || false)), dom = _DOMSerializer$render.dom, contentDOM = _DOMSerializer$render.contentDOM; this.getPos = getPos; // Ignored via go/ees005 // eslint-disable-next-line @atlaskit/editor/no-as-casting this.dom = dom; // Ignored via go/ees005 // eslint-disable-next-line @atlaskit/editor/no-as-casting this.contentDOM = contentDOM; // Ignored via go/ees005 // eslint-disable-next-line @atlaskit/editor/no-as-casting this.icon = this.dom.querySelector(".".concat(PanelSharedCssClassName.icon)); if (!this.icon) { return; } // set contentEditable as false to be able to select the custom panels with keyboard this.icon.contentEditable = 'false'; var panelAttrs = node.attrs; // Determine if this is a standard panel type (info, note, success, warning, error) var isStandardPanel = panelAttrs.panelType && [PanelType.INFO, PanelType.NOTE, PanelType.SUCCESS, PanelType.WARNING, PanelType.ERROR].includes(panelAttrs.panelType); // For standard panels (info, note, success, warning, error), render icon directly as native DOM // This avoids Portal rendering delays that cause flickering on SSR and page transitions if (isStandardPanel && expValEquals('platform_editor_vc90_transition_panel_icon', 'isEnabled', true)) { renderPanelIcon(panelAttrs.panelType, this.icon); } else { this.nodeViewPortalProviderAPI.render(function () { return /*#__PURE__*/React.createElement(PanelIcon, { pluginInjectionApi: api, allowCustomPanel: pluginOptions.allowCustomPanel, panelAttributes: panelAttrs, providerFactory: _this.providerFactory }); }, this.icon, this.key); } } return _createClass(PanelNodeView, [{ key: "ignoreMutation", value: function ignoreMutation(mutation) { // ignore mutation if it caused by the icon. if (!this.icon) { return false; } var isIcon = mutation.target === this.icon || mutation.target.parentNode === this.icon; // ignore mutation if it caused by the lazy load emoji inside icon. var isInsideIcon = this.icon.contains(mutation.target); return isIcon || isInsideIcon; } }, { key: "destroy", value: function destroy() { var panelAttrs = this.node.attrs; // Determine if this is a standard panel type (info, note, success, warning, error) var isStandardPanel = panelAttrs.panelType && [PanelType.INFO, PanelType.NOTE, PanelType.SUCCESS, PanelType.WARNING, PanelType.ERROR].includes(panelAttrs.panelType); // Only remove Portal if it was used (for custom emoji panels) if (!(isStandardPanel && expValEquals('platform_editor_vc90_transition_panel_icon', 'isEnabled', true))) { this.nodeViewPortalProviderAPI.remove(this.key); } } }]); }(); export var getPanelNodeView = function getPanelNodeView(pluginOptions, api, nodeViewPortalProviderAPI, providerFactory) { return function (node, view, getPos) { return new PanelNodeView(node, view, getPos, pluginOptions, api, nodeViewPortalProviderAPI, providerFactory); }; };