@atlaskit/editor-plugin-base
Version:
Base plugin for @atlaskit/editor-core
87 lines (86 loc) • 3.32 kB
JavaScript
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;
}
};
}
});
});