import { type ImageOptions } from "@tiptap/extension-image";
import type { EditorView } from "@tiptap/pm/view";
/**
* The injectable async upload contract for the shared image block.
*
* An app provides this to turn a picked / pasted / dropped {@link File} into a
* hosted image. It returns the final `src` (a hosted URL) plus an optional
* `alt`. Plans wire it to the framework `upload-image` action; Content keeps its
* own richer image block and does not use this contract.
*
* When NO upload function is supplied, the shared block still renders images and
* round-trips `` markdown — it just cannot ingest local files (paste
* of an image URL / markdown still works via the base node's input rules).
*/
export type ImageUploadFn = (file: File) => Promise<{
src: string;
alt?: string;
}>;
export interface SharedImageOptions extends ImageOptions {
/**
* App-injected uploader. When present, the shared block accepts pasted /
* dropped image files and the `/image` slash command, uploading each file
* through this function and patching the node's `src` on resolve.
*/
onImageUpload?: ImageUploadFn | null;
}
/**
* The SHARED block-level image node. Built on `@tiptap/extension-image` (a
* node named `image`), so:
*
* - **GFM serialization** emits pure `` markdown via a block-aware
* `addStorage().markdown.serialize` (it calls `closeBlock` so a block image
* keeps its blank-line separator, byte-stable). It emits NO `
`
* HTML, so plans stay source-syncable under the GFM `html:false` contract.
* - **Paste / drop** of local image files is handled by a self-contained
* ProseMirror plugin that calls the injected {@link ImageUploadFn}. Pasting
* an image URL or `` markdown works through the base node's input
* rules even when no uploader is supplied.
*
* The node adds one transient `uploadId` attribute (never parsed/rendered to
* HTML, never serialized to markdown) used to track an in-flight upload.
*
* Content keeps its own richer `ImageNode` (Assets picker, AI alt-text, resize,
* NFM `{color}` serialization) and does NOT use this shared node — both nodes
* are named `image` but never coexist in the same editor because Content leaves
* `features.image` off and injects its own via `extraExtensions`.
*/
export declare const SharedImage: import("@tiptap/core").Node;
/**
* Build the shared image extension, optionally wired with an app uploader.
*
* @example
* createImageExtension({ onImageUpload: uploadEditorImage })
*/
export declare function createImageExtension(options?: {
onImageUpload?: ImageUploadFn | null;
}): import("@tiptap/core").Node;
/**
* Open a native file picker, then upload + insert the chosen image(s) through
* the same flow as paste/drop. Used by the `/image` slash command.
*/
export declare function pickAndInsertImage(view: EditorView, upload: ImageUploadFn): void;
//# sourceMappingURL=ImageExtension.d.ts.map