dn-react-router-toolkit 0.2.3 → 0.2.5

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 (57) hide show
  1. package/dist/auth/client/provider.d.mts +2 -4
  2. package/dist/auth/client/provider.d.ts +2 -4
  3. package/dist/auth/client/provider.js +3 -4
  4. package/dist/auth/client/provider.mjs +3 -4
  5. package/dist/auth/jwt_manager.js +1 -1
  6. package/dist/auth/jwt_manager.mjs +1 -1
  7. package/dist/file/cdn.d.mts +3 -2
  8. package/dist/file/cdn.d.ts +3 -2
  9. package/dist/file/client/drop_file_input.js +36 -10
  10. package/dist/file/client/drop_file_input.mjs +36 -10
  11. package/dist/file/client/file_uploader.js +36 -10
  12. package/dist/file/client/file_uploader.mjs +36 -10
  13. package/dist/file/client/metadata.d.mts +5 -1
  14. package/dist/file/client/metadata.d.ts +5 -1
  15. package/dist/file/client/metadata.js +36 -10
  16. package/dist/file/client/metadata.mjs +36 -10
  17. package/dist/index.d.mts +1 -0
  18. package/dist/index.d.ts +1 -0
  19. package/dist/index.js +7 -0
  20. package/dist/index.mjs +6 -0
  21. package/dist/sleep.d.mts +3 -0
  22. package/dist/sleep.d.ts +3 -0
  23. package/dist/sleep.js +32 -0
  24. package/dist/sleep.mjs +7 -0
  25. package/dist/text_editor/attach_media.d.mts +16 -0
  26. package/dist/text_editor/attach_media.d.ts +16 -0
  27. package/dist/text_editor/attach_media.js +237 -0
  28. package/dist/text_editor/attach_media.mjs +210 -0
  29. package/dist/text_editor/plugins/drag_and_drop.d.mts +13 -0
  30. package/dist/text_editor/plugins/drag_and_drop.d.ts +13 -0
  31. package/dist/text_editor/plugins/drag_and_drop.js +59 -0
  32. package/dist/text_editor/plugins/drag_and_drop.mjs +34 -0
  33. package/dist/text_editor/plugins/keymap.d.mts +5 -0
  34. package/dist/text_editor/plugins/keymap.d.ts +5 -0
  35. package/dist/text_editor/plugins/keymap.js +40 -0
  36. package/dist/text_editor/plugins/keymap.mjs +15 -0
  37. package/dist/text_editor/plugins/placehoder.d.mts +5 -0
  38. package/dist/text_editor/plugins/placehoder.d.ts +5 -0
  39. package/dist/text_editor/plugins/placehoder.js +112 -0
  40. package/dist/text_editor/plugins/placehoder.mjs +87 -0
  41. package/dist/text_editor/plugins/trailing_paragraph.d.mts +5 -0
  42. package/dist/text_editor/plugins/trailing_paragraph.d.ts +5 -0
  43. package/dist/text_editor/plugins/trailing_paragraph.js +46 -0
  44. package/dist/text_editor/plugins/trailing_paragraph.mjs +21 -0
  45. package/dist/text_editor/plugins/upload_placeholder.d.mts +7 -0
  46. package/dist/text_editor/plugins/upload_placeholder.d.ts +7 -0
  47. package/dist/text_editor/plugins/upload_placeholder.js +94 -0
  48. package/dist/text_editor/plugins/upload_placeholder.mjs +68 -0
  49. package/dist/text_editor/schema.d.mts +9 -0
  50. package/dist/text_editor/schema.d.ts +9 -0
  51. package/dist/text_editor/schema.js +354 -0
  52. package/dist/text_editor/schema.mjs +319 -0
  53. package/dist/text_editor/text_editor.d.mts +44 -0
  54. package/dist/text_editor/text_editor.d.ts +44 -0
  55. package/dist/text_editor/text_editor.js +830 -0
  56. package/dist/text_editor/text_editor.mjs +802 -0
  57. package/package.json +14 -2
