dn-react-text-editor 0.1.1 → 0.2.0

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 (55) hide show
  1. package/README.md +14 -214
  2. package/dist/attach_file.d.mts +20 -18
  3. package/dist/attach_file.d.ts +20 -18
  4. package/dist/attach_file.js +18 -9
  5. package/dist/attach_file.mjs +18 -9
  6. package/dist/base64_file_uploader.d.mts +6 -0
  7. package/dist/base64_file_uploader.d.ts +6 -0
  8. package/dist/{plugins/trailing_paragraph.js → base64_file_uploader.js} +19 -22
  9. package/dist/base64_file_uploader.mjs +18 -0
  10. package/dist/commands.d.mts +23 -0
  11. package/dist/commands.d.ts +23 -0
  12. package/dist/commands.js +110 -0
  13. package/dist/commands.mjs +75 -0
  14. package/dist/create_text_editor.d.mts +28 -0
  15. package/dist/create_text_editor.d.ts +28 -0
  16. package/dist/create_text_editor.js +1082 -0
  17. package/dist/create_text_editor.mjs +1053 -0
  18. package/dist/html.d.mts +8 -0
  19. package/dist/html.d.ts +8 -0
  20. package/dist/html.js +136 -0
  21. package/dist/html.mjs +98 -0
  22. package/dist/index.d.mts +7 -4
  23. package/dist/index.d.ts +7 -4
  24. package/dist/index.js +790 -380
  25. package/dist/index.mjs +789 -377
  26. package/dist/input.d.mts +21 -0
  27. package/dist/input.d.ts +21 -0
  28. package/dist/input.js +70 -0
  29. package/dist/input.mjs +37 -0
  30. package/dist/plugins/drag_and_drop.d.mts +1 -1
  31. package/dist/plugins/drag_and_drop.d.ts +1 -1
  32. package/dist/plugins/drag_and_drop.js +3 -0
  33. package/dist/plugins/drag_and_drop.mjs +3 -0
  34. package/dist/plugins/highlighter.d.mts +6 -0
  35. package/dist/plugins/highlighter.d.ts +6 -0
  36. package/dist/plugins/highlighter.js +105 -0
  37. package/dist/plugins/highlighter.mjs +69 -0
  38. package/dist/plugins/keymap.js +17 -0
  39. package/dist/plugins/keymap.mjs +17 -0
  40. package/dist/schema.d.mts +2 -2
  41. package/dist/schema.d.ts +2 -2
  42. package/dist/schema.js +255 -14
  43. package/dist/schema.mjs +245 -14
  44. package/dist/text_editor_controller.d.mts +46 -0
  45. package/dist/text_editor_controller.d.ts +46 -0
  46. package/dist/text_editor_controller.js +503 -0
  47. package/dist/text_editor_controller.mjs +470 -0
  48. package/package.json +3 -1
  49. package/dist/plugins/trailing_paragraph.d.mts +0 -5
  50. package/dist/plugins/trailing_paragraph.d.ts +0 -5
  51. package/dist/plugins/trailing_paragraph.mjs +0 -21
  52. package/dist/text_editor.d.mts +0 -37
  53. package/dist/text_editor.d.ts +0 -37
  54. package/dist/text_editor.js +0 -720
  55. package/dist/text_editor.mjs +0 -687
