or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

core-editor-view.mdcustom-views.mddecoration-system.mdeditor-props.mdindex.mdinput-handling.mdposition-mapping.md
tile.json

tessl/npm-prosemirror-view

ProseMirror's view component that manages DOM structure and user interactions for rich text editing

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/prosemirror-view@1.40.x

To install, run

npx @tessl/cli install tessl/npm-prosemirror-view@1.40.0

index.mddocs/

ProseMirror View

ProseMirror's view component provides the DOM rendering and user interaction layer for rich text editors. It manages the DOM representation of documents, handles user input and events, and offers extensible APIs for custom node and mark rendering. The view bridges ProseMirror's abstract document model with the browser's contentEditable interface.

Package Information

  • Package Name: prosemirror-view
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install prosemirror-view

Core Imports

import { EditorView } from "prosemirror-view";

For decorations:

import { Decoration, DecorationSet } from "prosemirror-view";

For custom views:

import { NodeView, MarkView } from "prosemirror-view";

Basic Usage

import { EditorView } from "prosemirror-view";
import { EditorState } from "prosemirror-state";
import { Schema, DOMParser } from "prosemirror-model";
import { exampleSetup } from "prosemirror-example-setup";

// Create editor state
const schema = new Schema({
  nodes: {
    doc: { content: "paragraph+" },
    paragraph: { content: "text*", toDOM: () => ["p", 0] },
    text: {}
  }
});

const state = EditorState.create({
  schema,
  plugins: exampleSetup({ schema })
});

// Create editor view
const view = new EditorView(document.querySelector("#editor"), {
  state,
  dispatchTransaction(tr) {
    view.updateState(view.state.apply(tr));
  }
});

// Focus the editor
view.focus();

// Get position from coordinates
const pos = view.posAtCoords({ left: 100, top: 50 });
if (pos) {
  console.log("Document position:", pos.pos);
}

Architecture

ProseMirror View is built around several key components:

  • EditorView: Central class managing DOM structure and user interactions
  • Decoration System: Visual decorations for styling and annotations (widgets, inline, node)
  • Custom Views: Extensible NodeView and MarkView interfaces for custom rendering
  • Input Handling: Comprehensive event processing including keyboard, mouse, and composition
  • Coordinate Mapping: Bidirectional position conversion between document and DOM
  • DOM Observer: Change detection and state synchronization
  • Cross-browser Support: Unified behavior across different browsers and platforms

Capabilities

Core Editor View

The main EditorView class that manages the DOM structure representing an editable document and handles user interactions.

class EditorView {
  constructor(
    place: null | DOMNode | ((editor: HTMLElement) => void) | {mount: HTMLElement},
    props: DirectEditorProps
  );
  
  readonly state: EditorState;
  readonly dom: HTMLElement;
  readonly editable: boolean;
  readonly dragging: null | {slice: Slice, move: boolean};
  readonly composing: boolean;
  readonly props: DirectEditorProps;
  readonly root: Document | ShadowRoot;
  
  update(props: DirectEditorProps): void;
  setProps(props: Partial<DirectEditorProps>): void;
  updateState(state: EditorState): void;
  focus(): void;
  hasFocus(): boolean;
  destroy(): void;
  dispatch(tr: Transaction): void;
}

Core Editor View

Decoration System

Visual decorations that can be applied to document content for styling, annotations, and interactive elements.

class Decoration {
  readonly from: number;
  readonly to: number;
  readonly spec: any;
  
  static widget(pos: number, toDOM: WidgetConstructor, spec?: object): Decoration;
  static inline(from: number, to: number, attrs: DecorationAttrs, spec?: object): Decoration;
  static node(from: number, to: number, attrs: DecorationAttrs, spec?: object): Decoration;
}

class DecorationSet {
  static empty: DecorationSet;
  static create(doc: Node, decorations: readonly Decoration[]): DecorationSet;
  
  find(start?: number, end?: number, predicate?: (spec: any) => boolean): Decoration[];
  map(mapping: Mappable, doc: Node, options?: {onRemove?: (decorationSpec: any) => void}): DecorationSet;
  add(doc: Node, decorations: readonly Decoration[]): DecorationSet;
  remove(decorations: readonly Decoration[]): DecorationSet;
}

Decoration System

Custom Node and Mark Views

