UNPKG

edix

Version:

An experimental, type-safe, framework agnostic and small (5kB+) contenteditable state manager.

107 lines (106 loc) 3.39 kB
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 {};