@@ -0,0 +1,802 @@
1
+ // src/text_editor/text_editor.tsx
2
+ import React2 from "react";
3
+ import { EditorState as EditorState2 } from "prosemirror-state";
4
+ import { EditorView } from "prosemirror-view";
5
+ import { useCallback, useEffect, useMemo, useRef } from "react";
6
+ import { baseKeymap, setBlockType, toggleMark } from "prosemirror-commands";
7
+ import { keymap } from "prosemirror-keymap";
8
+
9
+ // src/text_editor/plugins/drag_and_drop.tsx
10
+ import { Plugin } from "prosemirror-state";
11
+ function dragAndDropPlugin({
12
+ attachMedia
13
+ }) {
14
+ return new Plugin({
15
+ props: {
16
+ handleDOMEvents: {
17
+ drop(view, event) {
18
+ const files = event.dataTransfer?.files;
19
+ if (!files || files.length === 0) {
20
+ return;
21
+ }
22
+ event.preventDefault();
23
+ const pos = view.state.selection.$from.pos || view.posAtCoords({
24
+ left: event.clientX,
25
+ top: event.clientY
26
+ })?.pos || null;
27
+ if (pos === null) {
28
+ return;
29
+ }
30
+ const medias = Array.from(files).filter(
31
+ (file) => file.type.startsWith("image/") || file.type.startsWith("video/")
32
+ );
33
+ attachMedia(view, medias);
34
+ return true;
35
+ }
36
+ }
37
+ }
38
+ });
39
+ }
40
+
41
+ // src/text_editor/plugins/upload_placeholder.tsx
42
+ import { Plugin as Plugin2 } from "prosemirror-state";
43
+ import { Decoration, DecorationSet } from "prosemirror-view";
44
+ var uploadPlaceholderPlugin = new Plugin2({
45
+ state: {
46
+ init() {
47
+ return DecorationSet.empty;
48
+ },
49
+ apply(tr, set) {
50
+ set = set.map(tr.mapping, tr.doc);
51
+ const action = tr.getMeta(this);
52
+ if (action && action.add) {
53
+ const { type, width, height } = action.add;
54
+ const widget = document.createElement("div");
55
+ widget.className = "upload-placeholder";
56
+ widget.style.width = `100%`;
57
+ if (type.startsWith("image/") || type.startsWith("video/")) {
58
+ widget.style.aspectRatio = `${width} / ${height}`;
59
+ widget.style.maxWidth = `${width}px`;
60
+ } else {
61
+ widget.style.height = "80px";
62
+ }
63
+ const progress = document.createElement("div");
64
+ progress.className = "upload-progress";
65
+ widget.appendChild(progress);
66
+ const deco = Decoration.widget(action.add.pos, widget, {
67
+ id: action.add.id
68
+ });
69
+ set = set.add(tr.doc, [deco]);
70
+ } else if (action && action.progress) {
71
+ const found = set.find(
72
+ void 0,
73
+ void 0,
74
+ (spec) => spec.id === action.progress.id
75
+ );
76
+ if (found.length) {
77
+ const widget = found[0].type.toDOM;
78
+ const progress = widget.querySelector(".upload-progress");
79
+ if (progress) {
80
+ progress.innerHTML = `${Math.round(action.progress.progress)}%`;
81
+ }
82
+ }
83
+ } else if (action && action.remove) {
84
+ set = set.remove(
85
+ set.find(void 0, void 0, (spec) => spec.id === action.remove.id)
86
+ );
87
+ }
88
+ return set;
89
+ }
90
+ },
91
+ props: {
92
+ decorations(state) {
93
+ return this.getState(state);
94
+ }
95
+ }
96
+ });
97
+ var findPlaceholder = (state, id) => {
98
+ const decos = uploadPlaceholderPlugin.getState(state);
99
+ if (!decos) {
100
+ return null;
101
+ }
102
+ const found = decos.find(void 0, void 0, (spec) => spec.id === id);
103
+ return found.length ? found[0].from : null;
104
+ };
105
+
106
+ // src/file/client/metadata.ts
107
+ function generateMetadata(blob, {
108
+ uploadBlob
109
+ } = {}) {
110
+ return new Promise((resolve) => {
111
+ if (blob.type.startsWith("image/")) {
112
+ const img = new Image();
113
+ img.src = URL.createObjectURL(blob);
114
+ img.onload = () => {
115
+ resolve({
116
+ width: img.width,
117
+ height: img.height
118
+ });
119
+ };
120
+ img.onerror = () => resolve({});
121
+ return;
122
+ }
123
+ if (blob.type.startsWith("video/")) {
124
+ const video = document.createElement("video");
125
+ video.onloadeddata = () => {
126
+ const canvas = document.createElement("canvas");
127
+ canvas.width = video.videoWidth;
128
+ canvas.height = video.videoHeight;
129
+ const context = canvas.getContext("2d");
130
+ if (!context || !uploadBlob) {
131
+ return resolve({
132
+ width: video.videoWidth,
133
+ height: video.videoHeight
134
+ });
135
+ }
136
+ video.addEventListener("seeked", () => {
137
+ context.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
138
+ canvas.toBlob((blob2) => {
139
+ if (!blob2) {
140
+ return resolve({
141
+ width: video.videoWidth,
142
+ height: video.videoHeight
143
+ });
144
+ }
145
+ uploadBlob(blob2, "poster").then(({ url }) => {
146
+ resolve({
147
+ width: video.videoWidth,
148
+ height: video.videoHeight,
149
+ poster: url
150
+ });
151
+ });
152
+ }, "image/jpeg");
153
+ });
154
+ video.currentTime = 0;
155
+ };
156
+ video.onerror = () => resolve({});
157
+ video.src = URL.createObjectURL(blob);
158
+ return;
159
+ }
160
+ resolve({});
161
+ });
162
+ }
163
+
164
+ // src/file/cdn.ts
165
+ var createCDN = (origin) => {
166
+ return (key, { width } = {}) => {
167
+ return key ? `${origin}/${key}${width ? `?w=${width}` : ""}` : void 0;
168
+ };
169
+ };
170
+
171
+ // src/text_editor/attach_media.tsx
172
+ function createAttachMedia({
173
+ schema,
174
+ cdnOrigin,
175
+ fileUploader
176
+ }) {
177
+ const cdn = createCDN(cdnOrigin);
178
+ const attachEachMedia = async (view, file, pos) => {
179
+ const metadata = await generateMetadata(file, {
180
+ uploadBlob: (blob, type) => fileUploader.uploadBlob(blob, type).then(({ key }) => ({
181
+ url: cdn(key)
182
+ }))
183
+ });
184
+ const id = {};
185
+ view.focus();
186
+ const tr = view.state.tr;
187
+ if (!tr.selection.empty) {
188
+ tr.deleteSelection();
189
+ }
190
+ tr.setMeta(uploadPlaceholderPlugin, {
191
+ add: {
192
+ id,
193
+ pos: pos ?? tr.selection.from,
194
+ type: file.type,
195
+ ...metadata
196
+ }
197
+ });
198
+ view.dispatch(tr);
199
+ const $pos = findPlaceholder(view.state, id);
200
+ if (!$pos) {
201
+ return;
202
+ }
203
+ try {
204
+ const { name, key } = await fileUploader.uploadFile(file);
205
+ const src = cdn(key);
206
+ const tr2 = view.state.tr.setMeta(uploadPlaceholderPlugin, {
207
+ remove: { id }
208
+ });
209
+ const media = (() => {
210
+ if (file.type.startsWith("image/")) {
211
+ return schema.nodes.image.create({
212
+ src,
213
+ alt: name,
214
+ width: metadata.width,
215
+ height: metadata.height
216
+ });
217
+ }
218
+ if (file.type.startsWith("video/")) {
219
+ return schema.nodes.video.create({
220
+ src,
221
+ width: metadata.width,
222
+ height: metadata.height,
223
+ poster: metadata.poster
224
+ });
225
+ }
226
+ })();
227
+ if (!media) {
228
+ return;
229
+ }
230
+ view.dispatch(tr2.replaceWith($pos, $pos, media));
231
+ return media;
232
+ } catch (e) {
233
+ view.dispatch(tr.setMeta(uploadPlaceholderPlugin, { remove: { id } }));
234
+ }
235
+ };
236
+ return async (view, medias, pos) => {
237
+ const result = [];
238
+ for (let i = 0; i < medias.length; i++) {
239
+ const file = medias[i];
240
+ const item = await attachEachMedia(view, file, pos);
241
+ if (item) {
242
+ result.push(item);
243
+ }
244
+ }
245
+ return result;
246
+ };
247
+ }
248
+
249
+ // src/text_editor/plugins/placehoder.tsx
250
+ import { Plugin as Plugin3 } from "prosemirror-state";
251
+ var getFirstChildDescendants = (view) => {
252
+ const nodes = [];
253
+ view.state.doc?.descendants((n) => {
254
+ nodes.push(n);
255
+ });
256
+ return nodes;
257
+ };
258
+ function placeholderPlugin(text) {
259
+ const update = (view) => {
260
+ const decos = uploadPlaceholderPlugin.getState(view.state);
261
+ 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) {
262
+ view.dom.removeAttribute("data-placeholder");
263
+ } else {
264
+ view.dom.setAttribute("data-placeholder", text);
265
+ }
266
+ };
267
+ return new Plugin3({
268
+ view(view) {
269
+ update(view);
270
+ return { update };
271
+ }
272
+ });
273
+ }
274
+
275
+ // src/text_editor/text_editor.tsx
276
+ import {
277
+ DOMSerializer,
278
+ DOMParser
279
+ } from "prosemirror-model";
280
+ import { history } from "prosemirror-history";
281
+
282
+ // src/text_editor/plugins/keymap.tsx
283
+ import { undo, redo } from "prosemirror-history";
284
+ function buildKeymap() {
285
+ const keys = {};
286
+ function bind(key, cmd) {
287
+ keys[key] = cmd;
288
+ }
289
+ bind("Mod-z", undo);
290
+ bind("Shift-Mod-z", redo);
291
+ bind("Mod-y", redo);
292
+ return keys;
293
+ }
294
+
295
+ // src/text_editor/schema.tsx
296
+ import { Schema } from "prosemirror-model";
297
+ import { addListNodes } from "prosemirror-schema-list";
298
+
299
+ // src/file/responsive_image.tsx
300
+ import React from "react";
301
+ var sizes = [
302
+ 64,
303
+ 128,
304
+ 256,
305
+ 320,
306
+ 480,
307
+ 640,
308
+ 768,
309
+ 1080,
310
+ 1200,
311
+ 1536,
312
+ 1920,
313
+ 2560,
314
+ 3840
315
+ ];
316
+ var generateSrc = (cdnOrigin, src, width, height, ratio, image = {}) => {
317
+ const searchParams = new URLSearchParams();
318
+ if (image.width) {
319
+ searchParams.set("w", image.width.toString());
320
+ }
321
+ if (width) {
322
+ searchParams.set("w", width.toString());
323
+ if (ratio) {
324
+ searchParams.set("h", Math.round(width / ratio).toString());
325
+ }
326
+ }
327
+ if (image.height) {
328
+ searchParams.set("h", image.height.toString());
329
+ }
330
+ if (height) {
331
+ searchParams.set("h", height.toString());
332
+ }
333
+ const search = searchParams.toString() ? `?${searchParams.toString()}` : "";
334
+ if (!src.includes(cdnOrigin)) {
335
+ return src;
336
+ }
337
+ return `${encodeURI(decodeURI(src))}${search}`;
338
+ };
339
+ function generateSrcSet(cdnOrigin, image, ratio, props = {}) {
340
+ const src = typeof image === "string" ? image : image.src;
341
+ const isGif = src.endsWith(".gif");
342
+ if (isGif) {
343
+ return void 0;
344
+ }
345
+ if (props.width) {
346
+ return [1, 2, 3].map((scale) => {
347
+ const genWidth = Number(props.width) * scale;
348
+ return `${generateSrc(
349
+ cdnOrigin,
350
+ src,
351
+ genWidth,
352
+ props.height ? Number(props.height) * scale : ratio ? Math.round(genWidth / ratio) : void 0
353
+ )} ${scale}x`;
354
+ }).join(", ");
355
+ }
356
+ return sizes.map(
357
+ (size) => `${generateSrc(cdnOrigin, src, size, void 0, ratio, props)} ${size}w`
358
+ ).join(", ");
359
+ }
360
+
361
+ // src/text_editor/schema.tsx
362
+ function createSchema({ cdnOrigin }) {
363
+ const customSchema = new Schema({
364
+ nodes: {
365
+ doc: { content: "block+" },
366
+ paragraph: {
367
+ attrs: { align: { default: null } },
368
+ content: "inline*",
369
+ group: "block",
370
+ parseDOM: [
371
+ {
372
+ tag: "p",
373
+ getAttrs(dom) {
374
+ return {
375
+ align: dom.style.textAlign || null
376
+ };
377
+ }
378
+ }
379
+ ],
380
+ toDOM(node) {
381
+ return [
382
+ "p",
383
+ {
384
+ style: node.attrs.align ? `text-align: ${node.attrs.align}` : null
385
+ },
386
+ 0
387
+ ];
388
+ }
389
+ },
390
+ text: {
391
+ group: "inline"
392
+ },
393
+ hard_break: {
394
+ inline: true,
395
+ group: "inline",
396
+ selectable: false,
397
+ parseDOM: [{ tag: "br" }],
398
+ toDOM() {
399
+ return ["br"];
400
+ }
401
+ },
402
+ heading: {
403
+ attrs: { level: { default: 1 }, align: { default: null } },
404
+ content: "inline*",
405
+ group: "block",
406
+ defining: true,
407
+ parseDOM: [
408
+ {
409
+ tag: "h1",
410
+ getAttrs(node) {
411
+ return {
412
+ level: 1,
413
+ algin: node.style.textAlign || null
414
+ };
415
+ }
416
+ },
417
+ {
418
+ tag: "h2",
419
+ getAttrs(node) {
420
+ return {
421
+ level: 2,
422
+ algin: node.style.textAlign || null
423
+ };
424
+ }
425
+ },
426
+ {
427
+ tag: "h3",
428
+ getAttrs(node) {
429
+ return {
430
+ level: 3,
431
+ algin: node.style.textAlign || null
432
+ };
433
+ }
434
+ },
435
+ {
436
+ tag: "h4",
437
+ getAttrs(node) {
438
+ return {
439
+ level: 4,
440
+ algin: node.style.textAlign || null
441
+ };
442
+ }
443
+ },
444
+ {
445
+ tag: "h5",
446
+ getAttrs(node) {
447
+ return {
448
+ level: 5,
449
+ algin: node.style.textAlign || null
450
+ };
451
+ }
452
+ },
453
+ {
454
+ tag: "h6",
455
+ getAttrs(node) {
456
+ return {
457
+ level: 6,
458
+ algin: node.style.textAlign || null
459
+ };
460
+ }
461
+ }
462
+ ],
463
+ toDOM(node) {
464
+ return [
465
+ "h" + node.attrs.level,
466
+ {
467
+ id: node.textContent.toLowerCase().replace(/\s+/g, "-"),
468
+ style: node.attrs.align ? `text-align: ${node.attrs.align};` : null
469
+ },
470
+ 0
471
+ ];
472
+ }
473
+ },
474
+ horizontal_rule: {
475
+ group: "block",
476
+ parseDOM: [{ tag: "hr" }],
477
+ toDOM() {
478
+ return ["hr"];
479
+ }
480
+ },
481
+ image: {
482
+ attrs: {
483
+ src: { validate: "string" },
484
+ alt: { default: null, validate: "string|null" },
485
+ title: {
486
+ default: null,
487
+ validate: "string|null"
488
+ },
489
+ width: {
490
+ default: null,
491
+ validate: "number|null"
492
+ },
493
+ height: {
494
+ default: null,
495
+ validate: "number|null"
496
+ }
497
+ },
498
+ inline: true,
499
+ group: "inline",
500
+ draggable: true,
501
+ parseDOM: [
502
+ {
503
+ tag: "img",
504
+ getAttrs(dom) {
505
+ return {
506
+ src: dom.getAttribute("src"),
507
+ title: dom.getAttribute("title"),
508
+ alt: dom.getAttribute("alt"),
509
+ width: dom.getAttribute("width"),
510
+ height: dom.getAttribute("height")
511
+ };
512
+ }
513
+ }
514
+ ],
515
+ toDOM(node) {
516
+ const { src, alt, title, width, height } = node.attrs;
517
+ return [
518
+ "img",
519
+ {
520
+ src,
521
+ alt,
522
+ title,
523
+ width,
524
+ height,
525
+ srcSet: cdnOrigin ? generateSrcSet(cdnOrigin, src) : void 0,
526
+ sizes: cdnOrigin ? "(max-width: 768px) 100vw, 768px" : void 0
527
+ }
528
+ ];
529
+ }
530
+ }
531
+ },
532
+ marks: {
533
+ link: {
534
+ attrs: {
535
+ href: { default: "" },
536
+ title: { default: null }
537
+ },
538
+ inclusive: false,
539
+ parseDOM: [
540
+ {
541
+ tag: "a[href]",
542
+ getAttrs(dom) {
543
+ return {
544
+ href: dom.getAttribute("href"),
545
+ title: dom.getAttribute("title")
546
+ };
547
+ }
548
+ }
549
+ ],
550
+ toDOM(node) {
551
+ const { href, title } = node.attrs;
552
+ const target = "_blank";
553
+ const rel = "noopener noreferrer";
554
+ return ["a", { href, title: title || href, target, rel }, 0];
555
+ }
556
+ },
557
+ bold: {
558
+ parseDOM: [
559
+ { tag: "strong" },
560
+ {
561
+ tag: "b",
562
+ getAttrs: (node) => node.style.fontWeight != "normal" && null
563
+ },
564
+ {
565
+ style: "font-weight=400",
566
+ clearMark: (m) => m.type.name == "strong"
567
+ },
568
+ {
569
+ style: "font-weight",
570
+ getAttrs: (value) => /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null
571
+ }
572
+ ],
573
+ toDOM() {
574
+ return ["strong", 0];
575
+ }
576
+ },
577
+ italic: {
578
+ parseDOM: [
579
+ { tag: "em" },
580
+ { tag: "i" },
581
+ { style: "font-style=italic" },
582
+ {
583
+ style: "font-style=normal",
584
+ clearMark: (m) => m.type.name == "em"
585
+ }
586
+ ],
587
+ toDOM() {
588
+ return ["em", 0];
589
+ }
590
+ },
591
+ underline: {
592
+ parseDOM: [
593
+ { tag: "u" },
594
+ {
595
+ style: "text-decoration",
596
+ getAttrs: (value) => value === "underline" && null
597
+ }
598
+ ],
599
+ toDOM() {
600
+ return ["u", 0];
601
+ }
602
+ }
603
+ }
604
+ });
605
+ const prosemirrorSchema = new Schema({
606
+ nodes: addListNodes(customSchema.spec.nodes, "paragraph block*", "block"),
607
+ marks: customSchema.spec.marks
608
+ });
609
+ return prosemirrorSchema;
610
+ }
611
+
612
+ // src/cn.ts
613
+ function cn(...classes) {
614
+ return classes.filter(Boolean).join(" ").trim();
615
+ }
616
+
617
+ // src/text_editor/text_editor.tsx
618
+ function createTextEditor({
619
+ fileUploader,
620
+ cdnOrigin
621
+ } = {}) {
622
+ const schema = createSchema({ cdnOrigin });
623
+ const prosemirrorParser = DOMParser.fromSchema(schema);
624
+ const prosemirrorSerializer = DOMSerializer.fromSchema(schema);
625
+ const attachMediaComponent = cdnOrigin && fileUploader ? createAttachMedia({
626
+ schema,
627
+ cdnOrigin,
628
+ fileUploader
629
+ }) : null;
630
+ function useTextEditor() {
631
+ const view = useRef(null);
632
+ const observers = useMemo(() => [], []);
633
+ const Component = useCallback(
634
+ function Component2({
635
+ name,
636
+ placeholder,
637
+ className,
638
+ defaultValue,
639
+ onClick,
640
+ onHTMLChanged,
641
+ editor,
642
+ state,
643
+ ...props
644
+ }) {
645
+ const ref = useRef(null);
646
+ useEffect(() => {
647
+ const container = ref.current;
648
+ if (!container) {
649
+ return;
650
+ }
651
+ const wrapper = document.createElement("div");
652
+ wrapper.innerHTML = defaultValue || "";
653
+ const editorView = new EditorView(container, {
654
+ ...editor,
655
+ attributes: (state2) => {
656
+ const propsAttributes = (() => {
657
+ if (typeof editor?.attributes === "function") {
658
+ return editor.attributes(state2);
659
+ }
660
+ return editor?.attributes;
661
+ })();
662
+ return {
663
+ ...propsAttributes,
664
+ class: cn(propsAttributes?.class, "outline-none"),
665
+ spellcheck: propsAttributes?.spellcheck || "false"
666
+ };
667
+ },
668
+ state: EditorState2.create({
669
+ schema: state?.schema || schema,
670
+ doc: state?.doc || prosemirrorParser.parse(wrapper),
671
+ plugins: [
672
+ ...state?.plugins || [],
673
+ history(),
674
+ keymap(baseKeymap),
675
+ keymap(buildKeymap()),
676
+ uploadPlaceholderPlugin,
677
+ attachMediaComponent ? dragAndDropPlugin({ attachMedia: attachMediaComponent }) : null,
678
+ placeholder && placeholderPlugin(placeholder)
679
+ ].filter((e) => !!e)
680
+ }),
681
+ dispatchTransaction(tr) {
682
+ let result;
683
+ if (editor?.dispatchTransaction) {
684
+ result = editor.dispatchTransaction(tr);
685
+ } else {
686
+ editorView.updateState(editorView.state.apply(tr));
687
+ }
688
+ observers.forEach((observer) => {
689
+ observer(editorView);
690
+ });
691
+ if (tr.docChanged) {
692
+ const html = serialize();
693
+ onHTMLChanged?.(html);
694
+ if (inputRef.current) {
695
+ inputRef.current.value = html;
696
+ }
697
+ }
698
+ return result;
699
+ }
700
+ });
701
+ view.current = editorView;
702
+ return () => {
703
+ view.current = null;
704
+ editorView.destroy();
705
+ container.innerHTML = "";
706
+ };
707
+ }, [editor, state, defaultValue, placeholder, onHTMLChanged]);
708
+ const inputRef = useRef(null);
709
+ return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(
710
+ "div",
711
+ {
712
+ ref,
713
+ className: cn("cursor-text", className),
714
+ onClick: (e) => {
715
+ e.stopPropagation();
716
+ view?.current?.focus();
717
+ onClick?.(e);
718
+ },
719
+ ...props
720
+ }
721
+ ), name && /* @__PURE__ */ React2.createElement("input", { ref: inputRef, type: "hidden", name }));
722
+ },
723
+ [observers]
724
+ );
725
+ const commands = {
726
+ async attachMedia(files) {
727
+ if (view.current && attachMediaComponent) {
728
+ return attachMediaComponent(view.current, files);
729
+ }
730
+ },
731
+ toggleMark(type, attrs, options) {
732
+ const markType = schema.marks[type];
733
+ if (view.current && markType) {
734
+ const command = toggleMark(markType, attrs, options);
735
+ command(view.current.state, view.current.dispatch);
736
+ }
737
+ },
738
+ setBlockType(type, attrs) {
739
+ const blockType = schema.nodes[type];
740
+ if (view.current && blockType) {
741
+ const command = setBlockType(blockType, attrs);
742
+ command(view.current.state, view.current.dispatch);
743
+ }
744
+ },
745
+ insertNode(type, attrs, content, marks) {
746
+ const nodeType = schema.nodes[type];
747
+ if (view.current && nodeType) {
748
+ const node = nodeType.create(attrs, content, marks);
749
+ view.current.dispatch(
750
+ view.current.state.tr.replaceSelectionWith(node)
751
+ );
752
+ }
753
+ },
754
+ setHTML(html) {
755
+ if (!view.current) {
756
+ return;
757
+ }
758
+ const wrap = document.createElement("div");
759
+ wrap.innerHTML = html;
760
+ const doc = prosemirrorParser.parse(wrap);
761
+ const tr = view.current.state.tr.replaceWith(
762
+ 0,
763
+ view.current.state.doc.content.size,
764
+ doc.content
765
+ );
766
+ view.current.dispatch(tr);
767
+ }
768
+ };
769
+ const serialize = () => {
770
+ if (!view.current) {
771
+ return "";
772
+ }
773
+ const fragment = prosemirrorSerializer.serializeFragment(
774
+ view.current.state.doc.content
775
+ );
776
+ const container = document.createElement("div");
777
+ container.appendChild(fragment);
778
+ return container.innerHTML;
779
+ };
780
+ const getTextContent = () => {
781
+ if (!view.current) {
782
+ return "";
783
+ }
784
+ return view.current.state.doc.textContent;
785
+ };
786
+ return {
787
+ schema,
788
+ view,
789
+ commands,
790
+ Component,
791
+ serialize,
792
+ getTextContent
793
+ };
794
+ }
795
+ return {
796
+ schema,
797
+ useTextEditor
798
+ };
799
+ }
800
+ export {
801
+ createTextEditor as default
802
+ };