Extensible interfaces for custom rendering of document nodes and marks.

interface NodeView {
  dom: DOMNode;
  contentDOM?: HTMLElement | null;
  update?(node: Node, decorations: readonly Decoration[], innerDecorations: DecorationSource): boolean;
  selectNode?(): void;
  deselectNode?(): void;
  setSelection?(anchor: number, head: number, root: Document | ShadowRoot): void;
  stopEvent?(event: Event): boolean;
  ignoreMutation?(mutation: ViewMutationRecord): boolean;
  destroy?(): void;
}

interface MarkView {
  dom: DOMNode;
  contentDOM?: HTMLElement | null;
  ignoreMutation?(mutation: ViewMutationRecord): boolean;
  destroy?(): void;
}

Custom Views

Position and Coordinate Mapping

Utilities for converting between document positions and DOM coordinates.

class EditorView {
  posAtCoords(coords: {left: number, top: number}): {pos: number, inside: number} | null;
  coordsAtPos(pos: number, side?: number): {left: number, right: number, top: number, bottom: number};
  domAtPos(pos: number, side?: number): {node: DOMNode, offset: number};
  nodeDOM(pos: number): DOMNode | null;
  posAtDOM(node: DOMNode, offset: number, bias?: number): number;
  endOfTextblock(dir: "up" | "down" | "left" | "right" | "forward" | "backward", state?: EditorState): boolean;
}

Position Mapping

Editor Props and Configuration

Comprehensive configuration system for customizing editor behavior and handling events.

interface EditorProps<P = any> {
  handleDOMEvents?: {[event in keyof DOMEventMap]?: (this: P, view: EditorView, event: DOMEventMap[event]) => boolean | void};
  handleKeyDown?(this: P, view: EditorView, event: KeyboardEvent): boolean | void;
  handleTextInput?(this: P, view: EditorView, from: number, to: number, text: string, deflt: () => Transaction): boolean | void;
  handleClick?(this: P, view: EditorView, pos: number, event: MouseEvent): boolean | void;
  handlePaste?(this: P, view: EditorView, event: ClipboardEvent, slice: Slice): boolean | void;
  handleDrop?(this: P, view: EditorView, event: DragEvent, slice: Slice, moved: boolean): boolean | void;
  
  nodeViews?: {[node: string]: NodeViewConstructor};
  markViews?: {[mark: string]: MarkViewConstructor};
  decorations?(this: P, state: EditorState): DecorationSource | null | undefined;
  editable?(this: P, state: EditorState): boolean;
  attributes?: {[name: string]: string} | ((state: EditorState) => {[name: string]: string});
}

interface DirectEditorProps extends EditorProps {
  state: EditorState;
  plugins?: readonly Plugin[];
  dispatchTransaction?(tr: Transaction): void;
}

Editor Props

Input and Event Handling

Comprehensive input processing including keyboard events, mouse interactions, clipboard operations, and composition input.

class EditorView {
  pasteHTML(html: string, event?: ClipboardEvent): boolean;
  pasteText(text: string, event?: ClipboardEvent): boolean;
  serializeForClipboard(slice: Slice): {dom: HTMLElement, text: string, slice: Slice};
  dispatchEvent(event: Event): boolean;
}

Input Handling

Types

type NodeViewConstructor = (
  node: Node,
  view: EditorView,
  getPos: () => number | undefined,
  decorations: readonly Decoration[],
  innerDecorations: DecorationSource
) => NodeView;

type MarkViewConstructor = (mark: Mark, view: EditorView, inline: boolean) => MarkView;

type WidgetConstructor = ((view: EditorView, getPos: () => number | undefined) => DOMNode) | DOMNode;

type DecorationAttrs = {
  nodeName?: string;
  class?: string;
  style?: string;
  [attribute: string]: string | undefined;
};

type ViewMutationRecord = MutationRecord | { type: "selection", target: DOMNode };

interface DOMEventMap extends HTMLElementEventMap {
  [event: string]: any;
}

interface DecorationSource {
  map(mapping: Mapping, node: Node): DecorationSource;
  forChild(offset: number, child: Node): DecorationSource;
  locals(node: Node): readonly Decoration[];
  eq(other: DecorationSource): boolean;
  forEachSet(f: (set: DecorationSet) => void): void;
}