UNPKG

@atlaskit/editor-plugin-base

Version:

Base plugin for @atlaskit/editor-core

87 lines (86 loc) 3.32 kB
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin'; import FeatureGates from '@atlaskit/feature-gate-js-client'; import { scrollGutterPluginKey } from './plugin-key'; const GUTTER_SIZE_IN_PX = 120; const GUTTER_SELECTOR_NAME = 'editor-scroll-gutter'; const GUTTER_ATTR = 'data-editor-scroll-gutter'; /** * Create a gutter element that can be added or removed from the DOM. */ function createGutter(gutterSize, parent) { if (FeatureGates.getExperimentValue('cc_snippets_dogfooding_beta', 'isEnabled', false)) { if (!parent) { return () => {}; } const existing = parent.querySelector(`[${GUTTER_ATTR}]`); if (existing instanceof HTMLElement) { return () => parent.removeChild(existing); } const gutter = document.createElement('div'); gutter.style.paddingBottom = `${gutterSize}px`; gutter.setAttribute('data-vc', 'scroll-gutter'); gutter.setAttribute(GUTTER_ATTR, 'true'); parent.appendChild(gutter); return () => parent.removeChild(gutter); } const gutterRef = document.getElementById(GUTTER_SELECTOR_NAME); if (gutterRef) { return () => parent === null || parent === void 0 ? void 0 : parent.removeChild(gutterRef); } const gutter = document.createElement('div'); gutter.style.paddingBottom = `${gutterSize}px`; gutter.setAttribute('data-vc', 'scroll-gutter'); gutter.id = GUTTER_SELECTOR_NAME; if (parent) { parent.appendChild(gutter); } return () => parent === null || parent === void 0 ? void 0 : parent.removeChild(gutter); } // eslint-disable-next-line @typescript-eslint/no-empty-object-type export default ((pluginOptions = {}) => { const { getScrollElement, gutterSize = GUTTER_SIZE_IN_PX } = pluginOptions; if (!getScrollElement) { return undefined; } return new SafePlugin({ key: scrollGutterPluginKey, state: { init: () => ({}), apply: (tr, pluginState) => { if (tr.getMeta(scrollGutterPluginKey)) { return tr.getMeta(scrollGutterPluginKey); } return pluginState; } }, props: { // Determines the distance (in pixels) between the cursor and the end of the visible viewport at which point, // when scrolling the cursor into view, scrolling takes place. // Defaults to 0: https://prosemirror.net/docs/ref/#view.EditorProps.scrollThreshold scrollThreshold: gutterSize, // Determines the extra space (in pixels) that is left above or below the cursor when it is scrolled into view. // Defaults to 5: https://prosemirror.net/docs/ref/#view.EditorProps.scrollMargin scrollMargin: gutterSize }, view(view) { var _editorElement; // Store references to avoid lookups on successive checks. const scrollElement = getScrollElement(view); let editorElement = view.dom instanceof HTMLElement ? view.dom : null; let editorParentElement = (_editorElement = editorElement) === null || _editorElement === void 0 ? void 0 : _editorElement.parentElement; let cleanup = () => {}; if (editorParentElement && scrollElement) { cleanup = createGutter(gutterSize, editorParentElement); } return { destroy() { cleanup(); editorParentElement = editorElement = null; } }; } }); });