@@ -0,0 +1,470 @@
1
+ // src/text_editor_controller.tsx
2
+ import {
3
+ EditorState as EditorState2
4
+ } from "prosemirror-state";
5
+ import { EditorView as EditorView3 } from "prosemirror-view";
6
+ import * as commands2 from "prosemirror-commands";
7
+ import { keymap } from "prosemirror-keymap";
8
+
9
+ // src/plugins/drag_and_drop.tsx
10
+ import { Plugin } from "prosemirror-state";
11
+ function dragAndDropPlugin({ attachFile }) {
12
+ return new Plugin({
13
+ props: {
14
+ handleDOMEvents: {
15
+ drop(view, event) {
16
+ if (!attachFile) {
17
+ return;
18
+ }
19
+ const files = event.dataTransfer?.files;
20
+ if (!files || files.length === 0) {
21
+ return;
22
+ }
23
+ event.preventDefault();
24
+ const pos = view.state.selection.$from.pos || view.posAtCoords({
25
+ left: event.clientX,
26
+ top: event.clientY
27
+ })?.pos || null;
28
+ if (pos === null) {
29
+ return;
30
+ }
31
+ const medias = Array.from(files).filter(
32
+ (file) => file.type.startsWith("image/") || file.type.startsWith("video/")
33
+ );
34
+ attachFile(view, medias);
35
+ return true;
36
+ }
37
+ }
38
+ }
39
+ });
40
+ }
41
+
42
+ // src/plugins/upload_placeholder.tsx
43
+ import { Plugin as Plugin2 } from "prosemirror-state";
44
+ import { Decoration, DecorationSet } from "prosemirror-view";
45
+ var uploadPlaceholderPlugin = new Plugin2({
46
+ state: {
47
+ init() {
48
+ return DecorationSet.empty;
49
+ },
50
+ apply(tr, set) {
51
+ set = set.map(tr.mapping, tr.doc);
52
+ const action = tr.getMeta(this);
53
+ if (action && action.add) {
54
+ const { type, width, height } = action.add;
55
+ const widget = document.createElement("div");
56
+ widget.className = "upload-placeholder";
57
+ widget.style.width = `100%`;
58
+ if (type.startsWith("image/") || type.startsWith("video/")) {
59
+ widget.style.aspectRatio = `${width} / ${height}`;
60
+ widget.style.maxWidth = `${width}px`;
61
+ } else {
62
+ widget.style.height = "80px";
63
+ }
64
+ const progress = document.createElement("div");
65
+ progress.className = "upload-progress";
66
+ widget.appendChild(progress);
67
+ const deco = Decoration.widget(action.add.pos, widget, {
68
+ id: action.add.id
69
+ });
70
+ set = set.add(tr.doc, [deco]);
71
+ } else if (action && action.progress) {
72
+ const found = set.find(
73
+ void 0,
74
+ void 0,
75
+ (spec) => spec.id === action.progress.id
76
+ );
77
+ if (found.length) {
78
+ const widget = found[0].type.toDOM;
79
+ const progress = widget.querySelector(".upload-progress");
80
+ if (progress) {
81
+ progress.innerHTML = `${Math.round(action.progress.progress)}%`;
82
+ }
83
+ }
84
+ } else if (action && action.remove) {
85
+ set = set.remove(
86
+ set.find(void 0, void 0, (spec) => spec.id === action.remove.id)
87
+ );
88
+ }
89
+ return set;
90
+ }
91
+ },
92
+ props: {
93
+ decorations(state) {
94
+ return this.getState(state);
95
+ }
96
+ }
97
+ });
98
+ var findPlaceholder = (state, id) => {
99
+ const decos = uploadPlaceholderPlugin.getState(state);
100
+ if (!decos) {
101
+ return null;
102
+ }
103
+ const found = decos.find(void 0, void 0, (spec) => spec.id === id);
104
+ return found.length ? found[0].from : null;
105
+ };
106
+
107
+ // src/plugins/placehoder.tsx
108
+ import "prosemirror-model";
109
+ import { Plugin as Plugin3 } from "prosemirror-state";
110
+ import "prosemirror-view";
111
+ var getFirstChildDescendants = (view) => {
112
+ const nodes = [];
113
+ view.state.doc?.descendants((n) => {
114
+ nodes.push(n);
115
+ });
116
+ return nodes;
117
+ };
118
+ function placeholderPlugin(text) {
119
+ const update = (view) => {
120
+ const decos = uploadPlaceholderPlugin.getState(view.state);
121
+ if (decos && decos.find().length > 0 || view.state.doc.content.content.some((e) => e.type.name !== "paragraph") || view.state.doc.childCount > 1 || getFirstChildDescendants(view).length > 1 || view.state.doc.textContent) {
122
+ view.dom.removeAttribute("data-placeholder");
123
+ } else {
124
+ view.dom.setAttribute("data-placeholder", text);
125
+ }
126
+ };
127
+ return new Plugin3({
128
+ view(view) {
129
+ update(view);
130
+ return { update };
131
+ }
132
+ });
133
+ }
134
+
135
+ // src/text_editor_controller.tsx
136
+ import { history } from "prosemirror-history";
137
+
138
+ // src/plugins/keymap.tsx
139
+ import { TextSelection } from "prosemirror-state";
140
+ import { undo, redo } from "prosemirror-history";
141
+ import { chainCommands, splitBlockAs } from "prosemirror-commands";
142
+ import { splitListItem } from "prosemirror-schema-list";
143
+ function buildKeymap(schema) {
144
+ const keys = {};
145
+ function bind(key, cmd) {
146
+ keys[key] = cmd;
147
+ }
148
+ bind("Mod-z", undo);
149
+ bind("Shift-Mod-z", redo);
150
+ bind("Mod-y", redo);
151
+ const li = schema.nodes.list_item;
152
+ bind(
153
+ "Enter",
154
+ chainCommands(splitListItem(li), (state, dispatch) => {
155
+ const { $head } = state.selection;
156
+ if ($head.parent.type === state.schema.nodes.paragraph) {
157
+ splitBlockAs((n) => {
158
+ return {
159
+ type: n.type,
160
+ attrs: n.attrs
161
+ };
162
+ })(state, dispatch);
163
+ return true;
164
+ }
165
+ return false;
166
+ })
167
+ );
168
+ bind("ArrowDown", (state, dispatch) => {
169
+ const doc = state.doc;
170
+ const lastNode = doc.lastChild;
171
+ if (lastNode && lastNode.type.name !== "paragraph") {
172
+ const paragraphType = state.schema.nodes.paragraph;
173
+ let tr = state.tr;
174
+ const endPos = doc.content.size;
175
+ tr = tr.insert(endPos, paragraphType.create());
176
+ tr = tr.setSelection(TextSelection.create(tr.doc, tr.doc.content.size));
177
+ if (dispatch) {
178
+ dispatch(tr);
179
+ }
180
+ return true;
181
+ }
182
+ return false;
183
+ });
184
+ return keys;
185
+ }
186
+
187
+ // src/cn.ts
188
+ function cn(...classes) {
189
+ return classes.filter(Boolean).join(" ").trim();
190
+ }
191
+
192
+ // src/attach_file.tsx
193
+ import "prosemirror-view";
194
+
195
+ // src/base64_file_uploader.ts
196
+ var base64FileUploader = async (file) => {
197
+ const base64 = await new Promise((resolve, reject) => {
198
+ const reader = new FileReader();
199
+ reader.onload = () => {
200
+ resolve(reader.result);
201
+ };
202
+ reader.onerror = reject;
203
+ reader.readAsDataURL(file);
204
+ });
205
+ return {
206
+ src: base64,
207
+ alt: file.name
208
+ };
209
+ };
210
+
211
+ // src/attach_file.tsx
212
+ function createAttachFile({
213
+ schema,
214
+ generateMetadata,
215
+ uploadFile = base64FileUploader
216
+ }) {
217
+ const attachEachFile = async (view, file, pos) => {
218
+ const metadata = generateMetadata ? await generateMetadata(file) : {};
219
+ const id = {};
220
+ view.focus();
221
+ const tr = view.state.tr;
222
+ if (!tr.selection.empty) {
223
+ tr.deleteSelection();
224
+ }
225
+ tr.setMeta(uploadPlaceholderPlugin, {
226
+ add: {
227
+ id,
228
+ pos: pos ?? tr.selection.from,
229
+ type: file.type,
230
+ ...metadata
231
+ }
232
+ });
233
+ view.dispatch(tr);
234
+ const $pos = findPlaceholder(view.state, id);
235
+ if (!$pos) {
236
+ return;
237
+ }
238
+ try {
239
+ const { src, alt } = await uploadFile(file);
240
+ const tr2 = view.state.tr.setMeta(uploadPlaceholderPlugin, {
241
+ remove: { id }
242
+ });
243
+ const createNode = () => {
244
+ if (file.type.startsWith("image/")) {
245
+ return schema.nodes.image.create({
246
+ src,
247
+ alt,
248
+ width: metadata.width,
249
+ height: metadata.height
250
+ });
251
+ }
252
+ if (file.type.startsWith("video/")) {
253
+ return schema.nodes.video.create({
254
+ src,
255
+ width: metadata.width,
256
+ height: metadata.height,
257
+ poster: metadata.poster
258
+ });
259
+ }
260
+ };
261
+ const node = createNode();
262
+ if (!node) {
263
+ return;
264
+ }
265
+ view.dispatch(tr2.replaceWith($pos, $pos, node));
266
+ } catch (e) {
267
+ view.dispatch(tr.setMeta(uploadPlaceholderPlugin, { remove: { id } }));
268
+ }
269
+ };
270
+ return async (view, files, pos) => {
271
+ for (let i = 0; i < files.length; i++) {
272
+ const file = files[i];
273
+ await attachEachFile(view, file, pos);
274
+ }
275
+ };
276
+ }
277
+
278
+ // src/commands.tsx
279
+ import * as commands from "prosemirror-commands";
280
+ import * as schemaList from "prosemirror-schema-list";
281
+ var createCommands = (schema, view, options = {}) => {
282
+ {
283
+ const isBlockTypeActive = (node, attrs, excludes = []) => {
284
+ const state = view.state;
285
+ const ranges = state.selection.ranges;
286
+ let active = false;
287
+ for (const range of ranges) {
288
+ const { $from, $to } = range;
289
+ state.doc.nodesBetween($from.pos, $to.pos, (n) => {
290
+ if (active) {
291
+ return true;
292
+ }
293
+ if (n.type !== node || excludes.includes(n.type)) {
294
+ return;
295
+ }
296
+ if (!attrs || Object.keys(attrs).every((key) => n.attrs[key] === attrs[key])) {
297
+ active = true;
298
+ }
299
+ });
300
+ return active;
301
+ }
302
+ };
303
+ const setBlockType2 = (node, attrs) => {
304
+ view.focus();
305
+ const nodeType = schema.nodes[node];
306
+ const command = commands.setBlockType(nodeType, attrs);
307
+ command(view.state, view.dispatch);
308
+ };
309
+ const toggleBlockType = (node, attrs) => {
310
+ view.focus();
311
+ const nodeType = schema.nodes[node];
312
+ const command = commands.setBlockType(nodeType, attrs);
313
+ if (isBlockTypeActive(nodeType, attrs)) {
314
+ command(view.state, view.dispatch);
315
+ }
316
+ };
317
+ const toggleMark2 = (mark, attrs, options2) => {
318
+ view.focus();
319
+ const markType = schema.marks[mark];
320
+ const command = commands.toggleMark(markType, attrs, options2);
321
+ command(view.state, view.dispatch);
322
+ };
323
+ const wrapInList2 = (listType, attrs) => {
324
+ view.focus();
325
+ const nodeType = schema.nodes[listType];
326
+ const command = schemaList.wrapInList(nodeType, attrs);
327
+ command(view.state, view.dispatch);
328
+ };
329
+ const clear = () => {
330
+ const tr = view.state.tr.replaceWith(
331
+ 0,
332
+ view.state.doc.content.size,
333
+ schema.nodes.doc.createAndFill()
334
+ );
335
+ view.dispatch(tr);
336
+ };
337
+ return {
338
+ isBlockTypeActive,
339
+ setBlockType: setBlockType2,
340
+ toggleBlockType,
341
+ toggleMark: toggleMark2,
342
+ wrapInList: wrapInList2,
343
+ clear,
344
+ attachFile: (files) => {
345
+ options.attachFile?.(view, files);
346
+ }
347
+ };
348
+ }
349
+ };
350
+
351
+ // src/text_editor_controller.tsx
352
+ import { DOMParser, DOMSerializer } from "prosemirror-model";
353
+ import { Subject } from "rxjs";
354
+ function createTextEditorController(container, schema, options, {
355
+ mode,
356
+ state,
357
+ editor,
358
+ defaultValue,
359
+ updateDelay = 500,
360
+ placeholder
361
+ }) {
362
+ const subject = new Subject();
363
+ const prosemirrorParser = DOMParser.fromSchema(schema);
364
+ const prosemirrorSerializer = DOMSerializer.fromSchema(schema);
365
+ const wrapper = document.createElement("div");
366
+ const toInnerHTML = (value) => {
367
+ if (mode === "html") {
368
+ return value;
369
+ }
370
+ return value.split("\n").map((line) => `<p>${line}</p>`).join("");
371
+ };
372
+ wrapper.innerHTML = toInnerHTML(defaultValue ? String(defaultValue) : "");
373
+ const attachFile = createAttachFile({
374
+ schema,
375
+ generateMetadata: options.attachFile?.generateMetadata,
376
+ uploadFile: options.attachFile?.uploadFile
377
+ });
378
+ const view = new EditorView3(container, {
379
+ ...editor,
380
+ attributes: (state2) => {
381
+ const propsAttributes = (() => {
382
+ if (typeof editor?.attributes === "function") {
383
+ return editor.attributes(state2);
384
+ }
385
+ return editor?.attributes;
386
+ })();
387
+ return {
388
+ ...propsAttributes,
389
+ class: cn(options?.className, propsAttributes?.class),
390
+ spellcheck: propsAttributes?.spellcheck || "false",
391
+ style: options.style || "width: 100%; height: inherit; outline: none;"
392
+ };
393
+ },
394
+ state: EditorState2.create({
395
+ ...state,
396
+ schema: state?.schema || schema,
397
+ doc: state?.doc || prosemirrorParser.parse(wrapper),
398
+ plugins: [
399
+ ...state?.plugins || [],
400
+ history({
401
+ newGroupDelay: updateDelay
402
+ }),
403
+ keymap(buildKeymap(schema)),
404
+ keymap(commands2.baseKeymap),
405
+ uploadPlaceholderPlugin,
406
+ dragAndDropPlugin({
407
+ attachFile
408
+ }),
409
+ placeholder && placeholderPlugin(placeholder)
410
+ ].filter((e) => !!e)
411
+ }),
412
+ dispatchTransaction(tr) {
413
+ let result;
414
+ if (editor?.dispatchTransaction) {
415
+ result = editor.dispatchTransaction(tr);
416
+ } else {
417
+ view.updateState(view.state.apply(tr));
418
+ }
419
+ subject.next(tr);
420
+ return result;
421
+ }
422
+ });
423
+ function setValue(value) {
424
+ const wrap = document.createElement("div");
425
+ wrap.innerHTML = toInnerHTML(value);
426
+ const doc = prosemirrorParser.parse(wrap);
427
+ const tr = view.state.tr.replaceWith(
428
+ 0,
429
+ view.state.doc.content.size,
430
+ doc.content
431
+ );
432
+ view.dispatch(tr);
433
+ }
434
+ function toHTML() {
435
+ const fragment = prosemirrorSerializer.serializeFragment(
436
+ view.state.doc.content
437
+ );
438
+ const container2 = document.createElement("div");
439
+ container2.appendChild(fragment);
440
+ return container2.innerHTML;
441
+ }
442
+ function toTextContent() {
443
+ const state2 = view.state;
444
+ return state2.doc.textBetween(0, state2.doc.content.size, "\n");
445
+ }
446
+ const textEditorCommands = createCommands(schema, view, {
447
+ attachFile
448
+ });
449
+ const textEditorController = {
450
+ schema,
451
+ view,
452
+ subject,
453
+ set value(value) {
454
+ setValue(value);
455
+ },
456
+ get value() {
457
+ switch (mode) {
458
+ case "text":
459
+ return toTextContent();
460
+ default:
461
+ return toHTML();
462
+ }
463
+ },
464
+ commands: textEditorCommands
465
+ };
466
+ return textEditorController;
467
+ }
468
+ export {
469
+ createTextEditorController
470
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dn-react-text-editor",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "types": "./dist/index.d.ts",
5
5
  "main": "./dist/index.mjs",
6
6
  "module": "./dist/index.js",
@@ -44,6 +44,8 @@
44
44
  "react-dom": "^19"
45
45
  },
