@@ -34,13 +34,12 @@ yarn add @nytimes/react-prosemirror
3434 - [ Building NodeViews with React] ( #building-nodeviews-with-react )
3535- [ API] ( #api )
3636 - [ ` ProseMirror ` ] ( #prosemirror )
37+ - [ ` react ` ] ( #react )
3738 - [ ` useEditorState ` ] ( #useeditorstate )
3839 - [ ` useEditorEventCallback ` ] ( #useeditoreventcallback-1 )
3940 - [ ` useEditorEventListener ` ] ( #useeditoreventlistener-1 )
4041 - [ ` useEditorEffect ` ] ( #useeditoreffect-1 )
4142 - [ ` useNodePos ` ] ( #usenodepos )
42- - [ ` useNodeViews ` ] ( #usenodeviews )
43- - [ ` react ` ] ( #react )
4443
4544<!-- tocstop -->
4645
@@ -280,7 +279,7 @@ semantics for ProseMirror's `handleDOMEvents` prop:
280279 want to prevent the default contenteditable behavior, you must call
281280 ` event.preventDefault ` .
282281
283- You can use this hook to implement custom behavior in your NodeViews :
282+ You can use this hook to implement custom behavior in your node views :
284283
285284``` tsx
286285import { useEditorEventListener } from " @nytimes/react-prosemirror" ;
@@ -306,22 +305,20 @@ function Paragraph({ node, children }) {
306305}
307306```
308307
309- ### Building NodeViews with React
308+ ### Building node views with React
310309
311310The other way to integrate React and ProseMirror is to have ProseMirror render
312- NodeViews using React components. This is somewhat more complex than the
313- previous section. This library provides a ` useNodeViews ` hook, a factory for
314- augmenting NodeView constructors with React components, and ` react ` , a
315- ProseMirror Plugin for maintaining the React component hierarchy.
311+ node views using React components. The ` <ProseMirror> ` component recognizes when
312+ a node view constructor returns a node view with a ` component ` property and it
313+ renders the React component into the ProseMirror DOM element using a portal. The
314+ node view constructor must return at least ` dom ` and ` component ` property, but
315+ can also return any other node view properties. To support React node views, the
316+ editor state must include the React plugin (see below).
316317
317- ` useNodeViews ` takes a map from node name to an extended NodeView constructor.
318- The NodeView constructor must return at least a ` dom ` attribute and a
319- ` component ` attribute, but can also return any other NodeView attributes. Here's
320- an example of its usage:
318+ Example usage:
321319
322320``` tsx
323321import {
324- useNodeViews ,
325322 useEditorEventCallback ,
326323 NodeViewComponentProps ,
327324 react ,
@@ -338,12 +335,11 @@ function Paragraph({ children }: NodeViewComponentProps) {
338335 return <p onClick = { onClick } >{ children } </p >;
339336}
340337
341- // Make sure that your ReactNodeViews are defined outside of
342- // your component, or are properly memoized. ProseMirror will
343- // teardown and rebuild all NodeViews if the nodeView prop is
344- // updated, leading to unbounded recursion if this object doesn't
345- // have a stable reference.
346- const reactNodeViews = {
338+ // Make sure that your node views are defined outside of your copmonent, or are
339+ // properly memoized. ProseMirror will teardown and rebuild all node views if
340+ // the `nodeView` prop changes, leading to unbounded recursion if the reference
341+ // is not stable.
342+ const nodeViews = {
347343 paragraph : () => ({
348344 component: Paragraph ,
349345 // We render the Paragraph component itself into a div element
@@ -355,21 +351,18 @@ const reactNodeViews = {
355351 }),
356352};
357353
354+ // You must add the `react` plugin to use React node views.
358355const state = EditorState .create ({
359356 schema ,
360- // You must add the react plugin if you use
361- // the useNodeViews or useNodePos hook.
362357 plugins: [react ()],
363358});
364359
365360function ProseMirrorEditor() {
366- const { nodeViews, renderNodeViews } = useNodeViews (reactNodeViews );
367361 const [mount, setMount] = useState <HTMLElement | null >(null );
368362
369363 return (
370364 <ProseMirror mount = { mount } nodeViews = { nodeViews } defaultState = { state } >
371365 <div ref = { setMount } />
372- { renderNodeViews ()}
373366 </ProseMirror >
374367 );
375368}
@@ -417,6 +410,17 @@ function MyProseMirrorField() {
417410}
418411```
419412
413+ ### ` react `
414+
415+ ``` tsx
416+ type react = Plugin <Map <number , string >>;
417+ ```
418+
419+ A ProseMirror Plugin that assists in maintaining the correct hierarchy for React
420+ node views.
421+
422+ If you use React node views, then your ` EditorState ` _ must_ include this plugin.
423+
420424### ` useEditorState `
421425
422426``` tsx
@@ -509,75 +513,3 @@ type useNodePos = () => number;
509513Returns the node's current position in the document. Takes the place of
510514ProseMirror's ` getPos ` function that gets passed to NodeView's, which is unsafe
511515to use in React render functions.
512-
513- This hook can only be used in React components rendered with
514- [ ` useNodeViews ` ] ( #usenodeviews ) .
515-
516- ### ` useNodeViews `
517-
518- ``` tsx
519- /**
520- * Extension of ProseMirror's NodeViewConstructor type to include
521- * `component`, the React component to used render the NodeView.
522- * All properties other than `component` and `dom` are optional.
523- */
524- type ReactNodeViewConstructor = (
525- node : Node ,
526- view : EditorView ,
527- getPos : () => number ,
528- decorations : readonly Decoration [],
529- innerDecorations : DecorationSource
530- ) => {
531- dom: HTMLElement | null ;
532- component: React .ComponentType <NodeViewComponentProps >;
533- contentDOM? : HTMLElement | null ;
534- selectNode? : () => void ;
535- deselectNode? : () => void ;
536- setSelection? : (
537- anchor : number ,
538- head : number ,
539- root : Document | ShadowRoot
540- ) => void ;
541- stopEvent? : (event : Event ) => boolean ;
542- ignoreMutation? : (mutation : MutationRecord ) => boolean ;
543- destroy? : () => void ;
544- update? : (
545- node : Node ,
546- decorations : readonly Decoration [],
547- innerDecoration : DecorationSource
548- ) => boolean ;
549- };
550-
551- type useNodeViews = (nodeViews : Record <string , ReactNodeViewConstructor >) => {
552- nodeViews: Record <string , NodeViewConstructor >;
553- renderNodeViews: () => ReactElement [];
554- };
555- ```
556-
557- Hook for creating and rendering NodeViewConstructors that are powered by React
558- components. To use this hook, you must also include
559- [ ` react ` ] ( #reactnodeviewplugin ) in your ` EditorState ` .
560-
561- ` component ` can be any React component that takes ` NodeViewComponentProps ` . It
562- will be passed as props all of the arguments to the ` nodeViewConstructor ` except
563- for ` editorView ` . NodeView components that need access directly to the
564- EditorView should use the ` useEditorEventCallback ` , ` useEditorEventListener ` and
565- ` useEditorEffect ` hooks to ensure safe access.
566-
567- For contentful Nodes, the NodeView component will also be passed a ` children `
568- prop containing an empty element. ProseMirror will render content nodes into
569- this element. Like in ProseMirror, the existence of a ` contentDOM ` attribute
570- determines whether a NodeView is contentful (i.e. the NodeView has editable
571- content that should be managed by ProseMirror).
572-
573- ### ` react `
574-
575- ``` tsx
576- type react = Plugin <Map <number , string >>;
577- ```
578-
579- A ProseMirror Plugin that assists in maintaining the correct hierarchy for React
580- node views.
581-
582- If you use ` useNodeViews ` or ` useNodePos ` , you _ must_ include this plugin in
583- your ` EditorState ` .
0 commit comments