0
# ProseMirror View
1
2
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.
3
4
## Package Information
5
6
- **Package Name**: prosemirror-view
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install prosemirror-view`
10
11
## Core Imports
12
13
```typescript
14
import { EditorView } from "prosemirror-view";
15
```
16
17
For decorations:
18
19
```typescript
20
import { Decoration, DecorationSet } from "prosemirror-view";
21
```
22
23
For custom views:
24
25
```typescript
26
import { NodeView, MarkView } from "prosemirror-view";
27
```
28
29
## Basic Usage
30
31
```typescript
32
import { EditorView } from "prosemirror-view";
33
import { EditorState } from "prosemirror-state";
34
import { Schema, DOMParser } from "prosemirror-model";
35
import { exampleSetup } from "prosemirror-example-setup";
36
37
// Create editor state
38
const schema = new Schema({
39
nodes: {
40
doc: { content: "paragraph+" },
41
paragraph: { content: "text*", toDOM: () => ["p", 0] },
42
text: {}
43
}
44
});
45
46
const state = EditorState.create({
47
schema,
48
plugins: exampleSetup({ schema })
49
});
50
51
// Create editor view
52
const view = new EditorView(document.querySelector("#editor"), {
53
state,
54
dispatchTransaction(tr) {
55
view.updateState(view.state.apply(tr));
56
}
57
});
58
59
// Focus the editor
60
view.focus();
61
62
// Get position from coordinates
63
const pos = view.posAtCoords({ left: 100, top: 50 });
64
if (pos) {
65
console.log("Document position:", pos.pos);
66
}
67
```
68
69
## Architecture
70
71
ProseMirror View is built around several key components:
72
73
- **EditorView**: Central class managing DOM structure and user interactions
74
- **Decoration System**: Visual decorations for styling and annotations (widgets, inline, node)
75
- **Custom Views**: Extensible NodeView and MarkView interfaces for custom rendering
76
- **Input Handling**: Comprehensive event processing including keyboard, mouse, and composition
77
- **Coordinate Mapping**: Bidirectional position conversion between document and DOM
78
- **DOM Observer**: Change detection and state synchronization
79
- **Cross-browser Support**: Unified behavior across different browsers and platforms
80
81
## Capabilities
82
83
### Core Editor View
84
85
The main EditorView class that manages the DOM structure representing an editable document and handles user interactions.
86
87
```typescript { .api }
88
class EditorView {
89
constructor(
90
place: null | DOMNode | ((editor: HTMLElement) => void) | {mount: HTMLElement},
91
props: DirectEditorProps
92
);
93
94
readonly state: EditorState;
95
readonly dom: HTMLElement;
96
readonly editable: boolean;
97
readonly dragging: null | {slice: Slice, move: boolean};
98
readonly composing: boolean;
99
readonly props: DirectEditorProps;
100
readonly root: Document | ShadowRoot;
101
102
update(props: DirectEditorProps): void;
103
setProps(props: Partial<DirectEditorProps>): void;
104
updateState(state: EditorState): void;
105
focus(): void;
106
hasFocus(): boolean;
107
destroy(): void;
108
dispatch(tr: Transaction): void;
109
}
110
```
111
112
[Core Editor View](./core-editor-view.md)
113
114
### Decoration System
115
116
Visual decorations that can be applied to document content for styling, annotations, and interactive elements.
117
118
```typescript { .api }
119
class Decoration {
120
readonly from: number;
121
readonly to: number;
122
readonly spec: any;
123
124
static widget(pos: number, toDOM: WidgetConstructor, spec?: object): Decoration;
125
static inline(from: number, to: number, attrs: DecorationAttrs, spec?: object): Decoration;
126
static node(from: number, to: number, attrs: DecorationAttrs, spec?: object): Decoration;
127
}
128
129
class DecorationSet {
130
static empty: DecorationSet;
131
static create(doc: Node, decorations: readonly Decoration[]): DecorationSet;
132
133
find(start?: number, end?: number, predicate?: (spec: any) => boolean): Decoration[];
134
map(mapping: Mappable, doc: Node, options?: {onRemove?: (decorationSpec: any) => void}): DecorationSet;
135
add(doc: Node, decorations: readonly Decoration[]): DecorationSet;
136
remove(decorations: readonly Decoration[]): DecorationSet;
137
}
138
```
139
140
[Decoration System](./decoration-system.md)
141
142
### Custom Node and Mark Views
143
144
Extensible interfaces for custom rendering of document nodes and marks.
145
146
```typescript { .api }
147
interface NodeView {
148
dom: DOMNode;
149
contentDOM?: HTMLElement | null;
150
update?(node: Node, decorations: readonly Decoration[], innerDecorations: DecorationSource): boolean;
151
selectNode?(): void;
152
deselectNode?(): void;
153
setSelection?(anchor: number, head: number, root: Document | ShadowRoot): void;
154
stopEvent?(event: Event): boolean;
155
ignoreMutation?(mutation: ViewMutationRecord): boolean;
156
destroy?(): void;
157
}
158
159
interface MarkView {
160
dom: DOMNode;
161
contentDOM?: HTMLElement | null;
162
ignoreMutation?(mutation: ViewMutationRecord): boolean;
163
destroy?(): void;
164
}
165
```
166
167
[Custom Views](./custom-views.md)
168
169
### Position and Coordinate Mapping
170
171
Utilities for converting between document positions and DOM coordinates.
172
173
```typescript { .api }
174
class EditorView {
175
posAtCoords(coords: {left: number, top: number}): {pos: number, inside: number} | null;
176
coordsAtPos(pos: number, side?: number): {left: number, right: number, top: number, bottom: number};
177
domAtPos(pos: number, side?: number): {node: DOMNode, offset: number};
178
nodeDOM(pos: number): DOMNode | null;
179
posAtDOM(node: DOMNode, offset: number, bias?: number): number;
180
endOfTextblock(dir: "up" | "down" | "left" | "right" | "forward" | "backward", state?: EditorState): boolean;
181
}
182
```
183
184
[Position Mapping](./position-mapping.md)
185
186
### Editor Props and Configuration
187
188
Comprehensive configuration system for customizing editor behavior and handling events.
189
190
```typescript { .api }
191
interface EditorProps<P = any> {
192
handleDOMEvents?: {[event in keyof DOMEventMap]?: (this: P, view: EditorView, event: DOMEventMap[event]) => boolean | void};
193
handleKeyDown?(this: P, view: EditorView, event: KeyboardEvent): boolean | void;
194
handleTextInput?(this: P, view: EditorView, from: number, to: number, text: string, deflt: () => Transaction): boolean | void;
195
handleClick?(this: P, view: EditorView, pos: number, event: MouseEvent): boolean | void;
196
handlePaste?(this: P, view: EditorView, event: ClipboardEvent, slice: Slice): boolean | void;
197
handleDrop?(this: P, view: EditorView, event: DragEvent, slice: Slice, moved: boolean): boolean | void;
198
199
nodeViews?: {[node: string]: NodeViewConstructor};
200
markViews?: {[mark: string]: MarkViewConstructor};
201
decorations?(this: P, state: EditorState): DecorationSource | null | undefined;
202
editable?(this: P, state: EditorState): boolean;
203
attributes?: {[name: string]: string} | ((state: EditorState) => {[name: string]: string});
204
}
205
206
interface DirectEditorProps extends EditorProps {
207
state: EditorState;
208
plugins?: readonly Plugin[];
209
dispatchTransaction?(tr: Transaction): void;
210
}
211
```
212
213
[Editor Props](./editor-props.md)
214
215
### Input and Event Handling
216
217
Comprehensive input processing including keyboard events, mouse interactions, clipboard operations, and composition input.
218
219
```typescript { .api }
220
class EditorView {
221
pasteHTML(html: string, event?: ClipboardEvent): boolean;
222
pasteText(text: string, event?: ClipboardEvent): boolean;
223
serializeForClipboard(slice: Slice): {dom: HTMLElement, text: string, slice: Slice};
224
dispatchEvent(event: Event): boolean;
225
}
226
```
227
228
[Input Handling](./input-handling.md)
229
230
## Types
231
232
```typescript { .api }
233
type NodeViewConstructor = (
234
node: Node,
235
view: EditorView,
236
getPos: () => number | undefined,
237
decorations: readonly Decoration[],
238
innerDecorations: DecorationSource
239
) => NodeView;
240
241
type MarkViewConstructor = (mark: Mark, view: EditorView, inline: boolean) => MarkView;
242
243
type WidgetConstructor = ((view: EditorView, getPos: () => number | undefined) => DOMNode) | DOMNode;
244
245
type DecorationAttrs = {
246
nodeName?: string;
247
class?: string;
248
style?: string;
249
[attribute: string]: string | undefined;
250
};
251
252
type ViewMutationRecord = MutationRecord | { type: "selection", target: DOMNode };
253
254
interface DOMEventMap extends HTMLElementEventMap {
255
[event: string]: any;
256
}
257
258
interface DecorationSource {
259
map(mapping: Mapping, node: Node): DecorationSource;
260
forChild(offset: number, child: Node): DecorationSource;
261
locals(node: Node): readonly Decoration[];
262
eq(other: DecorationSource): boolean;
263
forEachSet(f: (set: DecorationSet) => void): void;
264
}
265
```