@handlewithcare/react-prosemirror 2.4.12 → 2.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/dist/cjs/AbstractEditorView.js +4 -0
  2. package/dist/cjs/ReactEditorView.js +156 -0
  3. package/dist/cjs/StaticEditorView.js +86 -0
  4. package/dist/cjs/components/ChildNodeViews.js +58 -29
  5. package/dist/cjs/components/CustomNodeView.js +77 -137
  6. package/dist/cjs/{hooks/useNodePos.js → components/DefaultNodeView.js} +24 -26
  7. package/dist/cjs/components/DocNodeView.js +33 -41
  8. package/dist/cjs/components/MarkView.js +1 -2
  9. package/dist/cjs/components/NativeWidgetView.js +2 -3
  10. package/dist/cjs/components/NodeView.js +31 -21
  11. package/dist/cjs/components/ProseMirror.js +25 -17
  12. package/dist/cjs/components/ProseMirrorDoc.js +7 -27
  13. package/dist/cjs/components/ReactNodeView.js +98 -61
  14. package/dist/cjs/components/SeparatorHackView.js +1 -2
  15. package/dist/cjs/components/TextNodeView.js +4 -5
  16. package/dist/cjs/components/TrailingHackView.js +1 -2
  17. package/dist/cjs/components/WidgetView.js +2 -4
  18. package/dist/cjs/constants.js +33 -0
  19. package/dist/cjs/hooks/useEditor.js +33 -229
  20. package/dist/cjs/hooks/useEditorEffect.js +2 -2
  21. package/dist/cjs/hooks/useEditorEventCallback.js +8 -5
  22. package/dist/cjs/hooks/useIgnoreMutation.js +1 -1
  23. package/dist/cjs/hooks/useNodeViewDescriptor.js +123 -80
  24. package/dist/cjs/hooks/useReactKeys.js +1 -1
  25. package/dist/cjs/hooks/useSelectNode.js +9 -7
  26. package/dist/cjs/hooks/useStopEvent.js +1 -1
  27. package/dist/cjs/plugins/beforeInputPlugin.js +12 -0
  28. package/dist/cjs/testing/editorViewTestHelpers.js +0 -2
  29. package/dist/cjs/viewdesc.js +104 -25
  30. package/dist/esm/AbstractEditorView.js +1 -0
  31. package/dist/esm/ReactEditorView.js +156 -0
  32. package/dist/esm/StaticEditorView.js +76 -0
  33. package/dist/esm/components/ChildNodeViews.js +59 -31
  34. package/dist/esm/components/CustomNodeView.js +78 -138
  35. package/dist/esm/components/DefaultNodeView.js +16 -0
  36. package/dist/esm/components/DocNodeView.js +33 -41
  37. package/dist/esm/components/MarkView.js +1 -2
  38. package/dist/esm/components/NativeWidgetView.js +2 -3
  39. package/dist/esm/components/NodeView.js +32 -22
  40. package/dist/esm/components/ProseMirror.js +25 -17
  41. package/dist/esm/components/ProseMirrorDoc.js +7 -28
  42. package/dist/esm/components/ReactNodeView.js +99 -62
  43. package/dist/esm/components/SeparatorHackView.js +1 -2
  44. package/dist/esm/components/TextNodeView.js +4 -5
  45. package/dist/esm/components/TrailingHackView.js +1 -2
  46. package/dist/esm/components/WidgetView.js +2 -4
  47. package/dist/esm/constants.js +15 -0
  48. package/dist/esm/hooks/useEditor.js +29 -218
  49. package/dist/esm/hooks/useEditorEffect.js +2 -2
  50. package/dist/esm/hooks/useEditorEventCallback.js +8 -5
  51. package/dist/esm/hooks/useIgnoreMutation.js +1 -1
  52. package/dist/esm/hooks/useNodeViewDescriptor.js +125 -82
  53. package/dist/esm/hooks/useReactKeys.js +1 -1
  54. package/dist/esm/hooks/useSelectNode.js +9 -7
  55. package/dist/esm/hooks/useStopEvent.js +1 -1
  56. package/dist/esm/plugins/beforeInputPlugin.js +12 -0
  57. package/dist/esm/testing/editorViewTestHelpers.js +0 -2
  58. package/dist/esm/viewdesc.js +94 -18
  59. package/dist/tsconfig.tsbuildinfo +1 -1
  60. package/dist/types/AbstractEditorView.d.ts +27 -0
  61. package/dist/types/ReactEditorView.d.ts +80 -0
  62. package/dist/types/StaticEditorView.d.ts +24 -0
  63. package/dist/types/components/ChildNodeViews.d.ts +2 -2
  64. package/dist/types/components/CustomNodeView.d.ts +3 -3
  65. package/dist/types/components/DefaultNodeView.d.ts +3 -0
  66. package/dist/types/components/DocNodeView.d.ts +9 -17
  67. package/dist/types/components/MarkView.d.ts +2 -2
  68. package/dist/types/components/NativeWidgetView.d.ts +2 -2
  69. package/dist/types/components/NodeView.d.ts +5 -5
  70. package/dist/types/components/NodeViewComponentProps.d.ts +3 -4
  71. package/dist/types/components/ProseMirrorDoc.d.ts +14 -8
  72. package/dist/types/components/ReactNodeView.d.ts +4 -2
  73. package/dist/types/components/SeparatorHackView.d.ts +2 -2
  74. package/dist/types/components/TextNodeView.d.ts +4 -3
  75. package/dist/types/components/TrailingHackView.d.ts +2 -2
  76. package/dist/types/components/WidgetView.d.ts +2 -2
  77. package/dist/types/constants.d.ts +4 -0
  78. package/dist/types/contexts/EditorContext.d.ts +6 -4
  79. package/dist/types/contexts/IgnoreMutationContext.d.ts +2 -1
  80. package/dist/types/contexts/NodeViewContext.d.ts +3 -1
  81. package/dist/types/contexts/SelectNodeContext.d.ts +3 -1
  82. package/dist/types/contexts/StopEventContext.d.ts +2 -1
  83. package/dist/types/decorations/computeDocDeco.d.ts +3 -2
  84. package/dist/types/decorations/viewDecorations.d.ts +3 -2
  85. package/dist/types/hooks/useEditor.d.ts +5 -46
  86. package/dist/types/hooks/useNodeViewDescriptor.d.ts +18 -10
  87. package/dist/types/hooks/useReactKeys.d.ts +1 -1
  88. package/dist/types/hooks/useSelectNode.d.ts +2 -1
  89. package/dist/types/props.d.ts +3 -3
  90. package/dist/types/viewdesc.d.ts +29 -11
  91. package/package.json +7 -3
  92. package/dist/cjs/components/Editor.js +0 -28
  93. package/dist/cjs/components/NodeViews.js +0 -73
  94. package/dist/cjs/components/__tests__/LayoutGroup.test.js +0 -141
  95. package/dist/cjs/components/__tests__/ProseMirror.test.js +0 -255
  96. package/dist/cjs/contexts/NodeViewsContext.js +0 -10
  97. package/dist/cjs/hooks/__tests__/useEditorViewLayoutEffect.test.js +0 -107
  98. package/dist/cjs/hooks/__tests__/useNodeViews.test.js +0 -159
  99. package/dist/cjs/hooks/useClientOnly.js +0 -19
  100. package/dist/cjs/hooks/useEditorView.js +0 -100
  101. package/dist/cjs/hooks/useNodeViews.js +0 -100
  102. package/dist/cjs/nodeViews/createReactNodeViewConstructor.js +0 -244
  103. package/dist/cjs/nodeViews/phrasingContentTags.js +0 -57
  104. package/dist/cjs/plugins/__tests__/react.test.js +0 -139
  105. package/dist/cjs/plugins/react.js +0 -71
  106. package/dist/cjs/selection/SelectionDOMObserver.js +0 -171
  107. package/dist/cjs/selection/hasFocusAndSelection.js +0 -35
  108. package/dist/cjs/selection/selectionFromDOM.js +0 -77
  109. package/dist/cjs/selection/selectionToDOM.js +0 -226
  110. package/dist/cjs/ssr.js +0 -85
  111. package/dist/esm/components/Editor.js +0 -15
  112. package/dist/esm/components/NodeViews.js +0 -26
  113. package/dist/esm/components/__tests__/LayoutGroup.test.js +0 -98
  114. package/dist/esm/components/__tests__/ProseMirror.test.js +0 -207
  115. package/dist/esm/contexts/NodeViewsContext.js +0 -9
  116. package/dist/esm/hooks/__tests__/useEditorViewLayoutEffect.test.js +0 -98
  117. package/dist/esm/hooks/__tests__/useNodeViews.test.js +0 -116
  118. package/dist/esm/hooks/useClientOnly.js +0 -9
  119. package/dist/esm/hooks/useEditorView.js +0 -99
  120. package/dist/esm/hooks/useNodePos.js +0 -16
  121. package/dist/esm/hooks/useNodeViews.js +0 -53
  122. package/dist/esm/nodeViews/createReactNodeViewConstructor.js +0 -214
  123. package/dist/esm/nodeViews/phrasingContentTags.js +0 -49
  124. package/dist/esm/plugins/__tests__/react.test.js +0 -135
  125. package/dist/esm/plugins/react.js +0 -64
  126. package/dist/esm/selection/SelectionDOMObserver.js +0 -161
  127. package/dist/esm/selection/hasFocusAndSelection.js +0 -17
  128. package/dist/esm/selection/selectionFromDOM.js +0 -59
  129. package/dist/esm/selection/selectionToDOM.js +0 -196
  130. package/dist/esm/ssr.js +0 -82
  131. package/dist/types/components/Editor.d.ts +0 -7
  132. package/dist/types/components/NodeViews.d.ts +0 -6
  133. package/dist/types/components/__tests__/LayoutGroup.test.d.ts +0 -1
  134. package/dist/types/contexts/NodeViewsContext.d.ts +0 -19
  135. package/dist/types/hooks/__tests__/useEditorViewLayoutEffect.test.d.ts +0 -1
  136. package/dist/types/hooks/__tests__/useNodeViews.test.d.ts +0 -1
  137. package/dist/types/hooks/useClientOnly.d.ts +0 -1
  138. package/dist/types/hooks/useEditorView.d.ts +0 -23
  139. package/dist/types/hooks/useNodePos.d.ts +0 -9
  140. package/dist/types/hooks/useNodeViews.d.ts +0 -5
  141. package/dist/types/nodeViews/createReactNodeViewConstructor.d.ts +0 -48
  142. package/dist/types/nodeViews/phrasingContentTags.d.ts +0 -1
  143. package/dist/types/plugins/__tests__/react.test.d.ts +0 -1
  144. package/dist/types/plugins/react.d.ts +0 -21
  145. package/dist/types/selection/SelectionDOMObserver.d.ts +0 -33
  146. package/dist/types/selection/hasFocusAndSelection.d.ts +0 -3
  147. package/dist/types/selection/selectionFromDOM.d.ts +0 -4
  148. package/dist/types/selection/selectionToDOM.d.ts +0 -9
  149. package/dist/types/ssr.d.ts +0 -19
