or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

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

index.mddocs/

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

```