@tiptap/react 2.0.0-beta.209 → 2.0.0-beta.210
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.
- package/dist/index.cjs +437 -0
- package/dist/index.d.ts +101 -0
- package/dist/index.js +437 -0
- package/package.json +33 -11
- package/src/EditorContent.tsx +1 -0
- package/src/ReactNodeViewRenderer.tsx +17 -13
- package/dist/packages/react/src/BubbleMenu.d.ts +0 -10
- package/dist/packages/react/src/Editor.d.ts +0 -12
- package/dist/packages/react/src/EditorContent.d.ts +0 -23
- package/dist/packages/react/src/FloatingMenu.d.ts +0 -9
- package/dist/packages/react/src/NodeViewContent.d.ts +0 -6
- package/dist/packages/react/src/NodeViewWrapper.d.ts +0 -6
- package/dist/packages/react/src/ReactNodeViewRenderer.d.ts +0 -15
- package/dist/packages/react/src/ReactRenderer.d.ts +0 -24
- package/dist/packages/react/src/index.d.ts +0 -10
- package/dist/packages/react/src/useEditor.d.ts +0 -4
- package/dist/packages/react/src/useReactNodeView.d.ts +0 -7
- package/dist/tiptap-react.cjs +0 -405
- package/dist/tiptap-react.cjs.map +0 -1
- package/dist/tiptap-react.esm.js +0 -382
- package/dist/tiptap-react.esm.js.map +0 -1
- package/dist/tiptap-react.umd.js +0 -405
- package/dist/tiptap-react.umd.js.map +0 -1
package/dist/index.js
ADDED
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
// src/BubbleMenu.tsx
|
|
2
|
+
import { BubbleMenuPlugin } from "@tiptap/extension-bubble-menu";
|
|
3
|
+
import React, { useEffect, useState } from "react";
|
|
4
|
+
var BubbleMenu = (props) => {
|
|
5
|
+
const [element, setElement] = useState(null);
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
if (!element) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
if (props.editor.isDestroyed) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const {
|
|
14
|
+
pluginKey = "bubbleMenu",
|
|
15
|
+
editor,
|
|
16
|
+
tippyOptions = {},
|
|
17
|
+
updateDelay,
|
|
18
|
+
shouldShow = null
|
|
19
|
+
} = props;
|
|
20
|
+
const plugin = BubbleMenuPlugin({
|
|
21
|
+
updateDelay,
|
|
22
|
+
editor,
|
|
23
|
+
element,
|
|
24
|
+
pluginKey,
|
|
25
|
+
shouldShow,
|
|
26
|
+
tippyOptions
|
|
27
|
+
});
|
|
28
|
+
editor.registerPlugin(plugin);
|
|
29
|
+
return () => editor.unregisterPlugin(pluginKey);
|
|
30
|
+
}, [props.editor, element]);
|
|
31
|
+
return /* @__PURE__ */ React.createElement("div", { ref: setElement, className: props.className, style: { visibility: "hidden" } }, props.children);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// src/Editor.ts
|
|
35
|
+
import { Editor as CoreEditor } from "@tiptap/core";
|
|
36
|
+
var Editor = class extends CoreEditor {
|
|
37
|
+
constructor() {
|
|
38
|
+
super(...arguments);
|
|
39
|
+
this.contentComponent = null;
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// src/EditorContent.tsx
|
|
44
|
+
import React2 from "react";
|
|
45
|
+
import ReactDOM, { flushSync } from "react-dom";
|
|
46
|
+
var Portals = ({ renderers }) => {
|
|
47
|
+
return /* @__PURE__ */ React2.createElement(React2.Fragment, null, Object.entries(renderers).map(([key, renderer]) => {
|
|
48
|
+
return ReactDOM.createPortal(
|
|
49
|
+
renderer.reactElement,
|
|
50
|
+
renderer.element,
|
|
51
|
+
key
|
|
52
|
+
);
|
|
53
|
+
}));
|
|
54
|
+
};
|
|
55
|
+
var PureEditorContent = class extends React2.Component {
|
|
56
|
+
constructor(props) {
|
|
57
|
+
super(props);
|
|
58
|
+
this.editorContentRef = React2.createRef();
|
|
59
|
+
this.initialized = false;
|
|
60
|
+
this.state = {
|
|
61
|
+
renderers: {}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
componentDidMount() {
|
|
65
|
+
this.init();
|
|
66
|
+
}
|
|
67
|
+
componentDidUpdate() {
|
|
68
|
+
this.init();
|
|
69
|
+
}
|
|
70
|
+
init() {
|
|
71
|
+
const { editor } = this.props;
|
|
72
|
+
if (editor && editor.options.element) {
|
|
73
|
+
if (editor.contentComponent) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const element = this.editorContentRef.current;
|
|
77
|
+
element.append(...editor.options.element.childNodes);
|
|
78
|
+
editor.setOptions({
|
|
79
|
+
element
|
|
80
|
+
});
|
|
81
|
+
editor.contentComponent = this;
|
|
82
|
+
editor.createNodeViews();
|
|
83
|
+
this.initialized = true;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
maybeFlushSync(fn) {
|
|
87
|
+
if (this.initialized) {
|
|
88
|
+
flushSync(fn);
|
|
89
|
+
} else {
|
|
90
|
+
fn();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
setRenderer(id, renderer) {
|
|
94
|
+
this.maybeFlushSync(() => {
|
|
95
|
+
this.setState(({ renderers }) => ({
|
|
96
|
+
renderers: {
|
|
97
|
+
...renderers,
|
|
98
|
+
[id]: renderer
|
|
99
|
+
}
|
|
100
|
+
}));
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
removeRenderer(id) {
|
|
104
|
+
this.maybeFlushSync(() => {
|
|
105
|
+
this.setState(({ renderers }) => {
|
|
106
|
+
const nextRenderers = { ...renderers };
|
|
107
|
+
delete nextRenderers[id];
|
|
108
|
+
return { renderers: nextRenderers };
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
componentWillUnmount() {
|
|
113
|
+
const { editor } = this.props;
|
|
114
|
+
if (!editor) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
if (!editor.isDestroyed) {
|
|
118
|
+
editor.view.setProps({
|
|
119
|
+
nodeViews: {}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
editor.contentComponent = null;
|
|
123
|
+
if (!editor.options.element.firstChild) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
const newElement = document.createElement("div");
|
|
127
|
+
newElement.append(...editor.options.element.childNodes);
|
|
128
|
+
editor.setOptions({
|
|
129
|
+
element: newElement
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
render() {
|
|
133
|
+
const { editor, ...rest } = this.props;
|
|
134
|
+
return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement("div", { ref: this.editorContentRef, ...rest }), /* @__PURE__ */ React2.createElement(Portals, { renderers: this.state.renderers }));
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
var EditorContent = React2.memo(PureEditorContent);
|
|
138
|
+
|
|
139
|
+
// src/FloatingMenu.tsx
|
|
140
|
+
import { FloatingMenuPlugin } from "@tiptap/extension-floating-menu";
|
|
141
|
+
import React3, {
|
|
142
|
+
useEffect as useEffect2,
|
|
143
|
+
useState as useState2
|
|
144
|
+
} from "react";
|
|
145
|
+
var FloatingMenu = (props) => {
|
|
146
|
+
const [element, setElement] = useState2(null);
|
|
147
|
+
useEffect2(() => {
|
|
148
|
+
if (!element) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
if (props.editor.isDestroyed) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
const {
|
|
155
|
+
pluginKey = "floatingMenu",
|
|
156
|
+
editor,
|
|
157
|
+
tippyOptions = {},
|
|
158
|
+
shouldShow = null
|
|
159
|
+
} = props;
|
|
160
|
+
const plugin = FloatingMenuPlugin({
|
|
161
|
+
pluginKey,
|
|
162
|
+
editor,
|
|
163
|
+
element,
|
|
164
|
+
tippyOptions,
|
|
165
|
+
shouldShow
|
|
166
|
+
});
|
|
167
|
+
editor.registerPlugin(plugin);
|
|
168
|
+
return () => editor.unregisterPlugin(pluginKey);
|
|
169
|
+
}, [
|
|
170
|
+
props.editor,
|
|
171
|
+
element
|
|
172
|
+
]);
|
|
173
|
+
return /* @__PURE__ */ React3.createElement("div", { ref: setElement, className: props.className, style: { visibility: "hidden" } }, props.children);
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
// src/NodeViewContent.tsx
|
|
177
|
+
import React4 from "react";
|
|
178
|
+
|
|
179
|
+
// src/useReactNodeView.ts
|
|
180
|
+
import { createContext, useContext } from "react";
|
|
181
|
+
var ReactNodeViewContext = createContext({
|
|
182
|
+
onDragStart: void 0
|
|
183
|
+
});
|
|
184
|
+
var useReactNodeView = () => useContext(ReactNodeViewContext);
|
|
185
|
+
|
|
186
|
+
// src/NodeViewContent.tsx
|
|
187
|
+
var NodeViewContent = (props) => {
|
|
188
|
+
const Tag = props.as || "div";
|
|
189
|
+
const { nodeViewContentRef } = useReactNodeView();
|
|
190
|
+
return /* @__PURE__ */ React4.createElement(
|
|
191
|
+
Tag,
|
|
192
|
+
{
|
|
193
|
+
...props,
|
|
194
|
+
ref: nodeViewContentRef,
|
|
195
|
+
"data-node-view-content": "",
|
|
196
|
+
style: {
|
|
197
|
+
whiteSpace: "pre-wrap",
|
|
198
|
+
...props.style
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
);
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
// src/NodeViewWrapper.tsx
|
|
205
|
+
import React5 from "react";
|
|
206
|
+
var NodeViewWrapper = React5.forwardRef((props, ref) => {
|
|
207
|
+
const { onDragStart } = useReactNodeView();
|
|
208
|
+
const Tag = props.as || "div";
|
|
209
|
+
return /* @__PURE__ */ React5.createElement(
|
|
210
|
+
Tag,
|
|
211
|
+
{
|
|
212
|
+
...props,
|
|
213
|
+
ref,
|
|
214
|
+
"data-node-view-wrapper": "",
|
|
215
|
+
onDragStart,
|
|
216
|
+
style: {
|
|
217
|
+
whiteSpace: "normal",
|
|
218
|
+
...props.style
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
);
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
// src/ReactNodeViewRenderer.tsx
|
|
225
|
+
import {
|
|
226
|
+
NodeView
|
|
227
|
+
} from "@tiptap/core";
|
|
228
|
+
import React7 from "react";
|
|
229
|
+
|
|
230
|
+
// src/ReactRenderer.tsx
|
|
231
|
+
import React6 from "react";
|
|
232
|
+
function isClassComponent(Component) {
|
|
233
|
+
return !!(typeof Component === "function" && Component.prototype && Component.prototype.isReactComponent);
|
|
234
|
+
}
|
|
235
|
+
function isForwardRefComponent(Component) {
|
|
236
|
+
var _a;
|
|
237
|
+
return !!(typeof Component === "object" && ((_a = Component.$$typeof) == null ? void 0 : _a.toString()) === "Symbol(react.forward_ref)");
|
|
238
|
+
}
|
|
239
|
+
var ReactRenderer = class {
|
|
240
|
+
constructor(component, {
|
|
241
|
+
editor,
|
|
242
|
+
props = {},
|
|
243
|
+
as = "div",
|
|
244
|
+
className = ""
|
|
245
|
+
}) {
|
|
246
|
+
this.ref = null;
|
|
247
|
+
this.id = Math.floor(Math.random() * 4294967295).toString();
|
|
248
|
+
this.component = component;
|
|
249
|
+
this.editor = editor;
|
|
250
|
+
this.props = props;
|
|
251
|
+
this.element = document.createElement(as);
|
|
252
|
+
this.element.classList.add("react-renderer");
|
|
253
|
+
if (className) {
|
|
254
|
+
this.element.classList.add(...className.split(" "));
|
|
255
|
+
}
|
|
256
|
+
this.render();
|
|
257
|
+
}
|
|
258
|
+
render() {
|
|
259
|
+
var _a, _b;
|
|
260
|
+
const Component = this.component;
|
|
261
|
+
const props = this.props;
|
|
262
|
+
if (isClassComponent(Component) || isForwardRefComponent(Component)) {
|
|
263
|
+
props.ref = (ref) => {
|
|
264
|
+
this.ref = ref;
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
this.reactElement = /* @__PURE__ */ React6.createElement(Component, { ...props });
|
|
268
|
+
(_b = (_a = this.editor) == null ? void 0 : _a.contentComponent) == null ? void 0 : _b.setRenderer(this.id, this);
|
|
269
|
+
}
|
|
270
|
+
updateProps(props = {}) {
|
|
271
|
+
this.props = {
|
|
272
|
+
...this.props,
|
|
273
|
+
...props
|
|
274
|
+
};
|
|
275
|
+
this.render();
|
|
276
|
+
}
|
|
277
|
+
destroy() {
|
|
278
|
+
var _a, _b;
|
|
279
|
+
(_b = (_a = this.editor) == null ? void 0 : _a.contentComponent) == null ? void 0 : _b.removeRenderer(this.id);
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
// src/ReactNodeViewRenderer.tsx
|
|
284
|
+
var ReactNodeView = class extends NodeView {
|
|
285
|
+
mount() {
|
|
286
|
+
const props = {
|
|
287
|
+
editor: this.editor,
|
|
288
|
+
node: this.node,
|
|
289
|
+
decorations: this.decorations,
|
|
290
|
+
selected: false,
|
|
291
|
+
extension: this.extension,
|
|
292
|
+
getPos: () => this.getPos(),
|
|
293
|
+
updateAttributes: (attributes = {}) => this.updateAttributes(attributes),
|
|
294
|
+
deleteNode: () => this.deleteNode()
|
|
295
|
+
};
|
|
296
|
+
if (!this.component.displayName) {
|
|
297
|
+
const capitalizeFirstChar = (string) => {
|
|
298
|
+
return string.charAt(0).toUpperCase() + string.substring(1);
|
|
299
|
+
};
|
|
300
|
+
this.component.displayName = capitalizeFirstChar(this.extension.name);
|
|
301
|
+
}
|
|
302
|
+
const ReactNodeViewProvider = (componentProps) => {
|
|
303
|
+
const Component = this.component;
|
|
304
|
+
const onDragStart = this.onDragStart.bind(this);
|
|
305
|
+
const nodeViewContentRef = (element) => {
|
|
306
|
+
if (element && this.contentDOMElement && element.firstChild !== this.contentDOMElement) {
|
|
307
|
+
element.appendChild(this.contentDOMElement);
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
return /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(ReactNodeViewContext.Provider, { value: { onDragStart, nodeViewContentRef } }, /* @__PURE__ */ React7.createElement(Component, { ...componentProps })));
|
|
311
|
+
};
|
|
312
|
+
ReactNodeViewProvider.displayName = "ReactNodeView";
|
|
313
|
+
this.contentDOMElement = this.node.isLeaf ? null : document.createElement(this.node.isInline ? "span" : "div");
|
|
314
|
+
if (this.contentDOMElement) {
|
|
315
|
+
this.contentDOMElement.style.whiteSpace = "inherit";
|
|
316
|
+
}
|
|
317
|
+
let as = this.node.isInline ? "span" : "div";
|
|
318
|
+
if (this.options.as) {
|
|
319
|
+
as = this.options.as;
|
|
320
|
+
}
|
|
321
|
+
const { className = "" } = this.options;
|
|
322
|
+
this.renderer = new ReactRenderer(ReactNodeViewProvider, {
|
|
323
|
+
editor: this.editor,
|
|
324
|
+
props,
|
|
325
|
+
as,
|
|
326
|
+
className: `node-${this.node.type.name} ${className}`.trim()
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
get dom() {
|
|
330
|
+
var _a;
|
|
331
|
+
if (this.renderer.element.firstElementChild && !((_a = this.renderer.element.firstElementChild) == null ? void 0 : _a.hasAttribute("data-node-view-wrapper"))) {
|
|
332
|
+
throw Error("Please use the NodeViewWrapper component for your node view.");
|
|
333
|
+
}
|
|
334
|
+
return this.renderer.element;
|
|
335
|
+
}
|
|
336
|
+
get contentDOM() {
|
|
337
|
+
if (this.node.isLeaf) {
|
|
338
|
+
return null;
|
|
339
|
+
}
|
|
340
|
+
return this.contentDOMElement;
|
|
341
|
+
}
|
|
342
|
+
update(node, decorations) {
|
|
343
|
+
const updateProps = (props) => {
|
|
344
|
+
this.renderer.updateProps(props);
|
|
345
|
+
};
|
|
346
|
+
if (node.type !== this.node.type) {
|
|
347
|
+
return false;
|
|
348
|
+
}
|
|
349
|
+
if (typeof this.options.update === "function") {
|
|
350
|
+
const oldNode = this.node;
|
|
351
|
+
const oldDecorations = this.decorations;
|
|
352
|
+
this.node = node;
|
|
353
|
+
this.decorations = decorations;
|
|
354
|
+
return this.options.update({
|
|
355
|
+
oldNode,
|
|
356
|
+
oldDecorations,
|
|
357
|
+
newNode: node,
|
|
358
|
+
newDecorations: decorations,
|
|
359
|
+
updateProps: () => updateProps({ node, decorations })
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
if (node === this.node && this.decorations === decorations) {
|
|
363
|
+
return true;
|
|
364
|
+
}
|
|
365
|
+
this.node = node;
|
|
366
|
+
this.decorations = decorations;
|
|
367
|
+
updateProps({ node, decorations });
|
|
368
|
+
return true;
|
|
369
|
+
}
|
|
370
|
+
selectNode() {
|
|
371
|
+
this.renderer.updateProps({
|
|
372
|
+
selected: true
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
deselectNode() {
|
|
376
|
+
this.renderer.updateProps({
|
|
377
|
+
selected: false
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
destroy() {
|
|
381
|
+
this.renderer.destroy();
|
|
382
|
+
this.contentDOMElement = null;
|
|
383
|
+
}
|
|
384
|
+
};
|
|
385
|
+
function ReactNodeViewRenderer(component, options) {
|
|
386
|
+
return (props) => {
|
|
387
|
+
if (!props.editor.contentComponent) {
|
|
388
|
+
return {};
|
|
389
|
+
}
|
|
390
|
+
return new ReactNodeView(component, props, options);
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// src/useEditor.ts
|
|
395
|
+
import { useEffect as useEffect3, useState as useState3 } from "react";
|
|
396
|
+
function useForceUpdate() {
|
|
397
|
+
const [, setValue] = useState3(0);
|
|
398
|
+
return () => setValue((value) => value + 1);
|
|
399
|
+
}
|
|
400
|
+
var useEditor = (options = {}, deps = []) => {
|
|
401
|
+
const [editor, setEditor] = useState3(null);
|
|
402
|
+
const forceUpdate = useForceUpdate();
|
|
403
|
+
useEffect3(() => {
|
|
404
|
+
let isMounted = true;
|
|
405
|
+
const instance = new Editor(options);
|
|
406
|
+
setEditor(instance);
|
|
407
|
+
instance.on("transaction", () => {
|
|
408
|
+
requestAnimationFrame(() => {
|
|
409
|
+
requestAnimationFrame(() => {
|
|
410
|
+
if (isMounted) {
|
|
411
|
+
forceUpdate();
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
});
|
|
415
|
+
});
|
|
416
|
+
return () => {
|
|
417
|
+
instance.destroy();
|
|
418
|
+
isMounted = false;
|
|
419
|
+
};
|
|
420
|
+
}, deps);
|
|
421
|
+
return editor;
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
// src/index.ts
|
|
425
|
+
export * from "@tiptap/core";
|
|
426
|
+
export {
|
|
427
|
+
BubbleMenu,
|
|
428
|
+
Editor,
|
|
429
|
+
EditorContent,
|
|
430
|
+
FloatingMenu,
|
|
431
|
+
NodeViewContent,
|
|
432
|
+
NodeViewWrapper,
|
|
433
|
+
PureEditorContent,
|
|
434
|
+
ReactNodeViewRenderer,
|
|
435
|
+
ReactRenderer,
|
|
436
|
+
useEditor
|
|
437
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tiptap/react",
|
|
3
3
|
"description": "React components for tiptap",
|
|
4
|
-
"version": "2.0.0-beta.
|
|
4
|
+
"version": "2.0.0-beta.210",
|
|
5
5
|
"homepage": "https://tiptap.dev",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"tiptap",
|
|
@@ -12,35 +12,57 @@
|
|
|
12
12
|
"type": "github",
|
|
13
13
|
"url": "https://github.com/sponsors/ueberdosis"
|
|
14
14
|
},
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"import": "./dist/index.js",
|
|
19
|
+
"require": "./dist/index.cjs"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"main": "dist/index.cjs",
|
|
23
|
+
"module": "dist/index.js",
|
|
24
|
+
"types": "dist/index.d.ts",
|
|
25
|
+
"type": "module",
|
|
19
26
|
"files": [
|
|
20
27
|
"src",
|
|
21
28
|
"dist"
|
|
22
29
|
],
|
|
23
30
|
"devDependencies": {
|
|
24
|
-
"@tiptap/core": "^2.0.0-beta.
|
|
31
|
+
"@tiptap/core": "^2.0.0-beta.210",
|
|
32
|
+
"@tiptap/pm": "^2.0.0-beta.210",
|
|
25
33
|
"@types/react": "^18.0.1",
|
|
26
34
|
"@types/react-dom": "^18.0.0",
|
|
27
35
|
"react": "^18.0.0",
|
|
28
36
|
"react-dom": "^18.0.0"
|
|
29
37
|
},
|
|
30
38
|
"peerDependencies": {
|
|
31
|
-
"@tiptap/core": "^2.0.0-beta.
|
|
39
|
+
"@tiptap/core": "^2.0.0-beta.209",
|
|
40
|
+
"@tiptap/pm": "^2.0.0-beta.209",
|
|
32
41
|
"react": "^17.0.0 || ^18.0.0",
|
|
33
42
|
"react-dom": "^17.0.0 || ^18.0.0"
|
|
34
43
|
},
|
|
35
44
|
"dependencies": {
|
|
36
|
-
"@tiptap/extension-bubble-menu": "^2.0.0-beta.
|
|
37
|
-
"@tiptap/extension-floating-menu": "^2.0.0-beta.
|
|
38
|
-
"prosemirror-view": "^1.28.2"
|
|
45
|
+
"@tiptap/extension-bubble-menu": "^2.0.0-beta.210",
|
|
46
|
+
"@tiptap/extension-floating-menu": "^2.0.0-beta.210"
|
|
39
47
|
},
|
|
40
48
|
"repository": {
|
|
41
49
|
"type": "git",
|
|
42
50
|
"url": "https://github.com/ueberdosis/tiptap",
|
|
43
51
|
"directory": "packages/react"
|
|
44
52
|
},
|
|
45
|
-
"sideEffects": false
|
|
53
|
+
"sideEffects": false,
|
|
54
|
+
"scripts": {
|
|
55
|
+
"build": "tsup"
|
|
56
|
+
},
|
|
57
|
+
"tsup": {
|
|
58
|
+
"entry": [
|
|
59
|
+
"src/index.ts"
|
|
60
|
+
],
|
|
61
|
+
"dts": true,
|
|
62
|
+
"splitting": true,
|
|
63
|
+
"format": [
|
|
64
|
+
"esm",
|
|
65
|
+
"cjs"
|
|
66
|
+
]
|
|
67
|
+
}
|
|
46
68
|
}
|
package/src/EditorContent.tsx
CHANGED
|
@@ -5,8 +5,8 @@ import {
|
|
|
5
5
|
NodeViewRendererOptions,
|
|
6
6
|
NodeViewRendererProps,
|
|
7
7
|
} from '@tiptap/core'
|
|
8
|
-
import { Node as ProseMirrorNode } from '
|
|
9
|
-
import { Decoration, NodeView as ProseMirrorNodeView } from '
|
|
8
|
+
import { Node as ProseMirrorNode } from '@tiptap/pm/model'
|
|
9
|
+
import { Decoration, NodeView as ProseMirrorNodeView } from '@tiptap/pm/view'
|
|
10
10
|
import React from 'react'
|
|
11
11
|
|
|
12
12
|
import { Editor } from './Editor'
|
|
@@ -16,15 +16,15 @@ import { ReactNodeViewContext, ReactNodeViewContextProps } from './useReactNodeV
|
|
|
16
16
|
export interface ReactNodeViewRendererOptions extends NodeViewRendererOptions {
|
|
17
17
|
update:
|
|
18
18
|
| ((props: {
|
|
19
|
-
oldNode: ProseMirrorNode
|
|
20
|
-
oldDecorations: Decoration[]
|
|
21
|
-
newNode: ProseMirrorNode
|
|
22
|
-
newDecorations: Decoration[]
|
|
23
|
-
updateProps: () => void
|
|
19
|
+
oldNode: ProseMirrorNode
|
|
20
|
+
oldDecorations: Decoration[]
|
|
21
|
+
newNode: ProseMirrorNode
|
|
22
|
+
newDecorations: Decoration[]
|
|
23
|
+
updateProps: () => void
|
|
24
24
|
}) => boolean)
|
|
25
|
-
| null
|
|
26
|
-
as?: string
|
|
27
|
-
className?: string
|
|
25
|
+
| null
|
|
26
|
+
as?: string
|
|
27
|
+
className?: string
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
class ReactNodeView extends NodeView<
|
|
@@ -66,9 +66,13 @@ class ReactNodeView extends NodeView<
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
return (
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
<>
|
|
70
|
+
{/* @ts-ignore */}
|
|
71
|
+
<ReactNodeViewContext.Provider value={{ onDragStart, nodeViewContentRef }}>
|
|
72
|
+
{/* @ts-ignore */}
|
|
73
|
+
<Component {...componentProps} />
|
|
74
|
+
</ReactNodeViewContext.Provider>
|
|
75
|
+
</>
|
|
72
76
|
)
|
|
73
77
|
}
|
|
74
78
|
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { BubbleMenuPluginProps } from '@tiptap/extension-bubble-menu';
|
|
2
|
-
import React from 'react';
|
|
3
|
-
declare type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
|
|
4
|
-
export declare type BubbleMenuProps = Omit<Optional<BubbleMenuPluginProps, 'pluginKey'>, 'element'> & {
|
|
5
|
-
className?: string;
|
|
6
|
-
children: React.ReactNode;
|
|
7
|
-
updateDelay?: number;
|
|
8
|
-
};
|
|
9
|
-
export declare const BubbleMenu: (props: BubbleMenuProps) => JSX.Element;
|
|
10
|
-
export {};
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { Editor as CoreEditor } from '@tiptap/core';
|
|
2
|
-
import React from 'react';
|
|
3
|
-
import { EditorContentProps, EditorContentState } from './EditorContent';
|
|
4
|
-
import { ReactRenderer } from './ReactRenderer';
|
|
5
|
-
declare type ContentComponent = React.Component<EditorContentProps, EditorContentState> & {
|
|
6
|
-
setRenderer(id: string, renderer: ReactRenderer): void;
|
|
7
|
-
removeRenderer(id: string): void;
|
|
8
|
-
};
|
|
9
|
-
export declare class Editor extends CoreEditor {
|
|
10
|
-
contentComponent: ContentComponent | null;
|
|
11
|
-
}
|
|
12
|
-
export {};
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import React, { HTMLProps } from 'react';
|
|
2
|
-
import { Editor } from './Editor';
|
|
3
|
-
import { ReactRenderer } from './ReactRenderer';
|
|
4
|
-
export interface EditorContentProps extends HTMLProps<HTMLDivElement> {
|
|
5
|
-
editor: Editor | null;
|
|
6
|
-
}
|
|
7
|
-
export interface EditorContentState {
|
|
8
|
-
renderers: Record<string, ReactRenderer>;
|
|
9
|
-
}
|
|
10
|
-
export declare class PureEditorContent extends React.Component<EditorContentProps, EditorContentState> {
|
|
11
|
-
editorContentRef: React.RefObject<any>;
|
|
12
|
-
initialized: boolean;
|
|
13
|
-
constructor(props: EditorContentProps);
|
|
14
|
-
componentDidMount(): void;
|
|
15
|
-
componentDidUpdate(): void;
|
|
16
|
-
init(): void;
|
|
17
|
-
maybeFlushSync(fn: () => void): void;
|
|
18
|
-
setRenderer(id: string, renderer: ReactRenderer): void;
|
|
19
|
-
removeRenderer(id: string): void;
|
|
20
|
-
componentWillUnmount(): void;
|
|
21
|
-
render(): JSX.Element;
|
|
22
|
-
}
|
|
23
|
-
export declare const EditorContent: React.MemoExoticComponent<typeof PureEditorContent>;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { FloatingMenuPluginProps } from '@tiptap/extension-floating-menu';
|
|
2
|
-
import React from 'react';
|
|
3
|
-
declare type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
|
|
4
|
-
export declare type FloatingMenuProps = Omit<Optional<FloatingMenuPluginProps, 'pluginKey'>, 'element'> & {
|
|
5
|
-
className?: string;
|
|
6
|
-
children: React.ReactNode;
|
|
7
|
-
};
|
|
8
|
-
export declare const FloatingMenu: (props: FloatingMenuProps) => JSX.Element;
|
|
9
|
-
export {};
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { NodeViewRenderer, NodeViewRendererOptions } from '@tiptap/core';
|
|
2
|
-
import { Node as ProseMirrorNode } from 'prosemirror-model';
|
|
3
|
-
import { Decoration } from 'prosemirror-view';
|
|
4
|
-
export interface ReactNodeViewRendererOptions extends NodeViewRendererOptions {
|
|
5
|
-
update: ((props: {
|
|
6
|
-
oldNode: ProseMirrorNode;
|
|
7
|
-
oldDecorations: Decoration[];
|
|
8
|
-
newNode: ProseMirrorNode;
|
|
9
|
-
newDecorations: Decoration[];
|
|
10
|
-
updateProps: () => void;
|
|
11
|
-
}) => boolean) | null;
|
|
12
|
-
as?: string;
|
|
13
|
-
className?: string;
|
|
14
|
-
}
|
|
15
|
-
export declare function ReactNodeViewRenderer(component: any, options?: Partial<ReactNodeViewRendererOptions>): NodeViewRenderer;
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { Editor } from '@tiptap/core';
|
|
2
|
-
import React from 'react';
|
|
3
|
-
import { Editor as ExtendedEditor } from './Editor';
|
|
4
|
-
export interface ReactRendererOptions {
|
|
5
|
-
editor: Editor;
|
|
6
|
-
props?: Record<string, any>;
|
|
7
|
-
as?: string;
|
|
8
|
-
className?: string;
|
|
9
|
-
}
|
|
10
|
-
declare type ComponentType<R, P> = React.ComponentClass<P> | React.FunctionComponent<P> | React.ForwardRefExoticComponent<React.PropsWithoutRef<P> & React.RefAttributes<R>>;
|
|
11
|
-
export declare class ReactRenderer<R = unknown, P = unknown> {
|
|
12
|
-
id: string;
|
|
13
|
-
editor: ExtendedEditor;
|
|
14
|
-
component: any;
|
|
15
|
-
element: Element;
|
|
16
|
-
props: Record<string, any>;
|
|
17
|
-
reactElement: React.ReactNode;
|
|
18
|
-
ref: R | null;
|
|
19
|
-
constructor(component: ComponentType<R, P>, { editor, props, as, className, }: ReactRendererOptions);
|
|
20
|
-
render(): void;
|
|
21
|
-
updateProps(props?: Record<string, any>): void;
|
|
22
|
-
destroy(): void;
|
|
23
|
-
}
|
|
24
|
-
export {};
|