@@ -1,207 +0,0 @@
1
- import { act, render, screen } from "@testing-library/react";
2
- import userEvent from "@testing-library/user-event";
3
- import { Schema } from "prosemirror-model";
4
- import { EditorState } from "prosemirror-state";
5
- import React, { useEffect, useState } from "react";
6
- import { react } from "../../plugins/react.js";
7
- import { setupProseMirrorView, teardownProseMirrorView } from "../../testing/setupProseMirrorView.js";
8
- import { ProseMirror } from "../ProseMirror.js";
9
- // Mock `ReactDOM.flushSync` to call `act` to flush updates from DOM mutations.
10
- jest.mock("react-dom", ()=>({
11
- ...jest.requireActual("react-dom"),
12
- flushSync: (fn)=>act(fn)
13
- }));
14
- describe("ProseMirror", ()=>{
15
- beforeAll(()=>{
16
- setupProseMirrorView();
17
- });
18
- it("renders a contenteditable", async ()=>{
19
- const schema = new Schema({
20
- nodes: {
21
- text: {},
22
- doc: {
23
- content: "text*"
24
- }
25
- }
26
- });
27
- const defaultState = EditorState.create({
28
- schema
29
- });
30
- function TestEditor() {
31
- const [mount, setMount] = useState(null);
32
- return /*#__PURE__*/ React.createElement(ProseMirror, {
33
- mount: mount,
34
- defaultState: defaultState
35
- }, /*#__PURE__*/ React.createElement("div", {
36
- "data-testid": "editor",
37
- ref: setMount
38
- }));
39
- }
40
- const user = userEvent.setup();
41
- render(/*#__PURE__*/ React.createElement(TestEditor, null));
42
- const editor = screen.getByTestId("editor");
43
- await user.type(editor, "Hello, world!");
44
- expect(editor.textContent).toBe("Hello, world!");
45
- });
46
- it("supports observing transaction dispatch", async ()=>{
47
- const schema = new Schema({
48
- nodes: {
49
- text: {},
50
- doc: {
51
- content: "text*"
52
- }
53
- }
54
- });
55
- const defaultState = EditorState.create({
56
- schema
57
- });
58
- const dispatchTransaction = jest.fn();
59
- function TestEditor() {
60
- const [mount, setMount] = useState(null);
61
- return /*#__PURE__*/ React.createElement(ProseMirror, {
62
- mount: mount,
63
- defaultState: defaultState,
64
- dispatchTransaction: dispatchTransaction
65
- }, /*#__PURE__*/ React.createElement("div", {
66
- "data-testid": "editor",
67
- ref: setMount
68
- }));
69
- }
70
- const user = userEvent.setup();
71
- render(/*#__PURE__*/ React.createElement(TestEditor, null));
72
- const editor = screen.getByTestId("editor");
73
- await user.type(editor, "Hello, world!");
74
- expect(editor.textContent).toBe("Hello, world!");
75
- expect(dispatchTransaction).toHaveBeenCalledTimes(13);
76
- });
77
- it("supports controlling the editor state", async ()=>{
78
- const schema = new Schema({
79
- nodes: {
80
- text: {},
81
- doc: {
82
- content: "text*"
83
- }
84
- }
85
- });
86
- let observedState = EditorState.create({
87
- schema
88
- });
89
- function TestEditor() {
90
- const [state, setState] = useState(observedState);
91
- const [mount, setMount] = useState(null);
92
- useEffect(()=>{
93
- observedState = state;
94
- }, [
95
- state
96
- ]);
97
- return /*#__PURE__*/ React.createElement(ProseMirror, {
98
- mount: mount,
99
- state: state,
100
- dispatchTransaction: (tr)=>{
101
- setState((s)=>s.apply(tr));
102
- }
103
- }, /*#__PURE__*/ React.createElement("div", {
104
- "data-testid": "editor",
105
- ref: setMount
106
- }));
107
- }
108
- const user = userEvent.setup();
109
- render(/*#__PURE__*/ React.createElement(TestEditor, null));
110
- const editor = screen.getByTestId("editor");
111
- await user.type(editor, "Hello, world!");
112
- expect(observedState.doc.textContent).toBe("Hello, world!");
113
- });
114
- it("updates props atomically", async ()=>{
115
- const schema = new Schema({
116
- nodes: {
117
- text: {},
118
- doc: {
119
- content: "text*"
120
- }
121
- }
122
- });
123
- const defaultState = EditorState.create({
124
- schema
125
- });
126
- let allStatesMatched = true;
127
- function TestEditor() {
128
- const [state, setState] = useState(defaultState);
129
- const [mount, setMount] = useState(null);
130
- // Check that function props get invoked with the latest React state.
131
- const editable = (viewState)=>{
132
- allStatesMatched &&= viewState === state;
133
- return true;
134
- };
135
- return /*#__PURE__*/ React.createElement(ProseMirror, {
136
- mount: mount,
137
- editable: editable,
138
- state: state,
139
- dispatchTransaction: (tr)=>{
140
- setState((s)=>s.apply(tr));
141
- }
142
- }, /*#__PURE__*/ React.createElement("div", {
143
- "data-testid": "editor",
144
- ref: setMount
145
- }));
146
- }
147
- const user = userEvent.setup();
148
- render(/*#__PURE__*/ React.createElement(TestEditor, null));
149
- const editor = screen.getByTestId("editor");
150
- await user.type(editor, "Hello, world!");
151
- expect(allStatesMatched).toBe(true);
152
- });
153
- it("supports React NodeViews", async ()=>{
154
- const schema = new Schema({
155
- nodes: {
156
- text: {},
157
- paragraph: {
158
- content: "text*"
159
- },
160
- doc: {
161
- content: "paragraph+"
162
- }
163
- }
164
- });
165
- const defaultState = EditorState.create({
166
- schema,
167
- plugins: [
168
- react()
169
- ]
170
- });
171
- function Paragraph(param) {
172
- let { children } = param;
173
- return /*#__PURE__*/ React.createElement("p", {
174
- "data-testid": "paragraph"
175
- }, children);
176
- }
177
- const nodeViews = {
178
- paragraph: ()=>({
179
- component: Paragraph,
180
- dom: document.createElement("div"),
181
- contentDOM: document.createElement("span")
182
- })
183
- };
184
- function TestEditor() {
185
- const [mount, setMount] = useState(null);
186
- return /*#__PURE__*/ React.createElement(ProseMirror, {
187
- mount: mount,
188
- defaultState: defaultState,
189
- nodeViews: nodeViews
190
- }, /*#__PURE__*/ React.createElement("div", {
191
- "data-testid": "editor",
192
- ref: setMount
193
- }));
194
- }
195
- const user = userEvent.setup();
196
- render(/*#__PURE__*/ React.createElement(TestEditor, null));
197
- const editor = screen.getByTestId("editor");
198
- await user.type(editor, "Hello, world!");
199
- expect(editor.textContent).toBe("Hello, world!");
200
- // Ensure that ProseMirror really rendered our Paragraph
201
- // component, not just any old <p> tag
202
- expect(screen.getAllByTestId("paragraph").length).toBeGreaterThanOrEqual(1);
203
- });
204
- afterAll(()=>{
205
- teardownProseMirrorView();
206
- });
207
- });
@@ -1,9 +0,0 @@
1
- import { createContext } from "react";
2
- /**
3
- * A context containing a map of node view keys to portals.
4
- *
5
- * Each node view registers a portal under its parent's
6
- * key. Each can then retrieve the list of portals under their
7
- * key, allowing portals to be rendered with the appropriate
8
- * hierarchy.
9
- */ export const NodeViewsContext = createContext(null);
@@ -1,98 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-empty-function */ import { render } from "@testing-library/react";
2
- import React from "react";
3
- import { LayoutGroup } from "../../components/LayoutGroup.js";
4
- import { EditorContext } from "../../contexts/EditorContext.js";
5
- import { useEditorEffect } from "../useEditorEffect.js";
6
- function TestComponent(param) {
7
- let { effect , dependencies =[] } = param;
8
- useEditorEffect(effect, [
9
- effect,
10
- ...dependencies
11
- ]);
12
- return null;
13
- }
14
- describe("useEditorViewLayoutEffect", ()=>{
15
- it("should run the effect", ()=>{
16
- const effect = jest.fn();
17
- const editorView = {};
18
- const editorState = {};
19
- const registerEventListener = ()=>{};
20
- const unregisterEventListener = ()=>{};
21
- render(/*#__PURE__*/ React.createElement(LayoutGroup, null, /*#__PURE__*/ React.createElement(EditorContext.Provider, {
22
- value: {
23
- editorView,
24
- editorState,
25
- registerEventListener,
26
- unregisterEventListener
27
- }
28
- }, /*#__PURE__*/ React.createElement(TestComponent, {
29
- effect: effect
30
- }))));
31
- expect(effect).toHaveBeenCalled();
32
- expect(effect).toHaveBeenCalledWith(editorView);
33
- });
34
- it("should not re-run the effect if no dependencies change", ()=>{
35
- const effect = jest.fn();
36
- const editorView = {};
37
- const editorState = {};
38
- const registerEventListener = ()=>{};
39
- const unregisterEventListener = ()=>{};
40
- const { rerender } = render(/*#__PURE__*/ React.createElement(LayoutGroup, null, /*#__PURE__*/ React.createElement(EditorContext.Provider, {
41
- value: {
42
- editorView,
43
- editorState,
44
- registerEventListener,
45
- unregisterEventListener
46
- }
47
- }, /*#__PURE__*/ React.createElement(TestComponent, {
48
- effect: effect,
49
- dependencies: []
50
- }))));
51
- rerender(/*#__PURE__*/ React.createElement(LayoutGroup, null, /*#__PURE__*/ React.createElement(EditorContext.Provider, {
52
- value: {
53
- editorView,
54
- editorState,
55
- registerEventListener,
56
- unregisterEventListener
57
- }
58
- }, /*#__PURE__*/ React.createElement(TestComponent, {
59
- effect: effect,
60
- dependencies: []
61
- }))));
62
- expect(effect).toHaveBeenCalledTimes(1);
63
- });
64
- it("should re-run the effect if dependencies change", ()=>{
65
- const effect = jest.fn();
66
- const editorView = {};
67
- const editorState = {};
68
- const registerEventListener = ()=>{};
69
- const unregisterEventListener = ()=>{};
70
- const { rerender } = render(/*#__PURE__*/ React.createElement(LayoutGroup, null, /*#__PURE__*/ React.createElement(EditorContext.Provider, {
71
- value: {
72
- editorView,
73
- editorState,
74
- registerEventListener,
75
- unregisterEventListener
76
- }
77
- }, /*#__PURE__*/ React.createElement(TestComponent, {
78
- effect: effect,
79
- dependencies: [
80
- "one"
81
- ]
82
- }))));
83
- rerender(/*#__PURE__*/ React.createElement(LayoutGroup, null, /*#__PURE__*/ React.createElement(EditorContext.Provider, {
84
- value: {
85
- editorView,
86
- editorState,
87
- registerEventListener,
88
- unregisterEventListener
89
- }
90
- }, /*#__PURE__*/ React.createElement(TestComponent, {
91
- effect: effect,
92
- dependencies: [
93
- "two"
94
- ]
95
- }))));
96
- expect(effect).toHaveBeenCalledTimes(2);
97
- });
98
- });
@@ -1,116 +0,0 @@
1
- import { act, render, screen } from "@testing-library/react";
2
- import { Schema } from "prosemirror-model";
3
- import { EditorState } from "prosemirror-state";
4
- import React, { createContext, useContext, useState } from "react";
5
- import { ProseMirror } from "../../components/ProseMirror.js";
6
- import { react } from "../../plugins/react.js";
7
- // Mock `ReactDOM.flushSync` to call `act` to flush updates from DOM mutations.
8
- jest.mock("react-dom", ()=>({
9
- ...jest.requireActual("react-dom"),
10
- flushSync: (fn)=>act(fn)
11
- }));
12
- const schema = new Schema({
13
- nodes: {
14
- doc: {
15
- content: "block+"
16
- },
17
- list: {
18
- group: "block",
19
- content: "list_item+"
20
- },
21
- list_item: {
22
- content: "inline*"
23
- },
24
- text: {
25
- group: "inline"
26
- }
27
- }
28
- });
29
- const state = EditorState.create({
30
- doc: schema.topNodeType.create(null, schema.nodes.list.createAndFill()),
31
- schema,
32
- plugins: [
33
- react()
34
- ]
35
- });
36
- describe("useNodeViews", ()=>{
37
- it("should render node views", ()=>{
38
- function List(param) {
39
- let { children } = param;
40
- return /*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement("span", {
41
- contentEditable: false
42
- }, "list"), /*#__PURE__*/ React.createElement("ul", null, children));
43
- }
44
- function ListItem(param) {
45
- let { children } = param;
46
- return /*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement("span", {
47
- contentEditable: false
48
- }, "list item"), /*#__PURE__*/ React.createElement("li", null, children));
49
- }
50
- const nodeViews = {
51
- list: ()=>({
52
- component: List,
53
- dom: document.createElement("div"),
54
- contentDOM: document.createElement("div")
55
- }),
56
- list_item: ()=>({
57
- component: ListItem,
58
- dom: document.createElement("div"),
59
- contentDOM: document.createElement("div")
60
- })
61
- };
62
- function TestEditor() {
63
- const [mount, setMount] = useState(null);
64
- return /*#__PURE__*/ React.createElement(ProseMirror, {
65
- mount: mount,
66
- nodeViews: nodeViews,
67
- defaultState: state
68
- }, /*#__PURE__*/ React.createElement("div", {
69
- ref: setMount
70
- }));
71
- }
72
- render(/*#__PURE__*/ React.createElement(TestEditor, null));
73
- expect(screen.getByText("list")).toBeTruthy();
74
- expect(screen.getByText("list item")).toBeTruthy();
75
- });
76
- it("should render child node views as children of their parents", ()=>{
77
- const TestContext = /*#__PURE__*/ createContext("default");
78
- function List(param) {
79
- let { children } = param;
80
- return /*#__PURE__*/ React.createElement(TestContext.Provider, {
81
- value: "overriden"
82
- }, /*#__PURE__*/ React.createElement("ul", null, children));
83
- }
84
- function ListItem(param) {
85
- let { children } = param;
86
- const testContextValue = useContext(TestContext);
87
- return /*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement("span", {
88
- contentEditable: false
89
- }, testContextValue), /*#__PURE__*/ React.createElement("li", null, children));
90
- }
91
- const nodeViews = {
92
- list: ()=>({
93
- component: List,
94
- dom: document.createElement("div"),
95
- contentDOM: document.createElement("div")
96
- }),
97
- list_item: ()=>({
98
- component: ListItem,
99
- dom: document.createElement("div"),
100
- contentDOM: document.createElement("div")
101
- })
102
- };
103
- function TestEditor() {
104
- const [mount, setMount] = useState(null);
105
- return /*#__PURE__*/ React.createElement(ProseMirror, {
106
- mount: mount,
107
- nodeViews: nodeViews,
108
- defaultState: state
109
- }, /*#__PURE__*/ React.createElement("div", {
110
- ref: setMount
111
- }));
112
- }
113
- render(/*#__PURE__*/ React.createElement(TestEditor, null));
114
- expect(screen.getByText("overriden")).toBeTruthy();
115
- });
116
- });
@@ -1,9 +0,0 @@
1
- import { useSyncExternalStore } from "react";
2
- // eslint-disable-next-line @typescript-eslint/no-empty-function
3
- function unsubscribe() {}
4
- function subscribe() {
5
- return unsubscribe;
6
- }
7
- export function useClientOnly() {
8
- return useSyncExternalStore(subscribe, ()=>true, ()=>false);
9
- }
@@ -1,99 +0,0 @@
1
- import { Schema } from "prosemirror-model";
2
- import { EditorState } from "prosemirror-state";
3
- import { EditorView } from "prosemirror-view";
4
- import { useLayoutEffect, useMemo, useState } from "react";
5
- import { flushSync } from "react-dom";
6
- import { useComponentEventListeners } from "./useComponentEventListeners.js";
7
- const EMPTY_SCHEMA = new Schema({
8
- nodes: {
9
- doc: {
10
- content: "text*"
11
- },
12
- text: {
13
- inline: true
14
- }
15
- }
16
- });
17
- const EMPTY_STATE = EditorState.create({
18
- schema: EMPTY_SCHEMA
19
- });
20
- let didWarnValueDefaultValue = false;
21
- /**
22
- * Creates, mounts, and manages a ProseMirror `EditorView`.
23
- *
24
- * All state and props updates are executed in a layout effect.
25
- * To ensure that the EditorState and EditorView are never out of
26
- * sync, it's important that the EditorView produced by this hook
27
- * is only accessed through the provided hooks.
28
- */ export function useEditorView(mount, options) {
29
- if (process.env.NODE_ENV !== "production") {
30
- if (options.defaultState !== undefined && options.state !== undefined && !didWarnValueDefaultValue) {
31
- console.error("A component contains a ProseMirror editor with both value and defaultValue props. " + "ProseMirror editors must be either controlled or uncontrolled " + "(specify either the state prop, or the defaultState prop, but not both). " + "Decide between using a controlled or uncontrolled ProseMirror editor " + "and remove one of these props. More info: " + "https://reactjs.org/link/controlled-components");
32
- didWarnValueDefaultValue = true;
33
- }
34
- }
35
- const defaultState = options.defaultState ?? EMPTY_STATE;
36
- const [_state, setState] = useState(defaultState);
37
- const state = options.state ?? _state;
38
- const { componentEventListenersPlugin , registerEventListener , unregisterEventListener } = useComponentEventListeners();
39
- const plugins = useMemo(()=>[
40
- ...options.plugins ?? [],
41
- componentEventListenersPlugin
42
- ], [
43
- options.plugins,
44
- componentEventListenersPlugin
45
- ]);
46
- function dispatchTransaction(tr) {
47
- flushSync(()=>{
48
- if (!options.state) {
49
- setState((s)=>s.apply(tr));
50
- }
51
- if (options.dispatchTransaction) {
52
- options.dispatchTransaction.call(this, tr);
53
- }
54
- });
55
- }
56
- const directEditorProps = {
57
- ...options,
58
- state,
59
- plugins,
60
- dispatchTransaction
61
- };
62
- const [_view, setView] = useState(null);
63
- const view = options.view ?? _view;
64
- useLayoutEffect(()=>{
65
- return ()=>{
66
- if (_view) {
67
- _view.destroy();
68
- }
69
- };
70
- }, [
71
- _view
72
- ]);
73
- // This effect runs on every render and handles the view lifecycle.
74
- // eslint-disable-next-line react-hooks/exhaustive-deps
75
- useLayoutEffect(()=>{
76
- if (_view) {
77
- if (_view.dom === mount) {
78
- _view.setProps(directEditorProps);
79
- } else {
80
- setView(null);
81
- }
82
- } else if (mount) {
83
- setView(new EditorView({
84
- mount
85
- }, directEditorProps));
86
- }
87
- });
88
- return useMemo(()=>({
89
- editorState: state,
90
- editorView: view,
91
- registerEventListener,
92
- unregisterEventListener
93
- }), [
94
- state,
95
- _view,
96
- registerEventListener,
97
- unregisterEventListener
98
- ]);
99
- }
@@ -1,16 +0,0 @@
1
- import React, { createContext, useContext } from "react";
2
- import { reactPluginKey } from "../plugins/react.js";
3
- import { useEditorState } from "./useEditorState.js";
4
- const NodePosContext = /*#__PURE__*/ createContext(null);
5
- export function NodePosProvider(param) {
6
- let { nodeKey , children } = param;
7
- const editorState = useEditorState();
8
- const pluginState = reactPluginKey.getState(editorState);
9
- if (!pluginState) return /*#__PURE__*/ React.createElement(React.Fragment, null, children);
10
- return /*#__PURE__*/ React.createElement(NodePosContext.Provider, {
11
- value: pluginState.keyToPos.get(nodeKey) ?? 0
12
- }, children);
13
- }
14
- export function useNodePos() {
15
- return useContext(NodePosContext);
16
- }
@@ -1,53 +0,0 @@
1
- import React, { useCallback, useMemo, useState } from "react";
2
- import { NodeViews } from "../components/NodeViews.js";
3
- import { createReactNodeViewConstructor, findNodeKeyUp } from "../nodeViews/createReactNodeViewConstructor.js";
4
- export function useNodeViews(nodeViews) {
5
- const [portals, setPortals] = useState({});
6
- const registerPortal = useCallback((view, getPos, portal)=>{
7
- const nearestAncestorKey = findNodeKeyUp(view, getPos());
8
- setPortals((oldPortals)=>{
9
- const oldChildPortals = oldPortals[nearestAncestorKey] ?? [];
10
- const newChildPortals = oldChildPortals.concat({
11
- getPos,
12
- portal
13
- });
14
- return {
15
- ...oldPortals,
16
- [nearestAncestorKey]: newChildPortals
17
- };
18
- });
19
- return ()=>{
20
- setPortals((oldPortals)=>{
21
- const oldChildPortals = oldPortals[nearestAncestorKey] ?? [];
22
- const newChildPortals = oldChildPortals.filter((param)=>{
23
- let { portal: p } = param;
24
- return p !== portal;
25
- });
26
- return {
27
- ...oldPortals,
28
- [nearestAncestorKey]: newChildPortals
29
- };
30
- });
31
- };
32
- }, []);
33
- const wrappedNodeViews = useMemo(()=>{
34
- const nodeViewEntries = Object.entries(nodeViews ?? {});
35
- const wrappedNodeViewEntries = nodeViewEntries.map((param)=>{
36
- let [name, constructor] = param;
37
- return [
38
- name,
39
- createReactNodeViewConstructor(constructor, registerPortal)
40
- ];
41
- });
42
- return Object.fromEntries(wrappedNodeViewEntries);
43
- }, [
44
- nodeViews,
45
- registerPortal
46
- ]);
47
- return {
48
- nodeViews: wrappedNodeViews,
49
- nodeViewsComponent: /*#__PURE__*/ React.createElement(NodeViews, {
50
- portals: portals
51
- })
52
- };
53
- }