@frontlit/text-editor 0.1.0-alpha.2 → 0.1.0-alpha.4
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/docs.d.ts +1 -1
- package/dist/docs.js +621 -35
- package/dist/docs.js.map +1 -1
- package/dist/index.js +683 -18
- package/dist/index.js.map +1 -1
- package/dist/prose.css +305 -0
- package/dist/renderer/index.js +218 -14
- package/dist/renderer/index.js.map +1 -1
- package/dist/renderer/islands/docs-tabs.js +57 -0
- package/dist/renderer/islands/docs-tabs.js.map +1 -0
- package/dist/styles.css +299 -0
- package/package.json +7 -2
package/dist/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import React5, { createContext, useState, useRef, useMemo, useEffect, useCallback, useContext } from 'react';
|
|
3
|
-
import { Node, getSchema, generateText } from '@tiptap/core';
|
|
4
|
-
import { useEditor, EditorContent } from '@tiptap/react';
|
|
2
|
+
import React5, { createContext, useState, useRef, useMemo, useEffect, useCallback, useContext, useId } from 'react';
|
|
3
|
+
import { Node, Extension, getSchema, generateText } from '@tiptap/core';
|
|
4
|
+
import { useEditor, EditorContent, ReactNodeViewRenderer, NodeViewWrapper, NodeViewContent } from '@tiptap/react';
|
|
5
5
|
import StarterKit from '@tiptap/starter-kit';
|
|
6
6
|
import Placeholder from '@tiptap/extension-placeholder';
|
|
7
7
|
import Link from '@tiptap/extension-link';
|
|
8
8
|
import { TableRow, Table, TableCell, TableHeader } from '@tiptap/extension-table';
|
|
9
9
|
import Image from '@tiptap/extension-image';
|
|
10
10
|
import Dropcursor from '@tiptap/extension-dropcursor';
|
|
11
|
-
import Gapcursor from '@tiptap/extension-gapcursor';
|
|
11
|
+
import Gapcursor$1 from '@tiptap/extension-gapcursor';
|
|
12
12
|
import CodeBlockLowlight from '@tiptap/extension-code-block-lowlight';
|
|
13
13
|
import Heading from '@tiptap/extension-heading';
|
|
14
14
|
import Highlight from '@tiptap/extension-highlight';
|
|
@@ -18,12 +18,17 @@ import typescript from 'highlight.js/lib/languages/typescript';
|
|
|
18
18
|
import json from 'highlight.js/lib/languages/json';
|
|
19
19
|
import css from 'highlight.js/lib/languages/css';
|
|
20
20
|
import xml from 'highlight.js/lib/languages/xml';
|
|
21
|
-
import
|
|
21
|
+
import Code from '@tiptap/extension-code';
|
|
22
|
+
import { Undo2, Redo2, ChevronDown, Bold, Italic, Underline, Code as Code$1, Link as Link$1, List, ListOrdered, Quote, Plus, Minus, Table as Table$1, Image as Image$1, Trash2, Strikethrough, X, Check, OctagonAlert, CircleAlert, Info, Lightbulb, StickyNote, Copy } from 'lucide-react';
|
|
22
23
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
24
|
+
import { Fragment as Fragment$1 } from '@tiptap/pm/model';
|
|
23
25
|
import { BubbleMenuPlugin } from '@tiptap/extension-bubble-menu';
|
|
24
26
|
import { clsx } from 'clsx';
|
|
25
27
|
import { twMerge } from 'tailwind-merge';
|
|
28
|
+
import CodeBlock from '@tiptap/extension-code-block';
|
|
29
|
+
import { Gapcursor, TrailingNode } from '@tiptap/extensions';
|
|
26
30
|
import { renderToReactElement } from '@tiptap/static-renderer';
|
|
31
|
+
import { DynamicIcon } from 'lucide-react/dynamic';
|
|
27
32
|
|
|
28
33
|
// src/editor.tsx
|
|
29
34
|
|
|
@@ -58,6 +63,92 @@ var CodeMirrorNode = Node.create({
|
|
|
58
63
|
return ["pre", HTMLAttributes, 0];
|
|
59
64
|
}
|
|
60
65
|
});
|
|
66
|
+
var CALLOUT_TYPES = ["note", "tip", "info", "warning", "danger"];
|
|
67
|
+
function attr(name, fallback = null) {
|
|
68
|
+
return {
|
|
69
|
+
[name]: {
|
|
70
|
+
default: fallback,
|
|
71
|
+
parseHTML: (element) => {
|
|
72
|
+
const value = element.getAttribute(`data-${name}`);
|
|
73
|
+
if (value === null) return fallback;
|
|
74
|
+
try {
|
|
75
|
+
return JSON.parse(value);
|
|
76
|
+
} catch {
|
|
77
|
+
return fallback;
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
renderHTML: (attributes) => attributes[name] === null || attributes[name] === void 0 ? {} : { [`data-${name}`]: JSON.stringify(attributes[name]) }
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
function block(name, spec) {
|
|
85
|
+
const tag = `div[data-docs-block="${name}"]`;
|
|
86
|
+
return Node.create({
|
|
87
|
+
name,
|
|
88
|
+
group: spec.group,
|
|
89
|
+
content: spec.content,
|
|
90
|
+
atom: spec.atom,
|
|
91
|
+
defining: true,
|
|
92
|
+
isolating: true,
|
|
93
|
+
addAttributes() {
|
|
94
|
+
return Object.assign(
|
|
95
|
+
{},
|
|
96
|
+
...Object.entries(spec.attrs ?? {}).map(([key, value]) => attr(key, value))
|
|
97
|
+
);
|
|
98
|
+
},
|
|
99
|
+
parseHTML() {
|
|
100
|
+
return [{ tag }];
|
|
101
|
+
},
|
|
102
|
+
renderHTML({ HTMLAttributes }) {
|
|
103
|
+
return spec.atom ? ["div", { ...HTMLAttributes, "data-docs-block": name }] : ["div", { ...HTMLAttributes, "data-docs-block": name }, 0];
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
var DocsCode = Code.extend({ excludes: "" });
|
|
108
|
+
function createDocsBlockExtensions() {
|
|
109
|
+
return [
|
|
110
|
+
DocsCode,
|
|
111
|
+
block("callout", {
|
|
112
|
+
group: "block",
|
|
113
|
+
content: "block+",
|
|
114
|
+
attrs: { type: null, title: null }
|
|
115
|
+
}),
|
|
116
|
+
block("tabs", { group: "block", content: "tab+" }),
|
|
117
|
+
block("tab", { content: "block+", attrs: { label: "" } }),
|
|
118
|
+
block("steps", { group: "block", content: "step+" }),
|
|
119
|
+
block("step", { content: "block+" }),
|
|
120
|
+
block("cards", { group: "block", content: "card+" }),
|
|
121
|
+
block("card", {
|
|
122
|
+
content: "block*",
|
|
123
|
+
attrs: { title: "", href: null, icon: null }
|
|
124
|
+
}),
|
|
125
|
+
block("accordions", {
|
|
126
|
+
group: "block",
|
|
127
|
+
content: "accordion+",
|
|
128
|
+
attrs: { type: null }
|
|
129
|
+
}),
|
|
130
|
+
block("accordion", { content: "block+", attrs: { title: "" } }),
|
|
131
|
+
block("codeGroup", { group: "block", content: "codeBlock+" }),
|
|
132
|
+
block("typeTable", { group: "block", atom: true, attrs: { rows: [] } })
|
|
133
|
+
];
|
|
134
|
+
}
|
|
135
|
+
var CodeBlockTitle = Extension.create({
|
|
136
|
+
name: "codeBlockTitle",
|
|
137
|
+
addGlobalAttributes() {
|
|
138
|
+
return [
|
|
139
|
+
{
|
|
140
|
+
types: ["codeBlock"],
|
|
141
|
+
attributes: {
|
|
142
|
+
title: {
|
|
143
|
+
default: null,
|
|
144
|
+
parseHTML: (element) => element.getAttribute("data-title"),
|
|
145
|
+
renderHTML: (attributes) => attributes.title ? { "data-title": attributes.title } : {}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
];
|
|
150
|
+
}
|
|
151
|
+
});
|
|
61
152
|
|
|
62
153
|
// src/extensions.ts
|
|
63
154
|
lowlight.registerLanguage("javascript", javascript);
|
|
@@ -69,6 +160,7 @@ var createExtensions = ({
|
|
|
69
160
|
placeholder
|
|
70
161
|
} = {}) => [
|
|
71
162
|
StarterKit.configure({
|
|
163
|
+
code: false,
|
|
72
164
|
codeBlock: false,
|
|
73
165
|
// Configured/replaced explicitly below (custom options or a
|
|
74
166
|
// `.extend()`) — disabled here to avoid tiptap's duplicate-extension
|
|
@@ -109,7 +201,7 @@ var createExtensions = ({
|
|
|
109
201
|
color: "hsl(var(--foreground))",
|
|
110
202
|
width: 2
|
|
111
203
|
}),
|
|
112
|
-
Gapcursor,
|
|
204
|
+
Gapcursor$1,
|
|
113
205
|
CodeBlockLowlight.configure({
|
|
114
206
|
lowlight
|
|
115
207
|
}),
|
|
@@ -128,7 +220,9 @@ var createExtensions = ({
|
|
|
128
220
|
}
|
|
129
221
|
}),
|
|
130
222
|
Highlight,
|
|
131
|
-
CodeMirrorNode
|
|
223
|
+
CodeMirrorNode,
|
|
224
|
+
CodeBlockTitle,
|
|
225
|
+
...createDocsBlockExtensions()
|
|
132
226
|
];
|
|
133
227
|
var LinkEditorPopover = ({
|
|
134
228
|
editor,
|
|
@@ -296,6 +390,394 @@ var LinkEditorPopover = ({
|
|
|
296
390
|
);
|
|
297
391
|
};
|
|
298
392
|
var link_editor_popover_default = LinkEditorPopover;
|
|
393
|
+
var input = "h-7 min-w-0 rounded border border-input bg-card px-2 text-xs text-foreground placeholder:text-muted-foreground";
|
|
394
|
+
var smallButton = "inline-flex h-7 items-center gap-1 rounded px-2 text-xs text-muted-foreground hover:bg-muted hover:text-foreground disabled:opacity-40";
|
|
395
|
+
var paragraph = (text = "") => text ? { type: "paragraph", content: [{ type: "text", text }] } : { type: "paragraph" };
|
|
396
|
+
var docsBlockTemplates = {
|
|
397
|
+
callout: {
|
|
398
|
+
label: "Callout",
|
|
399
|
+
content: { type: "callout", attrs: { type: "info" }, content: [paragraph()] }
|
|
400
|
+
},
|
|
401
|
+
tabs: {
|
|
402
|
+
label: "Tabs",
|
|
403
|
+
content: {
|
|
404
|
+
type: "tabs",
|
|
405
|
+
content: ["Tab 1", "Tab 2"].map((label) => ({
|
|
406
|
+
type: "tab",
|
|
407
|
+
attrs: { label },
|
|
408
|
+
content: [paragraph()]
|
|
409
|
+
}))
|
|
410
|
+
}
|
|
411
|
+
},
|
|
412
|
+
steps: {
|
|
413
|
+
label: "Steps",
|
|
414
|
+
content: {
|
|
415
|
+
type: "steps",
|
|
416
|
+
content: [
|
|
417
|
+
{
|
|
418
|
+
type: "step",
|
|
419
|
+
content: [{ type: "heading", attrs: { level: 3 } }, paragraph()]
|
|
420
|
+
}
|
|
421
|
+
]
|
|
422
|
+
}
|
|
423
|
+
},
|
|
424
|
+
cards: {
|
|
425
|
+
label: "Cards",
|
|
426
|
+
content: { type: "cards", content: [{ type: "card", attrs: { title: "Card" } }] }
|
|
427
|
+
},
|
|
428
|
+
accordions: {
|
|
429
|
+
label: "Accordion",
|
|
430
|
+
content: {
|
|
431
|
+
type: "accordions",
|
|
432
|
+
content: [
|
|
433
|
+
{ type: "accordion", attrs: { title: "Question" }, content: [paragraph()] }
|
|
434
|
+
]
|
|
435
|
+
}
|
|
436
|
+
},
|
|
437
|
+
codeGroup: {
|
|
438
|
+
label: "Code group",
|
|
439
|
+
content: {
|
|
440
|
+
type: "codeGroup",
|
|
441
|
+
content: [
|
|
442
|
+
{ type: "codeBlock", attrs: { language: "bash", title: "Terminal" } },
|
|
443
|
+
{ type: "codeBlock", attrs: { language: "ts", title: "index.ts" } }
|
|
444
|
+
]
|
|
445
|
+
}
|
|
446
|
+
},
|
|
447
|
+
typeTable: {
|
|
448
|
+
label: "Type table",
|
|
449
|
+
content: {
|
|
450
|
+
type: "typeTable",
|
|
451
|
+
attrs: {
|
|
452
|
+
rows: [
|
|
453
|
+
{
|
|
454
|
+
name: "name",
|
|
455
|
+
type: "string",
|
|
456
|
+
default: null,
|
|
457
|
+
description: null,
|
|
458
|
+
required: false
|
|
459
|
+
}
|
|
460
|
+
]
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
};
|
|
465
|
+
var childTemplates = {
|
|
466
|
+
tabs: (count) => ({
|
|
467
|
+
type: "tab",
|
|
468
|
+
attrs: { label: `Tab ${count + 1}` },
|
|
469
|
+
content: [paragraph()]
|
|
470
|
+
}),
|
|
471
|
+
steps: () => ({
|
|
472
|
+
type: "step",
|
|
473
|
+
content: [{ type: "heading", attrs: { level: 3 } }, paragraph()]
|
|
474
|
+
}),
|
|
475
|
+
cards: () => ({ type: "card", attrs: { title: "Card" } }),
|
|
476
|
+
accordions: () => ({
|
|
477
|
+
type: "accordion",
|
|
478
|
+
attrs: { title: "Question" },
|
|
479
|
+
content: [paragraph()]
|
|
480
|
+
}),
|
|
481
|
+
codeGroup: () => ({ type: "codeBlock", attrs: { language: null, title: "Code" } })
|
|
482
|
+
};
|
|
483
|
+
var childLabels = {
|
|
484
|
+
tabs: "Add tab",
|
|
485
|
+
steps: "Add step",
|
|
486
|
+
cards: "Add card",
|
|
487
|
+
accordions: "Add item",
|
|
488
|
+
codeGroup: "Add code block"
|
|
489
|
+
};
|
|
490
|
+
function BlockFrame({
|
|
491
|
+
label,
|
|
492
|
+
props,
|
|
493
|
+
children,
|
|
494
|
+
fields
|
|
495
|
+
}) {
|
|
496
|
+
const { node, editor, getPos, deleteNode } = props;
|
|
497
|
+
const add = childTemplates[node.type.name];
|
|
498
|
+
return /* @__PURE__ */ jsxs(NodeViewWrapper, { className: "te-block", "data-block": node.type.name, children: [
|
|
499
|
+
/* @__PURE__ */ jsxs("div", { className: "te-block__bar", contentEditable: false, children: [
|
|
500
|
+
/* @__PURE__ */ jsx("span", { className: "te-block__label", children: label }),
|
|
501
|
+
fields,
|
|
502
|
+
/* @__PURE__ */ jsxs("span", { className: "ml-auto flex items-center gap-1", children: [
|
|
503
|
+
add && editor.isEditable && /* @__PURE__ */ jsxs(
|
|
504
|
+
"button",
|
|
505
|
+
{
|
|
506
|
+
type: "button",
|
|
507
|
+
className: smallButton,
|
|
508
|
+
onClick: () => {
|
|
509
|
+
const pos = getPos();
|
|
510
|
+
const current = typeof pos === "number" ? editor.state.doc.nodeAt(pos) : null;
|
|
511
|
+
if (typeof pos !== "number" || current?.type !== node.type) return;
|
|
512
|
+
const child = editor.schema.nodeFromJSON(add(current.childCount));
|
|
513
|
+
const end = current.childCount;
|
|
514
|
+
if (!current.canReplace(end, end, Fragment$1.from(child))) return;
|
|
515
|
+
const at = pos + current.nodeSize - 1;
|
|
516
|
+
editor.view.dispatch(
|
|
517
|
+
editor.state.tr.insert(at, child).scrollIntoView()
|
|
518
|
+
);
|
|
519
|
+
editor.view.focus();
|
|
520
|
+
},
|
|
521
|
+
children: [
|
|
522
|
+
/* @__PURE__ */ jsx(Plus, { className: "size-3.5" }),
|
|
523
|
+
childLabels[node.type.name]
|
|
524
|
+
]
|
|
525
|
+
}
|
|
526
|
+
),
|
|
527
|
+
editor.isEditable && /* @__PURE__ */ jsx(
|
|
528
|
+
"button",
|
|
529
|
+
{
|
|
530
|
+
type: "button",
|
|
531
|
+
className: smallButton,
|
|
532
|
+
"aria-label": `Remove ${label.toLowerCase()}`,
|
|
533
|
+
title: `Remove ${label.toLowerCase()}`,
|
|
534
|
+
onClick: deleteNode,
|
|
535
|
+
children: /* @__PURE__ */ jsx(Trash2, { className: "size-3.5" })
|
|
536
|
+
}
|
|
537
|
+
)
|
|
538
|
+
] })
|
|
539
|
+
] }),
|
|
540
|
+
children ?? /* @__PURE__ */ jsx(NodeViewContent, { className: "te-block__content" })
|
|
541
|
+
] });
|
|
542
|
+
}
|
|
543
|
+
function ItemFrame({
|
|
544
|
+
props,
|
|
545
|
+
fields
|
|
546
|
+
}) {
|
|
547
|
+
const { editor, getPos, deleteNode, node } = props;
|
|
548
|
+
const pos = getPos();
|
|
549
|
+
const parent = typeof pos === "number" ? editor.state.doc.resolve(pos).parent : null;
|
|
550
|
+
return /* @__PURE__ */ jsxs(NodeViewWrapper, { className: "te-block-item", "data-block": node.type.name, children: [
|
|
551
|
+
(fields || (parent?.childCount ?? 0) > 1) && /* @__PURE__ */ jsxs("div", { className: "te-block__bar", contentEditable: false, children: [
|
|
552
|
+
fields,
|
|
553
|
+
(parent?.childCount ?? 0) > 1 && editor.isEditable && /* @__PURE__ */ jsx(
|
|
554
|
+
"button",
|
|
555
|
+
{
|
|
556
|
+
type: "button",
|
|
557
|
+
className: `${smallButton} ml-auto`,
|
|
558
|
+
"aria-label": "Remove item",
|
|
559
|
+
title: "Remove item",
|
|
560
|
+
onClick: deleteNode,
|
|
561
|
+
children: /* @__PURE__ */ jsx(X, { className: "size-3.5" })
|
|
562
|
+
}
|
|
563
|
+
)
|
|
564
|
+
] }),
|
|
565
|
+
/* @__PURE__ */ jsx(NodeViewContent, { className: "te-block__content" })
|
|
566
|
+
] });
|
|
567
|
+
}
|
|
568
|
+
function TextField({
|
|
569
|
+
props,
|
|
570
|
+
name,
|
|
571
|
+
placeholder,
|
|
572
|
+
nullable,
|
|
573
|
+
className = "w-40"
|
|
574
|
+
}) {
|
|
575
|
+
const value = props.node.attrs[name] ?? "";
|
|
576
|
+
return /* @__PURE__ */ jsx(
|
|
577
|
+
"input",
|
|
578
|
+
{
|
|
579
|
+
className: `${input} ${className}`,
|
|
580
|
+
"aria-label": placeholder,
|
|
581
|
+
placeholder,
|
|
582
|
+
value,
|
|
583
|
+
disabled: !props.editor.isEditable,
|
|
584
|
+
onChange: (event) => props.updateAttributes({
|
|
585
|
+
[name]: nullable && !event.target.value ? null : event.target.value
|
|
586
|
+
})
|
|
587
|
+
}
|
|
588
|
+
);
|
|
589
|
+
}
|
|
590
|
+
function CalloutView(props) {
|
|
591
|
+
return /* @__PURE__ */ jsx(
|
|
592
|
+
BlockFrame,
|
|
593
|
+
{
|
|
594
|
+
label: "Callout",
|
|
595
|
+
props,
|
|
596
|
+
fields: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
597
|
+
/* @__PURE__ */ jsx(
|
|
598
|
+
"select",
|
|
599
|
+
{
|
|
600
|
+
className: input,
|
|
601
|
+
"aria-label": "Callout type",
|
|
602
|
+
value: props.node.attrs.type ?? "info",
|
|
603
|
+
disabled: !props.editor.isEditable,
|
|
604
|
+
onChange: (event) => props.updateAttributes({ type: event.target.value }),
|
|
605
|
+
children: CALLOUT_TYPES.map((type) => /* @__PURE__ */ jsx("option", { value: type, children: type }, type))
|
|
606
|
+
}
|
|
607
|
+
),
|
|
608
|
+
/* @__PURE__ */ jsx(
|
|
609
|
+
TextField,
|
|
610
|
+
{
|
|
611
|
+
props,
|
|
612
|
+
name: "title",
|
|
613
|
+
placeholder: "Title (optional)",
|
|
614
|
+
nullable: true
|
|
615
|
+
}
|
|
616
|
+
)
|
|
617
|
+
] })
|
|
618
|
+
}
|
|
619
|
+
);
|
|
620
|
+
}
|
|
621
|
+
function CodeBlockView(props) {
|
|
622
|
+
return /* @__PURE__ */ jsxs(NodeViewWrapper, { className: "te-block-code", children: [
|
|
623
|
+
/* @__PURE__ */ jsxs("div", { className: "te-block__bar", contentEditable: false, children: [
|
|
624
|
+
/* @__PURE__ */ jsx(TextField, { props, name: "title", placeholder: "File name", nullable: true }),
|
|
625
|
+
/* @__PURE__ */ jsx(
|
|
626
|
+
TextField,
|
|
627
|
+
{
|
|
628
|
+
props,
|
|
629
|
+
name: "language",
|
|
630
|
+
placeholder: "Language",
|
|
631
|
+
nullable: true,
|
|
632
|
+
className: "w-24"
|
|
633
|
+
}
|
|
634
|
+
)
|
|
635
|
+
] }),
|
|
636
|
+
/* @__PURE__ */ jsx("pre", { children: /* @__PURE__ */ jsx(NodeViewContent, { as: "code" }) })
|
|
637
|
+
] });
|
|
638
|
+
}
|
|
639
|
+
function TypeTableView(props) {
|
|
640
|
+
const rows = props.node.attrs.rows ?? [];
|
|
641
|
+
const editable = props.editor.isEditable;
|
|
642
|
+
const update = (index, patch) => props.updateAttributes({
|
|
643
|
+
rows: rows.map((row, i) => i === index ? { ...row, ...patch } : row)
|
|
644
|
+
});
|
|
645
|
+
const text = (index, key) => /* @__PURE__ */ jsx(
|
|
646
|
+
"input",
|
|
647
|
+
{
|
|
648
|
+
className: `${input} w-full`,
|
|
649
|
+
"aria-label": key,
|
|
650
|
+
placeholder: key,
|
|
651
|
+
value: rows[index][key] ?? "",
|
|
652
|
+
disabled: !editable,
|
|
653
|
+
onChange: (event) => update(index, {
|
|
654
|
+
[key]: (key === "default" || key === "description") && !event.target.value ? null : event.target.value
|
|
655
|
+
})
|
|
656
|
+
}
|
|
657
|
+
);
|
|
658
|
+
return /* @__PURE__ */ jsx(BlockFrame, { label: "Type table", props, children: /* @__PURE__ */ jsxs("div", { contentEditable: false, className: "te-block__content", children: [
|
|
659
|
+
/* @__PURE__ */ jsxs("table", { className: "te-block-table", children: [
|
|
660
|
+
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
661
|
+
/* @__PURE__ */ jsx("th", { children: "Prop" }),
|
|
662
|
+
/* @__PURE__ */ jsx("th", { children: "Type" }),
|
|
663
|
+
/* @__PURE__ */ jsx("th", { children: "Default" }),
|
|
664
|
+
/* @__PURE__ */ jsx("th", { children: "Description" }),
|
|
665
|
+
/* @__PURE__ */ jsx("th", { children: "Required" }),
|
|
666
|
+
/* @__PURE__ */ jsx("th", {})
|
|
667
|
+
] }) }),
|
|
668
|
+
/* @__PURE__ */ jsx("tbody", { children: rows.map((row, index) => (
|
|
669
|
+
// biome-ignore lint/suspicious/noArrayIndexKey: row names are edited in place.
|
|
670
|
+
/* @__PURE__ */ jsxs("tr", { children: [
|
|
671
|
+
/* @__PURE__ */ jsx("td", { children: text(index, "name") }),
|
|
672
|
+
/* @__PURE__ */ jsx("td", { children: text(index, "type") }),
|
|
673
|
+
/* @__PURE__ */ jsx("td", { children: text(index, "default") }),
|
|
674
|
+
/* @__PURE__ */ jsx("td", { children: text(index, "description") }),
|
|
675
|
+
/* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx(
|
|
676
|
+
"input",
|
|
677
|
+
{
|
|
678
|
+
type: "checkbox",
|
|
679
|
+
"aria-label": "Required",
|
|
680
|
+
checked: row.required,
|
|
681
|
+
disabled: !editable,
|
|
682
|
+
onChange: (event) => update(index, { required: event.target.checked })
|
|
683
|
+
}
|
|
684
|
+
) }),
|
|
685
|
+
/* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx(
|
|
686
|
+
"button",
|
|
687
|
+
{
|
|
688
|
+
type: "button",
|
|
689
|
+
className: smallButton,
|
|
690
|
+
"aria-label": "Remove row",
|
|
691
|
+
disabled: !editable || rows.length === 1,
|
|
692
|
+
onClick: () => props.updateAttributes({
|
|
693
|
+
rows: rows.filter((_, i) => i !== index)
|
|
694
|
+
}),
|
|
695
|
+
children: /* @__PURE__ */ jsx(X, { className: "size-3.5" })
|
|
696
|
+
}
|
|
697
|
+
) })
|
|
698
|
+
] }, index)
|
|
699
|
+
)) })
|
|
700
|
+
] }),
|
|
701
|
+
editable && /* @__PURE__ */ jsxs(
|
|
702
|
+
"button",
|
|
703
|
+
{
|
|
704
|
+
type: "button",
|
|
705
|
+
className: smallButton,
|
|
706
|
+
onClick: () => props.updateAttributes({
|
|
707
|
+
rows: [
|
|
708
|
+
...rows,
|
|
709
|
+
{
|
|
710
|
+
name: `prop${rows.length + 1}`,
|
|
711
|
+
type: "string",
|
|
712
|
+
default: null,
|
|
713
|
+
description: null,
|
|
714
|
+
required: false
|
|
715
|
+
}
|
|
716
|
+
]
|
|
717
|
+
}),
|
|
718
|
+
children: [
|
|
719
|
+
/* @__PURE__ */ jsx(Plus, { className: "size-3.5" }),
|
|
720
|
+
"Add row"
|
|
721
|
+
]
|
|
722
|
+
}
|
|
723
|
+
)
|
|
724
|
+
] }) });
|
|
725
|
+
}
|
|
726
|
+
var views = {
|
|
727
|
+
callout: CalloutView,
|
|
728
|
+
tabs: (props) => /* @__PURE__ */ jsx(BlockFrame, { label: "Tabs", props }),
|
|
729
|
+
tab: (props) => /* @__PURE__ */ jsx(
|
|
730
|
+
ItemFrame,
|
|
731
|
+
{
|
|
732
|
+
props,
|
|
733
|
+
fields: /* @__PURE__ */ jsx(TextField, { props, name: "label", placeholder: "Tab label" })
|
|
734
|
+
}
|
|
735
|
+
),
|
|
736
|
+
steps: (props) => /* @__PURE__ */ jsx(BlockFrame, { label: "Steps", props }),
|
|
737
|
+
step: (props) => /* @__PURE__ */ jsx(ItemFrame, { props }),
|
|
738
|
+
cards: (props) => /* @__PURE__ */ jsx(BlockFrame, { label: "Cards", props }),
|
|
739
|
+
card: (props) => /* @__PURE__ */ jsx(
|
|
740
|
+
ItemFrame,
|
|
741
|
+
{
|
|
742
|
+
props,
|
|
743
|
+
fields: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
744
|
+
/* @__PURE__ */ jsx(TextField, { props, name: "title", placeholder: "Title" }),
|
|
745
|
+
/* @__PURE__ */ jsx(TextField, { props, name: "href", placeholder: "Link (/docs/\u2026)", nullable: true }),
|
|
746
|
+
/* @__PURE__ */ jsx(
|
|
747
|
+
TextField,
|
|
748
|
+
{
|
|
749
|
+
props,
|
|
750
|
+
name: "icon",
|
|
751
|
+
placeholder: "Icon (e.g. Rocket)",
|
|
752
|
+
nullable: true,
|
|
753
|
+
className: "w-32"
|
|
754
|
+
}
|
|
755
|
+
)
|
|
756
|
+
] })
|
|
757
|
+
}
|
|
758
|
+
),
|
|
759
|
+
accordions: (props) => /* @__PURE__ */ jsx(BlockFrame, { label: "Accordion", props }),
|
|
760
|
+
accordion: (props) => /* @__PURE__ */ jsx(
|
|
761
|
+
ItemFrame,
|
|
762
|
+
{
|
|
763
|
+
props,
|
|
764
|
+
fields: /* @__PURE__ */ jsx(TextField, { props, name: "title", placeholder: "Title" })
|
|
765
|
+
}
|
|
766
|
+
),
|
|
767
|
+
codeGroup: (props) => /* @__PURE__ */ jsx(BlockFrame, { label: "Code group", props }),
|
|
768
|
+
typeTable: TypeTableView
|
|
769
|
+
};
|
|
770
|
+
function withDocsBlockViews(extensions, profile) {
|
|
771
|
+
return extensions.map((extension) => {
|
|
772
|
+
const view = views[extension.name] ?? (profile === "documentation" && extension.name === "codeBlock" ? CodeBlockView : void 0);
|
|
773
|
+
if (!view || !(extension instanceof Node)) return extension;
|
|
774
|
+
return extension.extend({
|
|
775
|
+
addNodeView() {
|
|
776
|
+
return ReactNodeViewRenderer(view);
|
|
777
|
+
}
|
|
778
|
+
});
|
|
779
|
+
});
|
|
780
|
+
}
|
|
299
781
|
var iconButtonBase = "inline-flex h-8 w-8 items-center justify-center rounded border border-transparent text-foreground transition-colors focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary disabled:cursor-not-allowed disabled:opacity-50";
|
|
300
782
|
function IconButton({
|
|
301
783
|
icon: Icon,
|
|
@@ -473,7 +955,7 @@ var Toolbar = ({
|
|
|
473
955
|
/* @__PURE__ */ jsx(
|
|
474
956
|
IconButton,
|
|
475
957
|
{
|
|
476
|
-
icon: Code,
|
|
958
|
+
icon: Code$1,
|
|
477
959
|
label: "Inline code",
|
|
478
960
|
active: editor.isActive("code"),
|
|
479
961
|
onClick: () => editor.chain().focus().toggleCode().run()
|
|
@@ -563,7 +1045,7 @@ var Toolbar = ({
|
|
|
563
1045
|
setActivePopover(null);
|
|
564
1046
|
},
|
|
565
1047
|
children: [
|
|
566
|
-
/* @__PURE__ */ jsx(Code, { className: "size-4" }),
|
|
1048
|
+
/* @__PURE__ */ jsx(Code$1, { className: "size-4" }),
|
|
567
1049
|
"Code block"
|
|
568
1050
|
]
|
|
569
1051
|
}
|
|
@@ -601,6 +1083,22 @@ var Toolbar = ({
|
|
|
601
1083
|
]
|
|
602
1084
|
}
|
|
603
1085
|
),
|
|
1086
|
+
profile === "documentation" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1087
|
+
/* @__PURE__ */ jsx("div", { className: "my-1 h-px bg-border" }),
|
|
1088
|
+
Object.entries(docsBlockTemplates).map(([name, block2]) => /* @__PURE__ */ jsx(
|
|
1089
|
+
"button",
|
|
1090
|
+
{
|
|
1091
|
+
type: "button",
|
|
1092
|
+
className: "flex w-full rounded px-2.5 py-2 text-sm hover:bg-muted",
|
|
1093
|
+
onClick: () => {
|
|
1094
|
+
editor.chain().focus().insertContent(block2.content).run();
|
|
1095
|
+
setActivePopover(null);
|
|
1096
|
+
},
|
|
1097
|
+
children: block2.label
|
|
1098
|
+
},
|
|
1099
|
+
name
|
|
1100
|
+
))
|
|
1101
|
+
] }),
|
|
604
1102
|
editor.isActive("table") && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
605
1103
|
/* @__PURE__ */ jsx("div", { className: "my-1 h-px bg-border" }),
|
|
606
1104
|
/* @__PURE__ */ jsx(
|
|
@@ -797,7 +1295,7 @@ var InlineBubbleMenu = ({
|
|
|
797
1295
|
/* @__PURE__ */ jsx(
|
|
798
1296
|
InlineButton,
|
|
799
1297
|
{
|
|
800
|
-
icon: Code,
|
|
1298
|
+
icon: Code$1,
|
|
801
1299
|
label: "Inline code",
|
|
802
1300
|
active: editor.isActive("code"),
|
|
803
1301
|
onClick: () => editor.chain().focus().toggleCode().run()
|
|
@@ -882,6 +1380,8 @@ function isSafeDocsUrl(value, image = false) {
|
|
|
882
1380
|
function createDocsExtensions() {
|
|
883
1381
|
return [
|
|
884
1382
|
StarterKit.configure({
|
|
1383
|
+
code: false,
|
|
1384
|
+
codeBlock: false,
|
|
885
1385
|
document: false,
|
|
886
1386
|
underline: false,
|
|
887
1387
|
link: false,
|
|
@@ -899,7 +1399,10 @@ function createDocsExtensions() {
|
|
|
899
1399
|
Table.configure({ resizable: false }),
|
|
900
1400
|
TableRow,
|
|
901
1401
|
TableCell.extend({ content: "paragraph" }),
|
|
902
|
-
TableHeader.extend({ content: "paragraph" })
|
|
1402
|
+
TableHeader.extend({ content: "paragraph" }),
|
|
1403
|
+
CodeBlock,
|
|
1404
|
+
CodeBlockTitle,
|
|
1405
|
+
...createDocsBlockExtensions()
|
|
903
1406
|
];
|
|
904
1407
|
}
|
|
905
1408
|
getSchema(createDocsExtensions());
|
|
@@ -931,10 +1434,19 @@ var Editor = Object.assign(
|
|
|
931
1434
|
const lastSerializedContentRef = useRef(JSON.stringify(initialContent ?? empty_doc_default));
|
|
932
1435
|
const refreshRef = useRef(refresh);
|
|
933
1436
|
const extensions = useMemo(
|
|
934
|
-
() =>
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
1437
|
+
() => withDocsBlockViews(
|
|
1438
|
+
profile === "documentation" ? [
|
|
1439
|
+
...createDocsExtensions(),
|
|
1440
|
+
Placeholder.configure({
|
|
1441
|
+
placeholder: placeholder || "Write something\u2026"
|
|
1442
|
+
}),
|
|
1443
|
+
// Editing only: lets authors type before or after a block that
|
|
1444
|
+
// starts or ends the doc. Empty paragraphs are not saved to Markdown.
|
|
1445
|
+
Gapcursor,
|
|
1446
|
+
TrailingNode
|
|
1447
|
+
] : createExtensions({ placeholder }),
|
|
1448
|
+
profile ?? "default"
|
|
1449
|
+
),
|
|
938
1450
|
[placeholder, profile]
|
|
939
1451
|
);
|
|
940
1452
|
const changeTimeoutRef = useRef(null);
|
|
@@ -1289,10 +1801,12 @@ function textFromChildren(node) {
|
|
|
1289
1801
|
function RenderedCodeBlock({
|
|
1290
1802
|
node,
|
|
1291
1803
|
children,
|
|
1292
|
-
language
|
|
1804
|
+
language,
|
|
1805
|
+
title
|
|
1293
1806
|
}) {
|
|
1294
1807
|
const source = extractTextFromNode(node) || textFromChildren(children);
|
|
1295
1808
|
return /* @__PURE__ */ jsxs("div", { className: "te-code-block", children: [
|
|
1809
|
+
title && /* @__PURE__ */ jsx("div", { className: "te-code-block__title", children: title }),
|
|
1296
1810
|
/* @__PURE__ */ jsx("pre", { children: /* @__PURE__ */ jsx("code", { className: language ? `language-${language}` : void 0, children }) }),
|
|
1297
1811
|
/* @__PURE__ */ jsx(CopyCodeButton, { source })
|
|
1298
1812
|
] });
|
|
@@ -1328,6 +1842,148 @@ function extractDocsHeadings(json2) {
|
|
|
1328
1842
|
if (json2) walk(json2);
|
|
1329
1843
|
return headings;
|
|
1330
1844
|
}
|
|
1845
|
+
function DocsTabs({
|
|
1846
|
+
labels,
|
|
1847
|
+
children,
|
|
1848
|
+
className
|
|
1849
|
+
}) {
|
|
1850
|
+
const id = useId();
|
|
1851
|
+
const [active, setActive] = useState(0);
|
|
1852
|
+
const panels = React5.Children.toArray(children);
|
|
1853
|
+
function onKeyDown(event, index) {
|
|
1854
|
+
const step = event.key === "ArrowRight" ? 1 : event.key === "ArrowLeft" ? -1 : 0;
|
|
1855
|
+
if (!step) return;
|
|
1856
|
+
event.preventDefault();
|
|
1857
|
+
const next = (index + step + labels.length) % labels.length;
|
|
1858
|
+
setActive(next);
|
|
1859
|
+
document.getElementById(`${id}-tab-${next}`)?.focus();
|
|
1860
|
+
}
|
|
1861
|
+
return /* @__PURE__ */ jsxs("div", { className, children: [
|
|
1862
|
+
/* @__PURE__ */ jsx("div", { role: "tablist", className: "te-tabs__list", children: labels.map((label, index) => /* @__PURE__ */ jsx(
|
|
1863
|
+
"button",
|
|
1864
|
+
{
|
|
1865
|
+
id: `${id}-tab-${index}`,
|
|
1866
|
+
type: "button",
|
|
1867
|
+
role: "tab",
|
|
1868
|
+
"aria-selected": index === active,
|
|
1869
|
+
"aria-controls": `${id}-panel-${index}`,
|
|
1870
|
+
tabIndex: index === active ? 0 : -1,
|
|
1871
|
+
className: "te-tabs__tab",
|
|
1872
|
+
onClick: () => setActive(index),
|
|
1873
|
+
onKeyDown: (event) => onKeyDown(event, index),
|
|
1874
|
+
children: label
|
|
1875
|
+
},
|
|
1876
|
+
index
|
|
1877
|
+
)) }),
|
|
1878
|
+
panels.map((panel, index) => /* @__PURE__ */ jsx(
|
|
1879
|
+
"div",
|
|
1880
|
+
{
|
|
1881
|
+
id: `${id}-panel-${index}`,
|
|
1882
|
+
role: "tabpanel",
|
|
1883
|
+
"aria-labelledby": `${id}-tab-${index}`,
|
|
1884
|
+
hidden: index !== active,
|
|
1885
|
+
className: "te-tabs__panel",
|
|
1886
|
+
children: panel
|
|
1887
|
+
},
|
|
1888
|
+
index
|
|
1889
|
+
))
|
|
1890
|
+
] });
|
|
1891
|
+
}
|
|
1892
|
+
var childAttrs = (node) => {
|
|
1893
|
+
const attrs = [];
|
|
1894
|
+
node.forEach((child) => {
|
|
1895
|
+
attrs.push(child.attrs);
|
|
1896
|
+
});
|
|
1897
|
+
return attrs;
|
|
1898
|
+
};
|
|
1899
|
+
var CALLOUT_ICONS = {
|
|
1900
|
+
note: StickyNote,
|
|
1901
|
+
tip: Lightbulb,
|
|
1902
|
+
info: Info,
|
|
1903
|
+
warning: CircleAlert,
|
|
1904
|
+
danger: OctagonAlert
|
|
1905
|
+
};
|
|
1906
|
+
function Callout({ node, children }) {
|
|
1907
|
+
const type = node.attrs.type ?? "info";
|
|
1908
|
+
const Icon = CALLOUT_ICONS[type] ?? Info;
|
|
1909
|
+
return /* @__PURE__ */ jsxs("div", { className: "te-callout", "data-type": type, role: "note", children: [
|
|
1910
|
+
/* @__PURE__ */ jsx(Icon, { className: "te-callout__icon", "aria-hidden": true }),
|
|
1911
|
+
/* @__PURE__ */ jsxs("div", { className: "te-callout__body", children: [
|
|
1912
|
+
node.attrs.title && /* @__PURE__ */ jsx("p", { className: "te-callout__title", children: node.attrs.title }),
|
|
1913
|
+
children
|
|
1914
|
+
] })
|
|
1915
|
+
] });
|
|
1916
|
+
}
|
|
1917
|
+
function Tabs({ node, children }) {
|
|
1918
|
+
return /* @__PURE__ */ jsx(DocsTabs, { className: "te-tabs", labels: childAttrs(node).map((attrs) => attrs.label), children });
|
|
1919
|
+
}
|
|
1920
|
+
function CodeGroup({ node, children }) {
|
|
1921
|
+
const labels = childAttrs(node).map(
|
|
1922
|
+
(attrs, index) => attrs.title ?? attrs.language ?? `Code ${index + 1}`
|
|
1923
|
+
);
|
|
1924
|
+
return /* @__PURE__ */ jsx(DocsTabs, { className: "te-tabs te-code-group", labels, children });
|
|
1925
|
+
}
|
|
1926
|
+
function Steps({ children }) {
|
|
1927
|
+
return /* @__PURE__ */ jsx("ol", { className: "te-steps", children });
|
|
1928
|
+
}
|
|
1929
|
+
function Step({ children }) {
|
|
1930
|
+
return /* @__PURE__ */ jsx("li", { className: "te-step", children });
|
|
1931
|
+
}
|
|
1932
|
+
function Cards({ children }) {
|
|
1933
|
+
return /* @__PURE__ */ jsx("div", { className: "te-cards", children });
|
|
1934
|
+
}
|
|
1935
|
+
var iconName = (name) => name.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/([A-Za-z])([0-9])/g, "$1-$2").toLowerCase();
|
|
1936
|
+
function Card({ node, children }) {
|
|
1937
|
+
const { title, href, icon } = node.attrs;
|
|
1938
|
+
const body = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1939
|
+
icon && /* @__PURE__ */ jsx(DynamicIcon, { name: iconName(icon), className: "te-card__icon", "aria-hidden": true }),
|
|
1940
|
+
/* @__PURE__ */ jsx("span", { className: "te-card__title", children: title }),
|
|
1941
|
+
node.childCount > 0 && /* @__PURE__ */ jsx("div", { className: "te-card__body", children })
|
|
1942
|
+
] });
|
|
1943
|
+
return href ? /* @__PURE__ */ jsx("a", { className: "te-card", href, children: body }) : /* @__PURE__ */ jsx("div", { className: "te-card", children: body });
|
|
1944
|
+
}
|
|
1945
|
+
function Accordions({ children }) {
|
|
1946
|
+
return /* @__PURE__ */ jsx("div", { className: "te-accordions", children });
|
|
1947
|
+
}
|
|
1948
|
+
function Accordion({ node, children }) {
|
|
1949
|
+
return /* @__PURE__ */ jsxs("details", { className: "te-accordion", children: [
|
|
1950
|
+
/* @__PURE__ */ jsx("summary", { className: "te-accordion__title", children: node.attrs.title }),
|
|
1951
|
+
/* @__PURE__ */ jsx("div", { className: "te-accordion__body", children })
|
|
1952
|
+
] });
|
|
1953
|
+
}
|
|
1954
|
+
function TypeTable({ node }) {
|
|
1955
|
+
const rows = node.attrs.rows ?? [];
|
|
1956
|
+
return /* @__PURE__ */ jsx("div", { className: "te-type-table", children: /* @__PURE__ */ jsxs("table", { children: [
|
|
1957
|
+
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
1958
|
+
/* @__PURE__ */ jsx("th", { children: "Prop" }),
|
|
1959
|
+
/* @__PURE__ */ jsx("th", { children: "Type" }),
|
|
1960
|
+
/* @__PURE__ */ jsx("th", { children: "Default" }),
|
|
1961
|
+
/* @__PURE__ */ jsx("th", { children: "Description" })
|
|
1962
|
+
] }) }),
|
|
1963
|
+
/* @__PURE__ */ jsx("tbody", { children: rows.map((row) => /* @__PURE__ */ jsxs("tr", { children: [
|
|
1964
|
+
/* @__PURE__ */ jsxs("td", { children: [
|
|
1965
|
+
/* @__PURE__ */ jsx("code", { children: row.name }),
|
|
1966
|
+
row.required && /* @__PURE__ */ jsx("span", { className: "te-type-table__required", children: " (required)" })
|
|
1967
|
+
] }),
|
|
1968
|
+
/* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx("code", { children: row.type }) }),
|
|
1969
|
+
/* @__PURE__ */ jsx("td", { children: row.default === null ? "\u2014" : /* @__PURE__ */ jsx("code", { children: row.default }) }),
|
|
1970
|
+
/* @__PURE__ */ jsx("td", { children: row.description ?? "" })
|
|
1971
|
+
] }, row.name)) })
|
|
1972
|
+
] }) });
|
|
1973
|
+
}
|
|
1974
|
+
var docsBlockMapping = {
|
|
1975
|
+
callout: Callout,
|
|
1976
|
+
tabs: Tabs,
|
|
1977
|
+
tab: ({ children }) => /* @__PURE__ */ jsx(Fragment, { children }),
|
|
1978
|
+
codeGroup: CodeGroup,
|
|
1979
|
+
steps: Steps,
|
|
1980
|
+
step: Step,
|
|
1981
|
+
cards: Cards,
|
|
1982
|
+
card: Card,
|
|
1983
|
+
accordions: Accordions,
|
|
1984
|
+
accordion: Accordion,
|
|
1985
|
+
typeTable: TypeTable
|
|
1986
|
+
};
|
|
1331
1987
|
var typographyClasses = (typography) => [
|
|
1332
1988
|
typography?.fontFamily,
|
|
1333
1989
|
typography?.fontSize,
|
|
@@ -1419,7 +2075,16 @@ function TextRenderer({
|
|
|
1419
2075
|
const Tag = profile === "documentation" ? `h${level}` : "h3";
|
|
1420
2076
|
return /* @__PURE__ */ jsx(Tag, { id, className: classes, children });
|
|
1421
2077
|
},
|
|
1422
|
-
|
|
2078
|
+
...docsBlockMapping,
|
|
2079
|
+
codeBlock: ({ node, children }) => /* @__PURE__ */ jsx(
|
|
2080
|
+
RenderedCodeBlock,
|
|
2081
|
+
{
|
|
2082
|
+
node,
|
|
2083
|
+
language: node?.attrs?.language,
|
|
2084
|
+
title: node?.attrs?.title,
|
|
2085
|
+
children
|
|
2086
|
+
}
|
|
2087
|
+
),
|
|
1423
2088
|
codeMirror: ({ node, children }) => /* @__PURE__ */ jsx(RenderedCodeBlock, { node, children })
|
|
1424
2089
|
},
|
|
1425
2090
|
markMapping: {
|
|
@@ -1487,7 +2152,7 @@ function normalizeTextEditorContent(json2) {
|
|
|
1487
2152
|
const text = typeof json2 === "string" ? json2.replace(/\r\n?/g, "\n") : "";
|
|
1488
2153
|
return {
|
|
1489
2154
|
type: "doc",
|
|
1490
|
-
content: text ? text.split(/\n{2,}/).map((
|
|
2155
|
+
content: text ? text.split(/\n{2,}/).map((paragraph2) => createParagraphNode(paragraph2)) : []
|
|
1491
2156
|
};
|
|
1492
2157
|
}
|
|
1493
2158
|
|