import type { StandardSchemaV1 } from "@standard-schema/spec";
import type { DocNode, SelectionSnapshot } from "./doc/types.js";
import type { EditorCommand } from "./commands.js";
import { Transaction, type Operation } from "./doc/edit.js";
import type { EditorPlugin } from "./plugins/types.js";
import { type CopyHook, type PasteHook, type KeyboardHook } from "./hooks/index.js";
/**
 * Options of {@link createEditor}.
 */
export interface EditorOptions<T extends DocNode, S extends StandardSchemaV1<T, T> | void = void> {
    /**
     * Optional [Standard Schema](https://github.com/standard-schema/standard-schema) to validate unsafe edits.
     */
    schema?: S;
    /**
     * Initial document.
     */
    doc: T;
    /**
     * The state editable or not.
     */
    readonly?: boolean;
    /**
     * Functions to handle keyboard events.
     *
     * Return `true` if you want to stop propagation.
     */
    keyboard?: KeyboardHook[];
    /**
     * Functions to handle copy events
     * @default [plainCopy()]
     */
    copy?: [CopyHook, ...rest: CopyHook[]];
    /**
     * Functions to handle paste / drop events
     * @default [plainPaste()]
     */
    paste?: [PasteHook, ...rest: PasteHook[]];
    /**
     * TODO
     */
    isBlock?: (node: HTMLElement) => boolean;
    /**
     * Callback invoked when document changes.
     */
    onChange: (doc: T) => void;
    /**
     * Callback invoked when errors happen.
     *
     * @default console.error
     */
    onError?: (message: string) => void;
}
type EditorEventMap = {
    change: () => void;
    selectionchange: () => void;
    readonly: () => void;
};
type EditorHookMap = {
    apply: (op: Operation, next: (op?: Operation) => void) => void;
    mount: (element: HTMLElement) => void | (() => void);
    keyboard: KeyboardHook;
};
/**
 * The editor instance.
 */
export interface Editor<T extends DocNode = DocNode> {
    readonly doc: T;
    readonly selection: SelectionSnapshot;
    /**
     * The getter/setter for the editor's read-only state.
     * `true` to read-only. `false` to editable.
     */
    readonly: boolean;
    /**
     * Dispatches editing operations.
     * @param tr {@link Transaction} or {@link EditorCommand}
     * @param args arguments of {@link EditorCommand}
     */
    apply(tr: Transaction): this;
    apply<A extends unknown[]>(fn: EditorCommand<A, T>, ...args: A): this;
    /**
     * A function to subscribe editor events.
     * @returns cleanup function
     */
    on<K extends keyof EditorEventMap>(key: K, callback: EditorEventMap[K]): () => void;
    /**
     * A function to register editor hooks.
     * @returns cleanup function
     */
    hook<K extends keyof EditorHookMap>(key: K, callback: EditorHookMap[K]): () => void;
    /**
     * A function to make DOM editable.
     * @returns A function to stop subscribing DOM changes and restores previous DOM state.
     */
    input: (element: HTMLElement) => () => void;
    /**
     * A function to use editor plugins.
     */
    use<A extends unknown[]>(fn: EditorPlugin<A, T>, ...args: A): this;
}
/**
 * A function to initialize {@link Editor}.
 */
export declare const createEditor: <T extends DocNode, S extends StandardSchemaV1<T, T> | void = void>({ doc, readonly, schema, keyboard, copy: copyHooks, paste: pasteHooks, isBlock, onChange, onError, }: EditorOptions<T, S>) => Editor<T>;
export {};
