@atlaskit/editor-plugin-synced-block
Version:
SyncedBlock plugin for @atlaskit/editor-core
89 lines (88 loc) • 5 kB
TypeScript
import type { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
import type { ExtractInjectionAPI, PMPluginFactoryParams } from '@atlaskit/editor-common/types';
import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/state';
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
import type { SyncBlockStoreManager } from '@atlaskit/editor-synced-block-provider';
import type { DeletionMechanism } from '@atlaskit/editor-synced-block-provider/common/types';
import type { SyncedBlockFeedbackContext, SyncedBlockPlugin, SyncedBlockPluginOptions } from '../syncedBlockPluginType';
import type { ActiveFlag, BodiedSyncBlockDeletionStatus, RetryCreationPosMap } from '../types';
export declare const syncedBlockPluginKey: PluginKey;
/**
* Dedicated transaction-meta {@link PluginKey} the synced-block removal command
* sets so {@link getDeleteMechanism} can report a toolbar Delete as
* `deleteButton` (otherwise indistinguishable from a keyboard delete — both are
* plain ReplaceSteps). A separate key (rather than `syncedBlockPluginKey`, which
* carries plugin-state transitions read in `apply()`, or a bare string) keeps
* this transient signal uniquely namespaced and isolated.
*/
export declare const deleteMechanismMetaKey: PluginKey<DeletionMechanism>;
/**
* Creation-type signals set by {@link createSyncedBlock} on the creating
* transaction. The async creation handler forwards them to the store manager,
* which attaches them to the `syncedBlockCreate` event. A dedicated key keeps
* this transient signal isolated from plugin state.
*/
export type SyncedBlockCreationMeta = {
createdEmpty?: boolean;
inputMethod?: INPUT_METHOD;
};
export declare const creationMetaKey: PluginKey<SyncedBlockCreationMeta>;
type SyncedBlockPluginState = {
activeFlag: ActiveFlag;
bodiedSyncBlockDeletionStatus?: BodiedSyncBlockDeletionStatus;
/**
* Tracks whether the document currently contains any synced block (source or
* reference). When `false`, downstream work in `appendTransaction`,
* `decorations`, and the `contentComponent` short-circuits to avoid the
* per-transition feature tax on the ~99.97% of pages that have no synced
* blocks (see EDITOR-6586).
*/
hasSyncedBlocks: boolean;
hasUnsavedBodiedSyncBlockChanges?: boolean;
/**
* Cached previous values for shared-state signals. Used inside `apply()` to
* detect when a status change requires a full rebuild of `statusDecorationSet`
* instead of a cheap `map()` call.
*/
prevIsDragging: boolean;
prevIsOffline: boolean;
prevIsViewMode: boolean;
retryCreationPosMap: RetryCreationPosMap;
selectionDecorationSet: DecorationSet;
/**
* Cached decoration set for sync-block status decorations (offline overlay,
* view-mode class, creation-loading spinner, drag border). When the perf
* gate is ON this is computed in `apply()` and mapped through edits so the
* `decorations` prop becomes an O(1) lookup instead of a full
* `doc.descendants()` walk every transaction (see EDITOR-6930).
*/
statusDecorationSet: DecorationSet;
syncBlockStore: SyncBlockStoreManager;
};
/**
* Derive how a source bodiedSyncBlock removal was performed, for the `mechanism`
* analytics dimension. Each value names the user action; most-specific wins:
* - `undo` / `redo` — history transaction.
* - `deleteButton` — the explicit "Delete" control in the synced-block toolbar
* (the removal command tags its transaction with {@link deleteMechanismMetaKey}).
* - `selectionReplaced` — ReplaceStep on a node-selected block (the
* accidental-overwrite path: block selected, then typed/pasted over).
* - `keyboardDelete` — ReplaceStep removal at a caret/range selection
* (Backspace/Delete key).
* - `other` — anything else (unsync, conversion, code-dispatched, or a
* structural `ReplaceAroundStep` such as wrap/lift/unwrap).
*
* Only a plain `ReplaceStep` counts as a direct user deletion. `ReplaceAroundStep`
* is used for wrapping/lifting/unwrapping content, not direct removal, so a
* removal carried by one is classified as `other` rather than misreported as a
* keyboard delete.
*
* `state` is the pre-transaction state, so its selection reflects what was
* selected when the edit was made.
*/
export declare const getDeleteMechanism: (tr: Transaction, state: EditorState) => DeletionMechanism;
export declare const getPromptedFeedbackEntryPoint: (mechanism: DeletionMechanism) => SyncedBlockFeedbackContext['entryPoint'] | undefined;
export declare const createPlugin: (options: SyncedBlockPluginOptions | undefined, pmPluginFactoryParams: PMPluginFactoryParams, syncBlockStore: SyncBlockStoreManager, api?: ExtractInjectionAPI<SyncedBlockPlugin>) => SafePlugin<SyncedBlockPluginState>;
export {};