import { Extension } from "@tiptap/core"; import type { Node as ProseMirrorNode } from "@tiptap/pm/model"; import { type EditorView } from "@tiptap/pm/view"; /** * Default editor-wrapper CSS selector the drag handle scopes itself to. * * The handle, the drop indicator, and the `position: relative` anchor are all * appended to / measured against the closest ancestor matching this selector. * Content's editor wraps its ProseMirror DOM in a `.visual-editor-wrapper` * element, so that is the historical default. Other apps (e.g. the plan editor) * pass their own wrapper selector via {@link DragHandleOptions.wrapperSelector}. */ export declare const DEFAULT_DRAG_HANDLE_WRAPPER_SELECTOR = ".visual-editor-wrapper"; export interface DragHandleOptions { /** * CSS selector for the editor wrapper element the handle is anchored to. * * Must match an ancestor of the ProseMirror editor DOM. The wrapper gets * `position: relative` so the absolutely-positioned grip and drop indicator * can be placed relative to it. Defaults to * {@link DEFAULT_DRAG_HANDLE_WRAPPER_SELECTOR} so Content keeps working * unchanged. */ wrapperSelector: string; /** * Optional source-side payload for a cross-editor block move. The editor doc * carries ProseMirror node content, but app-owned side-map data (for example a * plan `diagram` block's HTML/CSS) can live outside the doc; this lets the * host carry that data to the receiving editor before the node is inserted. */ getDragTransferData?: (context: { view: EditorView; node: ProseMirrorNode; pos: number; }) => unknown; /** * Optional target-side receiver for cross-editor transfer data. Called before * the node is inserted into the target editor so the target's serializer can * resolve app-owned data during the synchronous ProseMirror update. */ receiveDragTransferData?: (data: unknown, context: { view: EditorView; node: ProseMirrorNode; pos: number; sourceView: EditorView; }) => void; /** * Optional host-level drop handler for document-specific structure changes. * Returning true tells the shared drag handle that the host fully handled the * move and no ProseMirror insert/delete should run. This is used for * Notion-style side drops where dropping a block to the left/right creates or * inserts into a column layout rather than inserting into the target editor. */ handleDrop?: (data: unknown, context: DragHandleDropContext) => boolean; } export type DragHandleDropPlacement = "before" | "after" | "left" | "right"; export type DragHandleDropContext = { view: EditorView; sourceView: EditorView; sourceNode: ProseMirrorNode; sourcePos: number; sourceNodeSize: number; targetNode: ProseMirrorNode; targetPos: number; targetNodeSize: number; insertPos: number; placement: DragHandleDropPlacement; }; export declare const dragPreviewTransform: ({ clientX, clientY, pointerOffsetX, pointerOffsetY, }: { clientX: number; clientY: number; pointerOffsetX: number; pointerOffsetY: number; }) => string; /** * App-agnostic Tiptap extension providing a Notion-style left-margin drag grip * (the `::` handle), block selection, and drag-to-reorder over top-level block * nodes. * * Behavior: * - On hover over any top-level block, a `.drag-handle` grip appears in the left * margin (forgiving hit zone extends {@link HOVER_SIDE_OUTSET_REM}rem to the * sides and into the gap above/between blocks). * - Single-clicking the grip selects the block and opens a block action menu. * Dragging past a small threshold starts a reorder, showing a floating clone * preview (`.notion-drag-preview`) and a `.notion-drop-indicator` line. * `Escape` cancels. * - While dragging, the source block carries `.notion-block--dragging` and the * document element carries `.notion-editor-is-dragging` so apps can style the * in-flight state. Apps own all of these CSS class names. * - Works for ANY top-level node ProseMirror renders as a direct child of the * editor — including `group: "block"`, `draggable: true` atoms such as the * plan editor's `planBlock`. * * The only app-specific coupling — the editor wrapper element the handle and * drop indicator are anchored to — is configurable via * {@link DragHandleOptions.wrapperSelector}, defaulting to * {@link DEFAULT_DRAG_HANDLE_WRAPPER_SELECTOR} (`.visual-editor-wrapper`) so the * Content editor keeps working byte-identically. The plan editor passes its own * wrapper selector via `DragHandle.configure({ wrapperSelector })`. */ export declare const DragHandle: Extension; //# sourceMappingURL=DragHandle.d.ts.map