ProseMirror's view component that manages DOM structure and user interactions for rich text editing
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
The EditorView class is the central component that manages the DOM structure representing an editable document and handles all user interactions. It serves as the bridge between ProseMirror's abstract document model and the browser's DOM.
The main class for creating and managing editor instances.
/**
* An editor view manages the DOM structure that represents an
* editable document. Its state and behavior are determined by its props.
*/
class EditorView {
/**
* Create a view. `place` may be a DOM node that the editor should
* be appended to, a function that will place it into the document,
* or an object whose `mount` property holds the node to use as the
* document container. If it is `null`, the editor will not be
* added to the document.
*/
constructor(
place: null | DOMNode | ((editor: HTMLElement) => void) | {mount: HTMLElement},
props: DirectEditorProps
);
}Usage Examples:
import { EditorView } from "prosemirror-view";
import { EditorState } from "prosemirror-state";
// Mount to DOM element
const view = new EditorView(document.querySelector("#editor"), {
state: myEditorState,
dispatchTransaction(tr) {
this.updateState(this.state.apply(tr));
}
});
// Mount with custom placement function
const view2 = new EditorView((dom) => {
document.body.appendChild(dom);
}, { state: myEditorState });
// Mount to specific container
const view3 = new EditorView({ mount: document.querySelector("#container") }, {
state: myEditorState
});Core properties that define the editor's current state and configuration.
class EditorView {
/** The view's current state */
readonly state: EditorState;
/** An editable DOM node containing the document */
readonly dom: HTMLElement;
/** Indicates whether the editor is currently editable */
readonly editable: boolean;
/** When editor content is being dragged, contains drag information */
readonly dragging: null | {slice: Slice, move: boolean};
/** Holds true when a composition is active */
readonly composing: boolean;
/** The view's current props */
readonly props: DirectEditorProps;
/**
* Get the document root in which the editor exists.
* Usually the top-level document, but might be a shadow DOM root.
*/
readonly root: Document | ShadowRoot;
/** This is true when the view has been destroyed */
readonly isDestroyed: boolean;
}Methods for updating the editor's state and configuration.
class EditorView {
/**
* Update the view's props. Will immediately cause an update to the DOM.
*/
update(props: DirectEditorProps): void;
/**
* Update the view by updating existing props object with the object
* given as argument. Equivalent to `view.update(Object.assign({}, view.props, props))`.
*/
setProps(props: Partial<DirectEditorProps>): void;
/**
* Update the editor's `state` prop, without touching any of the other props.
*/
updateState(state: EditorState): void;
}Usage Examples:
// Update state
const newState = view.state.apply(transaction);
view.updateState(newState);
// Update props
view.setProps({
editable: false,
decorations: () => myDecorations
});
// Full props update
view.update({
...view.props,
state: newState,
handleKeyDown: myKeyHandler
});Methods for managing editor focus state.
class EditorView {
/**
* Query whether the view has focus.
* Works around IE focus handling issues.
*/
hasFocus(): boolean;
/**
* Focus the editor.
*/
focus(): void;
/**
* When an existing editor view is moved to a new document or
* shadow tree, call this to make it recompute its root.
*/
updateRoot(): void;
}Usage Examples:
// Check and focus if needed
if (!view.hasFocus()) {
view.focus();
}
// After moving to new document/shadow root
view.updateRoot();Utility for querying prop values across the view and its plugins.
class EditorView {
/**
* Goes over the values of a prop, first those provided directly,
* then those from plugins given to the view, then from plugins in
* the state (in order), and calls `f` every time a non-undefined
* value is found. When `f` returns a truthy value, that is
* immediately returned. When `f` isn't provided, it is treated as
* the identity function (the prop value is returned directly).
*/
someProp<PropName extends keyof EditorProps, Result>(
propName: PropName,
f: (value: NonNullable<EditorProps[PropName]>) => Result
): Result | undefined;
someProp<PropName extends keyof EditorProps>(
propName: PropName
): NonNullable<EditorProps[PropName]> | undefined;
}Usage Examples:
// Get first editable prop value
const isEditable = view.someProp("editable", f => f(view.state));
// Check if any plugin handles a key
const handled = view.someProp("handleKeyDown", f => f(view, event));
// Get nodeViews configuration
const nodeViews = view.someProp("nodeViews");Method for dispatching transactions to update the editor state.
class EditorView {
/**
* Dispatch a transaction. Will call `dispatchTransaction` when given,
* and otherwise defaults to applying the transaction to the current
* state and calling `updateState` with the result.
* This method is bound to the view instance, so that it can be
* easily passed around.
*/
dispatch(tr: Transaction): void;
}Usage Examples:
import { TextSelection } from "prosemirror-state";
// Create and dispatch transaction
const tr = view.state.tr.insertText("Hello, world!");
view.dispatch(tr);
// Move cursor to start
const startSelection = TextSelection.create(view.state.doc, 0);
view.dispatch(view.state.tr.setSelection(startSelection));
// Use as callback
button.addEventListener("click", view.dispatch);Method for properly destroying the editor view.
class EditorView {
/**
* Removes the editor from the DOM and destroys all node views.
*/
destroy(): void;
}Usage Examples:
// Clean up when component unmounts
useEffect(() => {
return () => {
view.destroy();
};
}, [view]);
// Check if destroyed
if (view.isDestroyed) {
console.log("View has been destroyed");
}Methods primarily intended for testing scenarios.
class EditorView {
/**
* Used for testing. Dispatches a DOM event to the view.
*/
dispatchEvent(event: Event): boolean;
}Usage Examples:
// Simulate key press in tests
const keyEvent = new KeyboardEvent("keydown", { key: "Enter" });
const handled = view.dispatchEvent(keyEvent);Install with Tessl CLI
npx tessl i tessl/npm-prosemirror-view