UNPKG

@atlaskit/editor-plugin-block-controls

Version:

Block controls plugin for @atlaskit/editor-core

105 lines (103 loc) 4.07 kB
import { createElement } from 'react'; // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead import uuid from 'uuid'; import { Decoration } from '@atlaskit/editor-prosemirror/view'; import { fg } from '@atlaskit/platform-feature-flags'; import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals'; import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments'; import { QuickInsertWithVisibility } from '../ui/quick-insert-button'; import { getActiveBlockMarks } from './utils/marks'; import { createVanillaButton } from './vanilla-quick-insert'; const TYPE_QUICK_INSERT = 'INSERT_BUTTON'; export const findQuickInsertInsertButtonDecoration = (decorations, from, to) => { return decorations.find(from, to, spec => spec.type === TYPE_QUICK_INSERT); }; export const quickInsertButtonDecoration = ({ api, formatMessage, rootPos, anchorName, nodeType, nodeViewPortalProviderAPI, rootAnchorName, rootNodeType, anchorRectCache, editorState }) => { // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead const key = uuid(); const cleanupCallbacks = []; const widgetSpec = editorExperiment('platform_editor_breakout_resizing', true) ? { side: -2, type: TYPE_QUICK_INSERT, /** * sigh - `marks` influences the position that the widget is drawn (as described on the `side` property). * Exclude 'breakout' on purpose, so the widgets render at the top of the document to avoid z-index issues * Other block marks must be added, otherwise PM will split the DOM elements causing mutations and re-draws */ marks: expValEquals('platform_editor_clean_up_widget_mark_logic', 'isEnabled', true) ? [] : getActiveBlockMarks(editorState, rootPos), destroy: _ => { if (fg('platform_editor_fix_widget_destroy')) { nodeViewPortalProviderAPI.remove(key); } cleanupCallbacks.forEach(cb => { cb(); }); } } : { side: -2, type: TYPE_QUICK_INSERT, destroy: _ => { if (fg('platform_editor_fix_widget_destroy')) { nodeViewPortalProviderAPI.remove(key); } cleanupCallbacks.forEach(cb => { cb(); }); } }; return Decoration.widget(rootPos, (view, getPos) => { const element = document.createElement('span'); // inline decoration causes cursor disappear when focusing editor at the first line (e.g. press Tab when title is focused) element.style.display = 'block'; // make sure it does not interfere with elements floating next to each other e.g. paragraph next to image with wrap-right element.style.clear = 'unset'; element.contentEditable = 'false'; element.setAttribute('data-blocks-quick-insert-container', 'true'); if (fg('confluence_remix_button_right_side_block_fg')) { element.setAttribute('data-blocks-quick-insert-button', 'true'); } element.setAttribute('data-testid', 'block-ctrl-quick-insert-button'); if (editorExperiment('platform_editor_block_control_optimise_render', true, { exposure: true })) { const vanillaElement = createVanillaButton({ formatMessage, api, view, getPos, cleanupCallbacks, rootAnchorName: rootAnchorName !== null && rootAnchorName !== void 0 ? rootAnchorName : nodeType, anchorName, rootNodeType: rootNodeType !== null && rootNodeType !== void 0 ? rootNodeType : nodeType, anchorRectCache }); element.appendChild(vanillaElement); return element; } nodeViewPortalProviderAPI.render(() => /*#__PURE__*/createElement(QuickInsertWithVisibility, { api, getPos, formatMessage, view, nodeType, anchorName, rootAnchorName, rootNodeType: rootNodeType !== null && rootNodeType !== void 0 ? rootNodeType : nodeType, anchorRectCache }), element, key, undefined, // @portal-render-immediately true); return element; }, widgetSpec); };