UNPKG

@atlaskit/editor-plugin-editor-disabled

Version:

Editor disabled plugin for @atlaskit/editor-core

133 lines (131 loc) 3.9 kB
import rafSchedule from 'raf-schd'; import { SafePlugin } from '@atlaskit/editor-common/safe-plugin'; import { pluginFactory } from '@atlaskit/editor-common/utils'; import { PluginKey } from '@atlaskit/editor-prosemirror/state'; import { ACTION, reducer } from './pm-plugins/reducer'; export const pluginKey = new PluginKey('editorDisabledPlugin'); const { getPluginState } = pluginFactory(pluginKey, reducer); /* Stores the state of the editor enabled/disabled for panel and floating toolbar to subscribe to through useSharedPluginState. Otherwise the NodeViews won't re-render when it changes. */ function createPlugin(dispatch, options) { const scheduleEditorDisabledUpdate = rafSchedule(view => { if (getPluginState(view.state).editorDisabled !== !view.editable) { const disabledMeta = { editorDisabled: !view.editable, disabledByPlugin: getPluginState(view.state).disabledByPlugin }; const tr = view.state.tr.setMeta(pluginKey, disabledMeta).setMeta('editorDisabledPlugin', disabledMeta); tr.setMeta('isLocal', true); view.dispatch(tr); } }); return new SafePlugin({ key: pluginKey, state: { init: () => { var _options$initialDisab; return { editorDisabled: (_options$initialDisab = options === null || options === void 0 ? void 0 : options.initialDisabledState) !== null && _options$initialDisab !== void 0 ? _options$initialDisab : false, disabledByPlugin: false }; }, apply: (tr, pluginState) => { const meta = tr.getMeta(pluginKey); if (meta) { if ('action' in meta) { return reducer(pluginState, meta); } return pluginState.editorDisabled !== meta.editorDisabled ? { ...pluginState, ...meta } : pluginState; } return pluginState; } }, props: { // If we set to undefined it respects the previous value. // Prosemirror doesn't have this typed correctly for this type of behaviour // @ts-expect-error editable: state => { var _pluginKey$getState; const { disabledByPlugin } = (_pluginKey$getState = pluginKey.getState(state)) !== null && _pluginKey$getState !== void 0 ? _pluginKey$getState : { disabledByPlugin: false }; return disabledByPlugin ? false : undefined; } }, view: view => { // schedule on mount scheduleEditorDisabledUpdate(view); return { update(view) { scheduleEditorDisabledUpdate(view); }, destroy() { scheduleEditorDisabledUpdate.cancel(); } }; } }); } /** * Editor disabled plugin to be added to an `EditorPresetBuilder` and used with `ComposableEditor` * from `@atlaskit/editor-core`. * * @param options - Plugin configuration options * @returns EditorDisabledPlugin * * @example * ```typescript * // Basic usage * .add(editorDisabledPlugin) * * // With initial disabled state * .add(editorDisabledPlugin, { initialDisabledState: true }) * ``` */ export const editorDisabledPlugin = ({ config: options = {} }) => ({ name: 'editorDisabled', getSharedState(editorState) { if (!editorState) { return { editorDisabled: false }; } const pluginState = pluginKey.getState(editorState); if (!pluginState) { return { editorDisabled: false }; } return { editorDisabled: pluginState.disabledByPlugin || pluginState.editorDisabled }; }, pmPlugins: () => [{ name: 'editorDisabled', plugin: ({ dispatch }) => createPlugin(dispatch, options) }], commands: { toggleDisabled: disabled => ({ tr }) => { return tr.setMeta(pluginKey, { action: ACTION.TOGGLE_DISABLED, disabled }); } } });