46
46
  "dependencies": {
47
+ "highlight.js": "^11.11.1",
48
+ "html-entities": "^2.6.0",
47
49
  "prosemirror-commands": "^1.7.1",
48
50
  "prosemirror-history": "^1.5.0",
49
51
  "prosemirror-keymap": "^1.2.3",
@@ -1,5 +0,0 @@
1
- import { Plugin } from 'prosemirror-state';
2
-
3
- declare function trailingParagraph(): Plugin<any>;
4
-
5
- export { trailingParagraph };
@@ -1,5 +0,0 @@
1
- import { Plugin } from 'prosemirror-state';
2
-
3
- declare function trailingParagraph(): Plugin<any>;
4
-
5
- export { trailingParagraph };
@@ -1,21 +0,0 @@
1
- // src/plugins/trailing_paragraph.tsx
2
- import { Plugin } from "prosemirror-state";
3
- function trailingParagraph() {
4
- return new Plugin({
5
- appendTransaction(transactions, oldState, newState) {
6
- const doc = newState.doc;
7
- const lastNode = doc.lastChild;
8
- if (lastNode && lastNode.type.name !== "paragraph") {
9
- const paragraphType = newState.schema.nodes.paragraph;
10
- const tr = newState.tr;
11
- const endPos = doc.content.size;
12
- tr.insert(endPos, paragraphType.create());
13
- return tr;
14
- }
15
- return null;
16
- }
17
- });
18
- }
19
- export {
20
- trailingParagraph
21
- };
@@ -1,37 +0,0 @@
1
- import { createAttachFile, AttachFile } from './attach_file.mjs';
2
- import * as orderedmap from 'orderedmap';
3
- import * as prosemirror_model from 'prosemirror-model';
4
- import React, { DetailedHTMLProps, InputHTMLAttributes, Ref } from 'react';
5
- import { Transaction, EditorStateConfig } from 'prosemirror-state';
6
- import { EditorView, DirectEditorProps } from 'prosemirror-view';
7
- import { createSchema } from './schema.mjs';
8
- import { Subject } from 'rxjs';
9
-
10
- type TextEditorController = {
11
- schema: ReturnType<typeof createSchema>;
12
- view: EditorView;
13
- subject: Subject<Transaction>;
14
- set value(value: string);
15
- get value(): string;
16
- clear: () => void;
17
- };
18
- type TextEditorProps = Omit<DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "ref"> & {
19
- ref?: Ref<TextEditorController>;
20
- state?: Partial<EditorStateConfig>;
21
- editor?: Partial<DirectEditorProps>;
22
- mode?: "html" | "text";
23
- updateDelay?: number;
24
- container?: string;
25
- };
26
- declare function createTextEditor(options?: {
27
- attachFile?: {
28
- generateMetadata: Parameters<typeof createAttachFile>[0]["generateMetadata"];
29
- uploadFile: Parameters<typeof createAttachFile>[0]["uploadFile"];
30
- };
31
- }): {
32
- schema: prosemirror_model.Schema<keyof orderedmap.default<prosemirror_model.NodeSpec>, keyof orderedmap.default<prosemirror_model.MarkSpec>>;
33
- attachFile: AttachFile;
34
- Component: ({ ref, state, editor, mode, container, autoFocus, name, placeholder, className, defaultValue, onClick, onChange, updateDelay, ...props }?: TextEditorProps) => React.JSX.Element;
35
- };
36
-
37
- export { type TextEditorController, type TextEditorProps, createTextEditor };
@@ -1,37 +0,0 @@
1
- import { createAttachFile, AttachFile } from './attach_file.js';
2
- import * as orderedmap from 'orderedmap';
3
- import * as prosemirror_model from 'prosemirror-model';
4
- import React, { DetailedHTMLProps, InputHTMLAttributes, Ref } from 'react';
5
- import { Transaction, EditorStateConfig } from 'prosemirror-state';
6
- import { EditorView, DirectEditorProps } from 'prosemirror-view';
7
- import { createSchema } from './schema.js';
8
- import { Subject } from 'rxjs';
9
-
10
- type TextEditorController = {
11
- schema: ReturnType<typeof createSchema>;
12
- view: EditorView;
13
- subject: Subject<Transaction>;
14
- set value(value: string);
15
- get value(): string;
16
- clear: () => void;
17
- };
18
- type TextEditorProps = Omit<DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "ref"> & {
19
- ref?: Ref<TextEditorController>;
20
- state?: Partial<EditorStateConfig>;
21
- editor?: Partial<DirectEditorProps>;
22
- mode?: "html" | "text";
23
- updateDelay?: number;
24
- container?: string;
25
- };
26
- declare function createTextEditor(options?: {
27
- attachFile?: {
28
- generateMetadata: Parameters<typeof createAttachFile>[0]["generateMetadata"];
29
- uploadFile: Parameters<typeof createAttachFile>[0]["uploadFile"];
30
- };
31
- }): {
32
- schema: prosemirror_model.Schema<keyof orderedmap.default<prosemirror_model.NodeSpec>, keyof orderedmap.default<prosemirror_model.MarkSpec>>;
33
- attachFile: AttachFile;
34
- Component: ({ ref, state, editor, mode, container, autoFocus, name, placeholder, className, defaultValue, onClick, onChange, updateDelay, ...props }?: TextEditorProps) => React.JSX.Element;
35
- };
36
-
37
- export { type TextEditorController, type TextEditorProps, createTextEditor };