@estiva-app/ui 0.72.0 → 0.73.0-inline-text.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/InlineText.d.ts +56 -0
- package/dist/InlineText.d.ts.map +1 -0
- package/dist/editor.d.ts +1 -0
- package/dist/editor.d.ts.map +1 -1
- package/dist/editor.js +219 -112
- package/dist/editor.js.map +4 -4
- package/package.json +1 -1
- package/registry.json +97 -3
- package/src/InlineText.mdx +64 -0
- package/src/InlineText.stories.tsx +86 -0
- package/src/InlineText.test.tsx +187 -0
- package/src/InlineText.tsx +187 -0
- package/src/editor.ts +1 -0
- package/src/registry/registry.test.ts +4 -4
- package/stories/Choosing.mdx +1 -0
package/dist/editor.js
CHANGED
|
@@ -456,10 +456,10 @@ var ComposeKeys = Extension2.create({
|
|
|
456
456
|
}
|
|
457
457
|
});
|
|
458
458
|
function isEmptyDoc(editor) {
|
|
459
|
-
const
|
|
460
|
-
if (
|
|
459
|
+
const doc2 = editor.state.doc;
|
|
460
|
+
if (doc2.textContent.length > 0) return false;
|
|
461
461
|
let empty = true;
|
|
462
|
-
|
|
462
|
+
doc2.descendants((node) => {
|
|
463
463
|
if (node.isAtom && node.type.name !== "hardBreak") empty = false;
|
|
464
464
|
});
|
|
465
465
|
return empty;
|
|
@@ -527,8 +527,114 @@ function ComposeBox({ editor, onSend, placeholder, tools, attachments, ready = f
|
|
|
527
527
|
] }) });
|
|
528
528
|
}
|
|
529
529
|
|
|
530
|
+
// src/InlineText.tsx
|
|
531
|
+
import { useCallback as useCallback3, useEffect as useEffect3, useImperativeHandle as useImperativeHandle2, useRef as useRef3, useState as useState3 } from "react";
|
|
532
|
+
import { Extension as Extension3, Node as Node2 } from "@tiptap/core";
|
|
533
|
+
import { history, redo, undo } from "@tiptap/pm/history";
|
|
534
|
+
import { EditorContent as EditorContent2, useEditor } from "@tiptap/react";
|
|
535
|
+
import { cn as cn2 } from "@estiva-app/ui";
|
|
536
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
537
|
+
var VARIANT = {
|
|
538
|
+
title: "text-h2 text-text-primary",
|
|
539
|
+
summary: "text-body-1 text-text-secondary"
|
|
540
|
+
};
|
|
541
|
+
var ROOM = "-mx-2 px-2 py-1";
|
|
542
|
+
var OneLine = Node2.create({ name: "doc", topNode: true, content: "paragraph" });
|
|
543
|
+
var Paragraph = Node2.create({
|
|
544
|
+
name: "paragraph",
|
|
545
|
+
content: "text*",
|
|
546
|
+
parseHTML: () => [{ tag: "p" }],
|
|
547
|
+
renderHTML: () => ["p", 0]
|
|
548
|
+
});
|
|
549
|
+
var Text = Node2.create({ name: "text" });
|
|
550
|
+
var Undo = Extension3.create({
|
|
551
|
+
name: "inlineTextUndo",
|
|
552
|
+
addProseMirrorPlugins: () => [history()],
|
|
553
|
+
addKeyboardShortcuts() {
|
|
554
|
+
const run = (command) => () => command(this.editor.state, this.editor.view.dispatch);
|
|
555
|
+
return { "Mod-z": run(undo), "Shift-Mod-z": run(redo), "Mod-y": run(redo) };
|
|
556
|
+
}
|
|
557
|
+
});
|
|
558
|
+
var doc = (text) => ({ type: "doc", content: [{ type: "paragraph", content: text ? [{ type: "text", text }] : [] }] });
|
|
559
|
+
var oneLine = (text) => text.replace(/\s+/g, " ").trim();
|
|
560
|
+
function InlineText({ value, placeholder, label, onCommit, onText, onEnter, variant = "title", clearable = false, readOnly = false, className, ref }) {
|
|
561
|
+
const saved = useRef3(value);
|
|
562
|
+
const [empty, setEmpty] = useState3(!value);
|
|
563
|
+
const latest = useRef3({ onEnter, onText, onCommit, clearable });
|
|
564
|
+
latest.current = { onEnter, onText, onCommit, clearable };
|
|
565
|
+
const save = useCallback3(async (text) => {
|
|
566
|
+
const next = oneLine(text);
|
|
567
|
+
if (next === saved.current) return;
|
|
568
|
+
if (!next && !latest.current.clearable) return;
|
|
569
|
+
if (await latest.current.onCommit(next)) saved.current = next;
|
|
570
|
+
}, []);
|
|
571
|
+
const editor = useEditor({
|
|
572
|
+
extensions: [OneLine, Paragraph, Text, Undo],
|
|
573
|
+
content: doc(value),
|
|
574
|
+
editable: !readOnly,
|
|
575
|
+
editorProps: {
|
|
576
|
+
attributes: {
|
|
577
|
+
"aria-label": label,
|
|
578
|
+
role: "textbox",
|
|
579
|
+
"aria-multiline": "false",
|
|
580
|
+
"aria-placeholder": placeholder,
|
|
581
|
+
...readOnly ? { "aria-readonly": "true" } : {},
|
|
582
|
+
class: "outline-none"
|
|
583
|
+
},
|
|
584
|
+
handleKeyDown: (view, event) => {
|
|
585
|
+
if (event.key === "Enter") {
|
|
586
|
+
event.preventDefault();
|
|
587
|
+
void save(view.state.doc.textContent);
|
|
588
|
+
latest.current.onEnter?.();
|
|
589
|
+
return true;
|
|
590
|
+
}
|
|
591
|
+
if (event.key === "Escape") {
|
|
592
|
+
view.dom.blur();
|
|
593
|
+
return true;
|
|
594
|
+
}
|
|
595
|
+
return false;
|
|
596
|
+
},
|
|
597
|
+
// A paste is its plain text on this one line, whatever it was copied from.
|
|
598
|
+
handlePaste: (view, event) => {
|
|
599
|
+
const text = event.clipboardData?.getData("text/plain");
|
|
600
|
+
if (text == null) return false;
|
|
601
|
+
view.dispatch(view.state.tr.insertText(text.replace(/\s+/g, " ")));
|
|
602
|
+
return true;
|
|
603
|
+
}
|
|
604
|
+
},
|
|
605
|
+
onFocus: ({ editor: e }) => latest.current.onText?.(e.getText()),
|
|
606
|
+
onUpdate: ({ editor: e }) => {
|
|
607
|
+
setEmpty(e.isEmpty);
|
|
608
|
+
latest.current.onText?.(e.getText());
|
|
609
|
+
},
|
|
610
|
+
onBlur: ({ editor: e }) => {
|
|
611
|
+
latest.current.onText?.(null);
|
|
612
|
+
if (e.isEmpty && saved.current && !latest.current.clearable) {
|
|
613
|
+
e.commands.setContent(doc(saved.current), { emitUpdate: false });
|
|
614
|
+
setEmpty(false);
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
void save(e.getText());
|
|
618
|
+
}
|
|
619
|
+
}, [readOnly]);
|
|
620
|
+
useEffect3(() => {
|
|
621
|
+
if (!editor || editor.isDestroyed || value === saved.current || editor.isFocused) return;
|
|
622
|
+
if (oneLine(editor.getText()) !== saved.current) return;
|
|
623
|
+
editor.commands.setContent(doc(value), { emitUpdate: false });
|
|
624
|
+
saved.current = value;
|
|
625
|
+
setEmpty(!value);
|
|
626
|
+
}, [editor, value]);
|
|
627
|
+
useImperativeHandle2(ref, () => ({
|
|
628
|
+
focus: (at = "start") => editor?.commands.focus(at)
|
|
629
|
+
}), [editor]);
|
|
630
|
+
return /* @__PURE__ */ jsxs3("div", { className: cn2("relative", VARIANT[variant], className), children: [
|
|
631
|
+
/* @__PURE__ */ jsx4(EditorContent2, { editor, className: cn2(ROOM, !readOnly && "cursor-text") }),
|
|
632
|
+
empty && !readOnly && /* @__PURE__ */ jsx4("span", { "aria-hidden": true, className: "pointer-events-none absolute left-0 top-1 text-text-muted", children: placeholder })
|
|
633
|
+
] });
|
|
634
|
+
}
|
|
635
|
+
|
|
530
636
|
// src/CommentHighlights.ts
|
|
531
|
-
import { Extension as
|
|
637
|
+
import { Extension as Extension4 } from "@tiptap/core";
|
|
532
638
|
import { Plugin as Plugin2, PluginKey as PluginKey2 } from "@tiptap/pm/state";
|
|
533
639
|
import { Decoration as Decoration2, DecorationSet as DecorationSet2 } from "@tiptap/pm/view";
|
|
534
640
|
var commentHighlightsKey = new PluginKey2("commentHighlights");
|
|
@@ -539,7 +645,7 @@ var COMMENT_HIGHLIGHT_CLASSES = {
|
|
|
539
645
|
var QUOTE_WHOLE_MAX = 1e3;
|
|
540
646
|
var QUOTE_END_LENGTH = 150;
|
|
541
647
|
var QUOTE_CONTEXT_LENGTH = 32;
|
|
542
|
-
function placesIn(
|
|
648
|
+
function placesIn(doc2) {
|
|
543
649
|
const places = /* @__PURE__ */ new Map();
|
|
544
650
|
const walk = (parent, parentPos) => {
|
|
545
651
|
parent.forEach((node, offset, index) => {
|
|
@@ -549,7 +655,7 @@ function placesIn(doc) {
|
|
|
549
655
|
if (!node.isTextblock && !node.isLeaf) walk(node, pos + 1);
|
|
550
656
|
});
|
|
551
657
|
};
|
|
552
|
-
walk(
|
|
658
|
+
walk(doc2, 0);
|
|
553
659
|
return places;
|
|
554
660
|
}
|
|
555
661
|
function textOf(block) {
|
|
@@ -578,7 +684,7 @@ function find(text, words, from, context) {
|
|
|
578
684
|
}
|
|
579
685
|
return first;
|
|
580
686
|
}
|
|
581
|
-
function runIn(
|
|
687
|
+
function runIn(doc2, places, ids) {
|
|
582
688
|
const present = ids.map((id) => places.get(id)).filter((p) => !!p);
|
|
583
689
|
if (present.length === 0) return null;
|
|
584
690
|
const byParent = /* @__PURE__ */ new Map();
|
|
@@ -587,7 +693,7 @@ function runIn(doc, places, ids) {
|
|
|
587
693
|
const low = Math.min(...group.map((p) => p.index));
|
|
588
694
|
const high = Math.max(...group.map((p) => p.index));
|
|
589
695
|
const contentStart = group[0].parent;
|
|
590
|
-
const parent = contentStart === 0 ?
|
|
696
|
+
const parent = contentStart === 0 ? doc2 : doc2.nodeAt(contentStart - 1);
|
|
591
697
|
if (!parent) return group;
|
|
592
698
|
const run = [];
|
|
593
699
|
parent.forEach((node, offset, index) => {
|
|
@@ -595,8 +701,8 @@ function runIn(doc, places, ids) {
|
|
|
595
701
|
});
|
|
596
702
|
return run;
|
|
597
703
|
}
|
|
598
|
-
function placeOf(
|
|
599
|
-
const run = runIn(
|
|
704
|
+
function placeOf(doc2, anchor, places = placesIn(doc2)) {
|
|
705
|
+
const run = runIn(doc2, places, anchor.blocks);
|
|
600
706
|
if (!run) return { state: "detached" };
|
|
601
707
|
const from = run[0].pos;
|
|
602
708
|
const to = run[run.length - 1].pos + run[run.length - 1].node.nodeSize;
|
|
@@ -626,7 +732,7 @@ function placeOf(doc, anchor, places = placesIn(doc)) {
|
|
|
626
732
|
if (endAt === -1 || quote.end === "") return reworded;
|
|
627
733
|
return { state: "resolved", from: a.starts[startAt], to: b.ends[endAt + quote.end.length - 1], words: true };
|
|
628
734
|
}
|
|
629
|
-
var CommentHighlights =
|
|
735
|
+
var CommentHighlights = Extension4.create({
|
|
630
736
|
name: "commentHighlights",
|
|
631
737
|
addOptions() {
|
|
632
738
|
return { onSelect: null };
|
|
@@ -723,10 +829,10 @@ function offsetIn(block, pos) {
|
|
|
723
829
|
return at === -1 ? block.starts.length : at;
|
|
724
830
|
}
|
|
725
831
|
function anchorOfSelection(editor) {
|
|
726
|
-
const { doc, selection } = editor.state;
|
|
832
|
+
const { doc: doc2, selection } = editor.state;
|
|
727
833
|
if (selection.empty) return null;
|
|
728
834
|
const { $from, $to } = selection;
|
|
729
|
-
const places = placesIn(
|
|
835
|
+
const places = placesIn(doc2);
|
|
730
836
|
const around = (depth) => {
|
|
731
837
|
for (let d = depth; d > 0; d--) {
|
|
732
838
|
const id = $from.node(d).attrs.blockId;
|
|
@@ -785,7 +891,7 @@ function anchorOfSelection(editor) {
|
|
|
785
891
|
}
|
|
786
892
|
|
|
787
893
|
// src/PastedImages.ts
|
|
788
|
-
import { Extension as
|
|
894
|
+
import { Extension as Extension5 } from "@tiptap/core";
|
|
789
895
|
import { Plugin as Plugin3, PluginKey as PluginKey3 } from "@tiptap/pm/state";
|
|
790
896
|
var IMAGE_EXTENSIONS = {
|
|
791
897
|
"image/png": "png",
|
|
@@ -821,7 +927,7 @@ function pastedImages(source, at = /* @__PURE__ */ new Date()) {
|
|
|
821
927
|
(file) => hasUsableName(file.name) ? file : new File([file], pastedImageName(file.type, at, generated++), { type: file.type, lastModified: file.lastModified })
|
|
822
928
|
);
|
|
823
929
|
}
|
|
824
|
-
var PastedImages =
|
|
930
|
+
var PastedImages = Extension5.create({
|
|
825
931
|
name: "pastedImages",
|
|
826
932
|
addOptions() {
|
|
827
933
|
return { onImages: () => false };
|
|
@@ -843,7 +949,7 @@ var PastedImages = Extension4.create({
|
|
|
843
949
|
});
|
|
844
950
|
|
|
845
951
|
// src/PastedMarkdown.ts
|
|
846
|
-
import { Extension as
|
|
952
|
+
import { Extension as Extension6 } from "@tiptap/core";
|
|
847
953
|
import { Slice } from "@tiptap/pm/model";
|
|
848
954
|
import { Plugin as Plugin4, PluginKey as PluginKey4 } from "@tiptap/pm/state";
|
|
849
955
|
function inTableCell($context) {
|
|
@@ -854,7 +960,7 @@ function inTableCell($context) {
|
|
|
854
960
|
return false;
|
|
855
961
|
}
|
|
856
962
|
var hasTable = (blocks) => blocks.some((block) => block.type === "table" || hasTable(block.content ?? []));
|
|
857
|
-
var PastedMarkdown =
|
|
963
|
+
var PastedMarkdown = Extension6.create({
|
|
858
964
|
name: "pastedMarkdown",
|
|
859
965
|
addOptions() {
|
|
860
966
|
return { read: () => void 0 };
|
|
@@ -911,7 +1017,7 @@ import { Selection } from "@tiptap/pm/state";
|
|
|
911
1017
|
import { MenuItem, MenuSub } from "@estiva-app/ui";
|
|
912
1018
|
|
|
913
1019
|
// src/ComposerTriggers.tsx
|
|
914
|
-
import { Extension as
|
|
1020
|
+
import { Extension as Extension7 } from "@tiptap/core";
|
|
915
1021
|
import { PluginKey as PluginKey5 } from "@tiptap/pm/state";
|
|
916
1022
|
import Mention from "@tiptap/extension-mention";
|
|
917
1023
|
import Suggestion from "@tiptap/suggestion";
|
|
@@ -920,7 +1026,7 @@ import { Avatar } from "@estiva-app/ui";
|
|
|
920
1026
|
import { EnterHint } from "@estiva-app/ui";
|
|
921
1027
|
import { inlineChipClassName } from "@estiva-app/ui";
|
|
922
1028
|
import { WithTooltip } from "@estiva-app/ui";
|
|
923
|
-
import { jsx as
|
|
1029
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
924
1030
|
var PEOPLE_LIMIT = 6;
|
|
925
1031
|
function filterPeople(people, query) {
|
|
926
1032
|
const q = query.toLowerCase();
|
|
@@ -938,8 +1044,8 @@ function peopleMenu(urgent) {
|
|
|
938
1044
|
row: (person) => ({
|
|
939
1045
|
label: person.name,
|
|
940
1046
|
description: person.description,
|
|
941
|
-
leading: person.avatar ?? /* @__PURE__ */
|
|
942
|
-
hint: /* @__PURE__ */
|
|
1047
|
+
leading: person.avatar ?? /* @__PURE__ */ jsx5(Avatar, { size: 32, alt: person.name }),
|
|
1048
|
+
hint: /* @__PURE__ */ jsx5(EnterHint, {}),
|
|
943
1049
|
size: "tall"
|
|
944
1050
|
})
|
|
945
1051
|
};
|
|
@@ -1068,9 +1174,9 @@ var CaptionedReference = Mention.extend({
|
|
|
1068
1174
|
return ReactNodeViewRenderer(
|
|
1069
1175
|
({ node }) => (
|
|
1070
1176
|
// The caption is cut at 24ch, so the whole of it is on hover, in the package's tooltip (UIG-14) — as Peek's sent chip has it.
|
|
1071
|
-
/* @__PURE__ */
|
|
1072
|
-
/* @__PURE__ */
|
|
1073
|
-
/* @__PURE__ */
|
|
1177
|
+
/* @__PURE__ */ jsx5(NodeViewWrapper, { as: "span", children: /* @__PURE__ */ jsx5(WithTooltip, { inline: true, label: captionOf(node.attrs.label, node.attrs.snippet), children: /* @__PURE__ */ jsxs4("span", { className: inlineChipClassName("neutral", "max-w-[24ch] cursor-default"), children: [
|
|
1178
|
+
/* @__PURE__ */ jsx5("span", { className: "flex items-center justify-center w-4 h-4 shrink-0 text-text-secondary", children: iconFor?.(node.attrs.uri ?? null) ?? icon }),
|
|
1179
|
+
/* @__PURE__ */ jsx5("span", { className: "truncate", children: captionOf(node.attrs.label, node.attrs.snippet) })
|
|
1074
1180
|
] }) }) })
|
|
1075
1181
|
),
|
|
1076
1182
|
{ as: "span" }
|
|
@@ -1093,11 +1199,11 @@ function referenceMenu({ ariaLabel, sectionLabel, icon, iconFor }) {
|
|
|
1093
1199
|
return groups;
|
|
1094
1200
|
},
|
|
1095
1201
|
itemKey: (item) => `reference-${item.id}`,
|
|
1096
|
-
row: (item) => ({ leading: item.icon ?? iconFor?.(item.uri) ?? icon, label: captionOf(item.label, item.snippet), description: item.description, hint: /* @__PURE__ */
|
|
1202
|
+
row: (item) => ({ leading: item.icon ?? iconFor?.(item.uri) ?? icon, label: captionOf(item.label, item.snippet), description: item.description, hint: /* @__PURE__ */ jsx5(EnterHint, {}) })
|
|
1097
1203
|
};
|
|
1098
1204
|
}
|
|
1099
1205
|
var listed = (options, query) => options.sections ? options.sections(query).flatMap((section) => section.items.map((item) => ({ ...item, section: section.label }))) : filterReferences(options.items(), query);
|
|
1100
|
-
var ReferenceTrigger =
|
|
1206
|
+
var ReferenceTrigger = Extension7.create({
|
|
1101
1207
|
name: "referenceTrigger",
|
|
1102
1208
|
addOptions() {
|
|
1103
1209
|
return { items: () => [], nodeName: "captionedReference", ariaLabel: "References", sectionLabel: "References", icon: null };
|
|
@@ -1213,7 +1319,7 @@ function filterSlashSections(sections, query) {
|
|
|
1213
1319
|
const q = query.toLowerCase();
|
|
1214
1320
|
return sections.map((section) => ({ ...section, commands: q ? section.commands.filter((command) => matches(command, q)) : section.commands }));
|
|
1215
1321
|
}
|
|
1216
|
-
var SlashCommands =
|
|
1322
|
+
var SlashCommands = Extension7.create({
|
|
1217
1323
|
name: "slashCommands",
|
|
1218
1324
|
addOptions() {
|
|
1219
1325
|
return { sections: [formatSection()] };
|
|
@@ -1247,7 +1353,7 @@ var SlashCommands = Extension6.create({
|
|
|
1247
1353
|
});
|
|
1248
1354
|
|
|
1249
1355
|
// src/EditorBlockHandle.tsx
|
|
1250
|
-
import { Fragment, jsx as
|
|
1356
|
+
import { Fragment, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1251
1357
|
function editorBlocks(view) {
|
|
1252
1358
|
const out = [];
|
|
1253
1359
|
view.state.doc.forEach((node, pos) => {
|
|
@@ -1314,8 +1420,8 @@ function EditorBlockHandle({ editor, turnInto = turnIntoRows, actions, children,
|
|
|
1314
1420
|
const node = pos === void 0 ? null : editor.state.doc.nodeAt(pos);
|
|
1315
1421
|
if (pos === void 0 || !node) return null;
|
|
1316
1422
|
const turnRows = typeof turnInto === "function" ? turnInto(node, editor) : node.isTextblock ? turnInto : [];
|
|
1317
|
-
return /* @__PURE__ */
|
|
1318
|
-
turnRows.length > 0 && /* @__PURE__ */
|
|
1423
|
+
return /* @__PURE__ */ jsxs5(Fragment, { children: [
|
|
1424
|
+
turnRows.length > 0 && /* @__PURE__ */ jsx6(MenuSub, { label: "Turn into", children: turnRows.map((row) => /* @__PURE__ */ jsx6(
|
|
1319
1425
|
MenuItem,
|
|
1320
1426
|
{
|
|
1321
1427
|
label: row.label,
|
|
@@ -1327,8 +1433,8 @@ function EditorBlockHandle({ editor, turnInto = turnIntoRows, actions, children,
|
|
|
1327
1433
|
},
|
|
1328
1434
|
row.label
|
|
1329
1435
|
)) }),
|
|
1330
|
-
/* @__PURE__ */
|
|
1331
|
-
/* @__PURE__ */
|
|
1436
|
+
/* @__PURE__ */ jsx6(MenuItem, { label: "Duplicate", leading: /* @__PURE__ */ jsx6(IconCopy, { size: 16, stroke: 1.5, className: "text-text-secondary" }), onClick: () => duplicateBlock(editor, pos) }),
|
|
1437
|
+
/* @__PURE__ */ jsx6(MenuItem, { label: "Delete", destructive: true, leading: /* @__PURE__ */ jsx6(IconTrash, { size: 16, stroke: 1.5, className: "text-error-default" }), onClick: () => deleteBlock(editor, pos) })
|
|
1332
1438
|
] });
|
|
1333
1439
|
},
|
|
1334
1440
|
startDrag: (block, event) => {
|
|
@@ -1350,7 +1456,7 @@ function EditorBlockHandle({ editor, turnInto = turnIntoRows, actions, children,
|
|
|
1350
1456
|
}
|
|
1351
1457
|
};
|
|
1352
1458
|
}, [editor, turnInto]);
|
|
1353
|
-
return /* @__PURE__ */
|
|
1459
|
+
return /* @__PURE__ */ jsx6(BlockHandle, { editing, actions, className, children });
|
|
1354
1460
|
}
|
|
1355
1461
|
var LISTS = ["bulletList", "orderedList"];
|
|
1356
1462
|
var isList = (node) => LISTS.includes(node.type.name);
|
|
@@ -1456,14 +1562,14 @@ function turnIntoRows(node, editor) {
|
|
|
1456
1562
|
}
|
|
1457
1563
|
|
|
1458
1564
|
// src/EditorTableControls.tsx
|
|
1459
|
-
import { useCallback as
|
|
1565
|
+
import { useCallback as useCallback4, useEffect as useEffect4, useRef as useRef4, useState as useState4 } from "react";
|
|
1460
1566
|
import { TextSelection } from "@tiptap/pm/state";
|
|
1461
1567
|
import { addColumnAfter, addColumnBefore, addRowAfter, addRowBefore, deleteColumn, deleteRow, deleteTable, toggleHeader } from "@tiptap/pm/tables";
|
|
1462
1568
|
import { IconColumnInsertLeft, IconColumnInsertRight, IconGripHorizontal, IconGripVertical, IconPlus, IconRowInsertBottom, IconRowInsertTop, IconTrash as IconTrash2 } from "@tabler/icons-react";
|
|
1463
|
-
import { cn as
|
|
1569
|
+
import { cn as cn3 } from "@estiva-app/ui";
|
|
1464
1570
|
import { IconButton as IconButton2 } from "@estiva-app/ui";
|
|
1465
1571
|
import { Menu, MenuItem as MenuItem2, MenuSeparator } from "@estiva-app/ui";
|
|
1466
|
-
import { Fragment as Fragment2, jsx as
|
|
1572
|
+
import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1467
1573
|
function inCell(editor, cell, command) {
|
|
1468
1574
|
const { view } = editor;
|
|
1469
1575
|
if (!view.dom.contains(cell)) return false;
|
|
@@ -1509,13 +1615,13 @@ function place(frame, { table, row, cell }) {
|
|
|
1509
1615
|
}
|
|
1510
1616
|
var ICON = { size: 16, stroke: 1.5, className: "text-text-secondary" };
|
|
1511
1617
|
var keepFocus = (e) => e.preventDefault();
|
|
1512
|
-
var HANDLE_BOX =
|
|
1618
|
+
var HANDLE_BOX = cn3(FLOATING_SURFACE_CLASSES, "shadow-none");
|
|
1513
1619
|
function EditorTableControls({ editor, children, className }) {
|
|
1514
|
-
const frame =
|
|
1515
|
-
const [hovered, setHovered] =
|
|
1516
|
-
const [menu, setMenu] =
|
|
1620
|
+
const frame = useRef4(null);
|
|
1621
|
+
const [hovered, setHovered] = useState4(null);
|
|
1622
|
+
const [menu, setMenu] = useState4(null);
|
|
1517
1623
|
const editable = !!editor && editor.isEditable;
|
|
1518
|
-
const follow =
|
|
1624
|
+
const follow = useCallback4(
|
|
1519
1625
|
(target) => {
|
|
1520
1626
|
if (!editor || !frame.current || !(target instanceof Element)) return;
|
|
1521
1627
|
if (target.closest("[data-table-control]")) return;
|
|
@@ -1531,7 +1637,7 @@ function EditorTableControls({ editor, children, className }) {
|
|
|
1531
1637
|
},
|
|
1532
1638
|
[editor]
|
|
1533
1639
|
);
|
|
1534
|
-
|
|
1640
|
+
useEffect4(() => {
|
|
1535
1641
|
if (!editor) return;
|
|
1536
1642
|
const changed = ({ transaction }) => {
|
|
1537
1643
|
if (transaction.docChanged && !menu) setHovered(null);
|
|
@@ -1547,11 +1653,11 @@ function EditorTableControls({ editor, children, className }) {
|
|
|
1547
1653
|
setMenu(null);
|
|
1548
1654
|
setHovered(null);
|
|
1549
1655
|
};
|
|
1550
|
-
return /* @__PURE__ */
|
|
1656
|
+
return /* @__PURE__ */ jsxs6(
|
|
1551
1657
|
"div",
|
|
1552
1658
|
{
|
|
1553
1659
|
ref: frame,
|
|
1554
|
-
className:
|
|
1660
|
+
className: cn3("relative", className),
|
|
1555
1661
|
onMouseMove: (e) => {
|
|
1556
1662
|
if (!menu) follow(e.target);
|
|
1557
1663
|
},
|
|
@@ -1560,39 +1666,39 @@ function EditorTableControls({ editor, children, className }) {
|
|
|
1560
1666
|
},
|
|
1561
1667
|
children: [
|
|
1562
1668
|
children,
|
|
1563
|
-
shown && editor && /* @__PURE__ */
|
|
1564
|
-
/* @__PURE__ */
|
|
1669
|
+
shown && editor && /* @__PURE__ */ jsxs6(Fragment2, { children: [
|
|
1670
|
+
/* @__PURE__ */ jsx7("div", { "data-table-control": true, className: cn3(HANDLE_BOX, "absolute -translate-x-1/2 -translate-y-1/2"), style: { left: shown.tableBox.left, top: shown.rowBox.top + shown.rowBox.height / 2 }, children: /* @__PURE__ */ jsxs6(
|
|
1565
1671
|
Menu,
|
|
1566
1672
|
{
|
|
1567
1673
|
open: menu === "row",
|
|
1568
1674
|
onOpenChange: (open) => setMenu(open ? "row" : null),
|
|
1569
|
-
trigger: /* @__PURE__ */
|
|
1675
|
+
trigger: /* @__PURE__ */ jsx7(IconButton2, { "aria-label": "Row menu", tooltip: "Row", className: "h-6 w-4 p-0", children: /* @__PURE__ */ jsx7(IconGripVertical, { size: 16, stroke: 1.5 }) }),
|
|
1570
1676
|
children: [
|
|
1571
|
-
!isHeaderRow(shown.row) && /* @__PURE__ */
|
|
1572
|
-
/* @__PURE__ */
|
|
1573
|
-
/* @__PURE__ */
|
|
1574
|
-
/* @__PURE__ */
|
|
1575
|
-
/* @__PURE__ */
|
|
1677
|
+
!isHeaderRow(shown.row) && /* @__PURE__ */ jsx7(MenuItem2, { label: "Insert above", leading: /* @__PURE__ */ jsx7(IconRowInsertTop, { ...ICON }), onClick: run(() => inCell(editor, shown.cell, addRowBefore)) }),
|
|
1678
|
+
/* @__PURE__ */ jsx7(MenuItem2, { label: "Insert below", leading: /* @__PURE__ */ jsx7(IconRowInsertBottom, { ...ICON }), onClick: run(() => inCell(editor, shown.cell, addRowAfter)) }),
|
|
1679
|
+
/* @__PURE__ */ jsx7(MenuSeparator, {}),
|
|
1680
|
+
/* @__PURE__ */ jsx7(MenuItem2, { label: "Delete", destructive: true, leading: /* @__PURE__ */ jsx7(IconTrash2, { size: 16, stroke: 1.5, className: "text-error-default" }), onClick: run(() => deleteTableRow(editor, shown.cell)) }),
|
|
1681
|
+
/* @__PURE__ */ jsx7(MenuItem2, { label: "Delete table", destructive: true, leading: /* @__PURE__ */ jsx7(IconTrash2, { size: 16, stroke: 1.5, className: "text-error-default" }), onClick: run(() => inCell(editor, shown.cell, deleteTable)) })
|
|
1576
1682
|
]
|
|
1577
1683
|
}
|
|
1578
1684
|
) }),
|
|
1579
|
-
/* @__PURE__ */
|
|
1685
|
+
/* @__PURE__ */ jsx7("div", { "data-table-control": true, className: cn3(HANDLE_BOX, "absolute -translate-x-1/2 -translate-y-1/2"), style: { left: shown.columnBox.left + shown.columnBox.width / 2, top: shown.tableBox.top }, children: /* @__PURE__ */ jsxs6(
|
|
1580
1686
|
Menu,
|
|
1581
1687
|
{
|
|
1582
1688
|
open: menu === "column",
|
|
1583
1689
|
onOpenChange: (open) => setMenu(open ? "column" : null),
|
|
1584
|
-
trigger: /* @__PURE__ */
|
|
1690
|
+
trigger: /* @__PURE__ */ jsx7(IconButton2, { "aria-label": "Column menu", tooltip: "Column", className: "h-4 w-6 p-0", children: /* @__PURE__ */ jsx7(IconGripHorizontal, { size: 16, stroke: 1.5 }) }),
|
|
1585
1691
|
children: [
|
|
1586
|
-
/* @__PURE__ */
|
|
1587
|
-
/* @__PURE__ */
|
|
1588
|
-
/* @__PURE__ */
|
|
1589
|
-
/* @__PURE__ */
|
|
1590
|
-
/* @__PURE__ */
|
|
1692
|
+
/* @__PURE__ */ jsx7(MenuItem2, { label: "Insert left", leading: /* @__PURE__ */ jsx7(IconColumnInsertLeft, { ...ICON }), onClick: run(() => inCell(editor, shown.cell, addColumnBefore)) }),
|
|
1693
|
+
/* @__PURE__ */ jsx7(MenuItem2, { label: "Insert right", leading: /* @__PURE__ */ jsx7(IconColumnInsertRight, { ...ICON }), onClick: run(() => inCell(editor, shown.cell, addColumnAfter)) }),
|
|
1694
|
+
/* @__PURE__ */ jsx7(MenuSeparator, {}),
|
|
1695
|
+
/* @__PURE__ */ jsx7(MenuItem2, { label: "Delete", destructive: true, leading: /* @__PURE__ */ jsx7(IconTrash2, { size: 16, stroke: 1.5, className: "text-error-default" }), onClick: run(() => deleteTableColumn(editor, shown.cell)) }),
|
|
1696
|
+
/* @__PURE__ */ jsx7(MenuItem2, { label: "Delete table", destructive: true, leading: /* @__PURE__ */ jsx7(IconTrash2, { size: 16, stroke: 1.5, className: "text-error-default" }), onClick: run(() => inCell(editor, shown.cell, deleteTable)) })
|
|
1591
1697
|
]
|
|
1592
1698
|
}
|
|
1593
1699
|
) }),
|
|
1594
|
-
shown.row === shown.table.rows[shown.table.rows.length - 1] && /* @__PURE__ */
|
|
1595
|
-
shown.cell === shown.row.cells[shown.row.cells.length - 1] && /* @__PURE__ */
|
|
1700
|
+
shown.row === shown.table.rows[shown.table.rows.length - 1] && /* @__PURE__ */ jsx7("div", { "data-table-control": true, className: cn3(HANDLE_BOX, "absolute flex h-4"), style: { left: shown.tableBox.left, top: shown.tableBox.top + shown.tableBox.height, width: shown.tableBox.width }, children: /* @__PURE__ */ jsx7(IconButton2, { "aria-label": "Add row", tooltip: "Add row", className: "h-full w-full p-0", onMouseDown: keepFocus, onClick: run(() => appendTableRow(editor, shown.table)), children: /* @__PURE__ */ jsx7(IconPlus, { size: 12, stroke: 1.5 }) }) }),
|
|
1701
|
+
shown.cell === shown.row.cells[shown.row.cells.length - 1] && /* @__PURE__ */ jsx7("div", { "data-table-control": true, className: cn3(HANDLE_BOX, "absolute flex w-4"), style: { left: shown.tableBox.left + shown.tableBox.width, top: shown.tableBox.top, height: shown.tableBox.height }, children: /* @__PURE__ */ jsx7(IconButton2, { "aria-label": "Add column", tooltip: "Add column", className: "h-full w-full p-0", onMouseDown: keepFocus, onClick: run(() => appendTableColumn(editor, shown.table)), children: /* @__PURE__ */ jsx7(IconPlus, { size: 12, stroke: 1.5 }) }) })
|
|
1596
1702
|
] })
|
|
1597
1703
|
]
|
|
1598
1704
|
}
|
|
@@ -1600,7 +1706,7 @@ function EditorTableControls({ editor, children, className }) {
|
|
|
1600
1706
|
}
|
|
1601
1707
|
|
|
1602
1708
|
// src/BlockNodes.tsx
|
|
1603
|
-
import { Extension as
|
|
1709
|
+
import { Extension as Extension11, InputRule, Node as Node3 } from "@tiptap/core";
|
|
1604
1710
|
import { DOMSerializer } from "@tiptap/pm/model";
|
|
1605
1711
|
import { Plugin as Plugin8, PluginKey as PluginKey9 } from "@tiptap/pm/state";
|
|
1606
1712
|
import { Mapping, ReplaceAroundStep } from "@tiptap/pm/transform";
|
|
@@ -1609,15 +1715,15 @@ import { Checkbox } from "@estiva-app/ui";
|
|
|
1609
1715
|
import { calloutLook } from "@estiva-app/ui";
|
|
1610
1716
|
|
|
1611
1717
|
// src/ReferenceMenu.tsx
|
|
1612
|
-
import { useCallback as
|
|
1613
|
-
import { Extension as
|
|
1718
|
+
import { useCallback as useCallback5 } from "react";
|
|
1719
|
+
import { Extension as Extension10 } from "@tiptap/core";
|
|
1614
1720
|
import { useEditorState } from "@tiptap/react";
|
|
1615
1721
|
import { NodeSelection as NodeSelection2, Plugin as Plugin7, PluginKey as PluginKey8, TextSelection as TextSelection2 } from "@tiptap/pm/state";
|
|
1616
1722
|
import { ReplaceStep } from "@tiptap/pm/transform";
|
|
1617
1723
|
import { IconCheck } from "@tabler/icons-react";
|
|
1618
1724
|
|
|
1619
1725
|
// src/LinkChips.ts
|
|
1620
|
-
import { Extension as
|
|
1726
|
+
import { Extension as Extension8 } from "@tiptap/core";
|
|
1621
1727
|
import { closeHistory } from "@tiptap/pm/history";
|
|
1622
1728
|
import { Plugin as Plugin5, PluginKey as PluginKey6 } from "@tiptap/pm/state";
|
|
1623
1729
|
var key = new PluginKey6("linkChips");
|
|
@@ -1638,10 +1744,10 @@ function urlRuns(text) {
|
|
|
1638
1744
|
}
|
|
1639
1745
|
return out;
|
|
1640
1746
|
}
|
|
1641
|
-
function findLinkChips(
|
|
1747
|
+
function findLinkChips(doc2, selection, referenceOf, pasted = []) {
|
|
1642
1748
|
const found = { chips: [], fills: [], open: [] };
|
|
1643
1749
|
const open = /* @__PURE__ */ new Set();
|
|
1644
|
-
|
|
1750
|
+
doc2.descendants((node, pos) => {
|
|
1645
1751
|
if (node.type.spec.code) return false;
|
|
1646
1752
|
if (node.type.name === "reference") {
|
|
1647
1753
|
const href = typeof node.attrs.href === "string" ? node.attrs.href : "";
|
|
@@ -1695,7 +1801,7 @@ function refreshLinkChips(editor) {
|
|
|
1695
1801
|
const tr = apply(editor.state, findLinkChips(editor.state.doc, editor.state.selection, chips.options.referenceOf, chips.pasted));
|
|
1696
1802
|
if (tr) editor.view.dispatch(tr);
|
|
1697
1803
|
}
|
|
1698
|
-
var LinkChips =
|
|
1804
|
+
var LinkChips = Extension8.create({
|
|
1699
1805
|
name: "linkChips",
|
|
1700
1806
|
addOptions() {
|
|
1701
1807
|
return { referenceOf: null, ask: null, limit: 24 };
|
|
@@ -1768,18 +1874,18 @@ import { MenuItem as MenuItem3, MenuSection, MenuSeparator as MenuSeparator2 } f
|
|
|
1768
1874
|
import { Popover as Popover2 } from "@estiva-app/ui";
|
|
1769
1875
|
|
|
1770
1876
|
// src/ReferenceCards.ts
|
|
1771
|
-
import { Extension as
|
|
1877
|
+
import { Extension as Extension9 } from "@tiptap/core";
|
|
1772
1878
|
import { NodeSelection, Plugin as Plugin6, PluginKey as PluginKey7 } from "@tiptap/pm/state";
|
|
1773
1879
|
import { Decoration as Decoration3, DecorationSet as DecorationSet3 } from "@tiptap/pm/view";
|
|
1774
|
-
import { useEffect as
|
|
1880
|
+
import { useEffect as useEffect5, useState as useState5 } from "react";
|
|
1775
1881
|
function layoutOf(raw) {
|
|
1776
1882
|
if (typeof raw !== "string" || raw === "" || raw === "none") return void 0;
|
|
1777
1883
|
return raw === "detailed" ? "detailed" : "compact";
|
|
1778
1884
|
}
|
|
1779
|
-
function referenceCardPlacements(
|
|
1885
|
+
function referenceCardPlacements(doc2) {
|
|
1780
1886
|
const out = [];
|
|
1781
1887
|
const seen = /* @__PURE__ */ new Map();
|
|
1782
|
-
|
|
1888
|
+
doc2.descendants((node, pos, parent) => {
|
|
1783
1889
|
if (!node.isTextblock) return true;
|
|
1784
1890
|
const cards = [];
|
|
1785
1891
|
node.forEach((child) => {
|
|
@@ -1812,16 +1918,16 @@ function elementFor(storage, slotKey) {
|
|
|
1812
1918
|
function storageOf(editor) {
|
|
1813
1919
|
return editor.storage.referenceCards;
|
|
1814
1920
|
}
|
|
1815
|
-
var ReferenceCards =
|
|
1921
|
+
var ReferenceCards = Extension9.create({
|
|
1816
1922
|
name: "referenceCards",
|
|
1817
1923
|
addStorage() {
|
|
1818
1924
|
return { elements: /* @__PURE__ */ new Map() };
|
|
1819
1925
|
},
|
|
1820
1926
|
addProseMirrorPlugins() {
|
|
1821
1927
|
const storage = this.storage;
|
|
1822
|
-
const decorate = (
|
|
1823
|
-
|
|
1824
|
-
referenceCardPlacements(
|
|
1928
|
+
const decorate = (doc2) => DecorationSet3.create(
|
|
1929
|
+
doc2,
|
|
1930
|
+
referenceCardPlacements(doc2).map(
|
|
1825
1931
|
(p) => Decoration3.widget(p.pos, () => elementFor(storage, p.key), {
|
|
1826
1932
|
key: p.key,
|
|
1827
1933
|
side: 1,
|
|
@@ -1844,8 +1950,8 @@ var ReferenceCards = Extension8.create({
|
|
|
1844
1950
|
}
|
|
1845
1951
|
});
|
|
1846
1952
|
function useReferenceCards(editor) {
|
|
1847
|
-
const [slots, setSlots] =
|
|
1848
|
-
|
|
1953
|
+
const [slots, setSlots] = useState5([]);
|
|
1954
|
+
useEffect5(() => {
|
|
1849
1955
|
if (!editor) return;
|
|
1850
1956
|
const storage = storageOf(editor);
|
|
1851
1957
|
if (!storage) return;
|
|
@@ -1910,7 +2016,7 @@ function setReferenceCardAt(editor, pos, layout) {
|
|
|
1910
2016
|
}
|
|
1911
2017
|
|
|
1912
2018
|
// src/ReferenceMenu.tsx
|
|
1913
|
-
import { Fragment as Fragment3, jsx as
|
|
2019
|
+
import { Fragment as Fragment3, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1914
2020
|
var key3 = new PluginKey8("referenceMenu");
|
|
1915
2021
|
var LAYOUTS = [
|
|
1916
2022
|
{ layout: "none", label: "None" },
|
|
@@ -1990,7 +2096,7 @@ function caretAfter(state, pos) {
|
|
|
1990
2096
|
const node = state.doc.nodeAt(pos);
|
|
1991
2097
|
return state.tr.setSelection(TextSelection2.create(state.doc, pos + (node?.nodeSize ?? 1)));
|
|
1992
2098
|
}
|
|
1993
|
-
var ReferenceMenu =
|
|
2099
|
+
var ReferenceMenu = Extension10.create({
|
|
1994
2100
|
name: "referenceMenu",
|
|
1995
2101
|
// Before the editor's own keys, so Enter on a highlighted row is the row's, not a new line.
|
|
1996
2102
|
priority: 1e3,
|
|
@@ -2072,7 +2178,7 @@ function ReferenceMenuView({ editor }) {
|
|
|
2072
2178
|
return { pos: open.pos, active: open.active, named: !!node.attrs.uri, layout };
|
|
2073
2179
|
}
|
|
2074
2180
|
});
|
|
2075
|
-
const keepFocus2 =
|
|
2181
|
+
const keepFocus2 = useCallback5((list) => {
|
|
2076
2182
|
const panel = list?.closest('[role="dialog"]');
|
|
2077
2183
|
if (!panel) return;
|
|
2078
2184
|
const keep = (event) => event.preventDefault();
|
|
@@ -2089,7 +2195,7 @@ function ReferenceMenuView({ editor }) {
|
|
|
2089
2195
|
};
|
|
2090
2196
|
return (
|
|
2091
2197
|
// finalFocus={false}: focus never left the text.
|
|
2092
|
-
/* @__PURE__ */
|
|
2198
|
+
/* @__PURE__ */ jsx8(
|
|
2093
2199
|
Popover2,
|
|
2094
2200
|
{
|
|
2095
2201
|
anchor,
|
|
@@ -2101,8 +2207,8 @@ function ReferenceMenuView({ editor }) {
|
|
|
2101
2207
|
align: "left",
|
|
2102
2208
|
ariaLabel: "Link",
|
|
2103
2209
|
finalFocus: false,
|
|
2104
|
-
children: shown && /* @__PURE__ */
|
|
2105
|
-
opens && /* @__PURE__ */
|
|
2210
|
+
children: shown && /* @__PURE__ */ jsxs7("div", { ref: keepFocus2, role: "menu", "aria-label": "Link", className: "flex flex-col gap-0.5", children: [
|
|
2211
|
+
opens && /* @__PURE__ */ jsx8(
|
|
2106
2212
|
MenuItem3,
|
|
2107
2213
|
{
|
|
2108
2214
|
role: "menuitem",
|
|
@@ -2115,9 +2221,9 @@ function ReferenceMenuView({ editor }) {
|
|
|
2115
2221
|
}
|
|
2116
2222
|
}
|
|
2117
2223
|
),
|
|
2118
|
-
shown.named && /* @__PURE__ */
|
|
2119
|
-
opens && /* @__PURE__ */
|
|
2120
|
-
/* @__PURE__ */
|
|
2224
|
+
shown.named && /* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
2225
|
+
opens && /* @__PURE__ */ jsx8(MenuSeparator2, {}),
|
|
2226
|
+
/* @__PURE__ */ jsx8("div", { role: "group", "aria-label": "Card", children: /* @__PURE__ */ jsx8(MenuSection, { label: "Card", children: LAYOUTS.map(({ layout, label }, i) => /* @__PURE__ */ jsx8(
|
|
2121
2227
|
MenuItem3,
|
|
2122
2228
|
{
|
|
2123
2229
|
role: "menuitemradio",
|
|
@@ -2125,7 +2231,7 @@ function ReferenceMenuView({ editor }) {
|
|
|
2125
2231
|
tabIndex: -1,
|
|
2126
2232
|
label,
|
|
2127
2233
|
selected: shown.active === i + (opens ? 1 : 0),
|
|
2128
|
-
trailing: shown.layout === layout ? /* @__PURE__ */
|
|
2234
|
+
trailing: shown.layout === layout ? /* @__PURE__ */ jsx8(IconCheck, { size: 16, "aria-hidden": true }) : void 0,
|
|
2129
2235
|
onMouseDown: (event) => {
|
|
2130
2236
|
event.preventDefault();
|
|
2131
2237
|
run(layout);
|
|
@@ -2141,7 +2247,7 @@ function ReferenceMenuView({ editor }) {
|
|
|
2141
2247
|
}
|
|
2142
2248
|
|
|
2143
2249
|
// src/BlockNodes.tsx
|
|
2144
|
-
import { jsx as
|
|
2250
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
2145
2251
|
var BLOCK_TYPES = [
|
|
2146
2252
|
"paragraph",
|
|
2147
2253
|
"heading",
|
|
@@ -2174,9 +2280,9 @@ function holdsText(node) {
|
|
|
2174
2280
|
});
|
|
2175
2281
|
return found;
|
|
2176
2282
|
}
|
|
2177
|
-
function claimsIn(
|
|
2283
|
+
function claimsIn(doc2) {
|
|
2178
2284
|
const claims = /* @__PURE__ */ new Map();
|
|
2179
|
-
|
|
2285
|
+
doc2.descendants((node, pos, parent) => {
|
|
2180
2286
|
const fixed = node.type.name === "unknownBlock";
|
|
2181
2287
|
if (!fixed && !BLOCK_TYPE_SET.has(node.type.name)) return;
|
|
2182
2288
|
if (parent?.type.name === "listItem" && LISTS2.has(node.type.name)) return;
|
|
@@ -2211,8 +2317,8 @@ function textStart({ pos, node }) {
|
|
|
2211
2317
|
}
|
|
2212
2318
|
return start;
|
|
2213
2319
|
}
|
|
2214
|
-
function repeatedBlockIds(
|
|
2215
|
-
const claims = claimsIn(
|
|
2320
|
+
function repeatedBlockIds(doc2, before, mapping) {
|
|
2321
|
+
const claims = claimsIn(doc2);
|
|
2216
2322
|
let previous;
|
|
2217
2323
|
const losers = [];
|
|
2218
2324
|
for (const [id, copies] of claims) {
|
|
@@ -2238,7 +2344,7 @@ var idOf = (node) => {
|
|
|
2238
2344
|
const id = node.attrs.blockId;
|
|
2239
2345
|
return typeof id === "string" && id !== "" ? id : void 0;
|
|
2240
2346
|
};
|
|
2241
|
-
function addressedBlocks(
|
|
2347
|
+
function addressedBlocks(doc2) {
|
|
2242
2348
|
const out = [];
|
|
2243
2349
|
const visit = (node, pos) => {
|
|
2244
2350
|
if (!BLOCK_TYPE_SET.has(node.type.name)) return;
|
|
@@ -2248,15 +2354,15 @@ function addressedBlocks(doc) {
|
|
|
2248
2354
|
for (const list of innerLists(node, pos)) list.node.forEach((child, offset) => visit(child, list.pos + 1 + offset));
|
|
2249
2355
|
}
|
|
2250
2356
|
};
|
|
2251
|
-
|
|
2357
|
+
doc2.forEach((node, offset) => visit(node, offset));
|
|
2252
2358
|
return out;
|
|
2253
2359
|
}
|
|
2254
|
-
function unnamedBlocks(
|
|
2255
|
-
return addressedBlocks(
|
|
2360
|
+
function unnamedBlocks(doc2) {
|
|
2361
|
+
return addressedBlocks(doc2).filter((b) => idOf(b.node) === void 0).map((b) => b.pos);
|
|
2256
2362
|
}
|
|
2257
|
-
function hiddenIds(
|
|
2363
|
+
function hiddenIds(doc2) {
|
|
2258
2364
|
const out = [];
|
|
2259
|
-
|
|
2365
|
+
doc2.descendants((node, pos) => {
|
|
2260
2366
|
if (!FLATTENED.has(node.type.name)) return;
|
|
2261
2367
|
node.forEach((child, offset) => {
|
|
2262
2368
|
const inner = child.isTextblock || node.type.name === "listItem" && LISTS2.has(child.type.name);
|
|
@@ -2265,10 +2371,10 @@ function hiddenIds(doc) {
|
|
|
2265
2371
|
});
|
|
2266
2372
|
return out;
|
|
2267
2373
|
}
|
|
2268
|
-
function handedOver(
|
|
2374
|
+
function handedOver(doc2, before, mapping, unnamed) {
|
|
2269
2375
|
const out = /* @__PURE__ */ new Map();
|
|
2270
2376
|
if (unnamed.length === 0) return out;
|
|
2271
|
-
const now = new Set(addressedBlocks(
|
|
2377
|
+
const now = new Set(addressedBlocks(doc2).map((b) => idOf(b.node)));
|
|
2272
2378
|
const gone = addressedBlocks(before).filter((b) => !b.node.isLeaf && idOf(b.node) !== void 0 && !now.has(idOf(b.node))).map((b) => ({ ...b, start: textStart(b) })).sort((a, b) => a.start - b.start || b.pos - a.pos);
|
|
2273
2379
|
for (const old of gone) {
|
|
2274
2380
|
const id = idOf(old.node);
|
|
@@ -2277,7 +2383,7 @@ function handedOver(doc, before, mapping, unnamed) {
|
|
|
2277
2383
|
let inner;
|
|
2278
2384
|
for (const pos of unnamed) {
|
|
2279
2385
|
if (out.has(pos)) continue;
|
|
2280
|
-
if (pos < at && at < pos +
|
|
2386
|
+
if (pos < at && at < pos + doc2.nodeAt(pos).nodeSize && (inner === void 0 || pos > inner)) inner = pos;
|
|
2281
2387
|
}
|
|
2282
2388
|
if (inner !== void 0) {
|
|
2283
2389
|
out.set(inner, id);
|
|
@@ -2299,7 +2405,7 @@ function bringsInBlocks(transactions) {
|
|
|
2299
2405
|
})
|
|
2300
2406
|
);
|
|
2301
2407
|
}
|
|
2302
|
-
var BlockId =
|
|
2408
|
+
var BlockId = Extension11.create({
|
|
2303
2409
|
name: "blockId",
|
|
2304
2410
|
onCreate() {
|
|
2305
2411
|
const { state, view } = this.editor;
|
|
@@ -2347,7 +2453,7 @@ var BlockId = Extension10.create({
|
|
|
2347
2453
|
}
|
|
2348
2454
|
});
|
|
2349
2455
|
var webUrl = (raw) => raw && /^https?:\/\/\S+$/i.test(raw) ? raw : null;
|
|
2350
|
-
var ReferenceNode =
|
|
2456
|
+
var ReferenceNode = Node3.create({
|
|
2351
2457
|
name: "reference",
|
|
2352
2458
|
group: "inline",
|
|
2353
2459
|
inline: true,
|
|
@@ -2386,7 +2492,7 @@ var ReferenceNode = Node2.create({
|
|
|
2386
2492
|
return ReactNodeViewRenderer2(({ node, editor, getPos }) => {
|
|
2387
2493
|
const uri = String(node.attrs.uri ?? "");
|
|
2388
2494
|
const href = typeof node.attrs.href === "string" && node.attrs.href ? node.attrs.href : void 0;
|
|
2389
|
-
return /* @__PURE__ */
|
|
2495
|
+
return /* @__PURE__ */ jsx9(
|
|
2390
2496
|
NodeViewWrapper2,
|
|
2391
2497
|
{
|
|
2392
2498
|
as: "span",
|
|
@@ -2397,13 +2503,13 @@ var ReferenceNode = Node2.create({
|
|
|
2397
2503
|
event.preventDefault();
|
|
2398
2504
|
event.stopPropagation();
|
|
2399
2505
|
},
|
|
2400
|
-
children: uri ? /* @__PURE__ */
|
|
2506
|
+
children: uri ? /* @__PURE__ */ jsx9(View, { uri, ...href ? { href } : {} }) : /* @__PURE__ */ jsx9("span", { children: href })
|
|
2401
2507
|
}
|
|
2402
2508
|
);
|
|
2403
2509
|
});
|
|
2404
2510
|
}
|
|
2405
2511
|
});
|
|
2406
|
-
var UnknownBlock =
|
|
2512
|
+
var UnknownBlock = Node3.create({
|
|
2407
2513
|
name: "unknownBlock",
|
|
2408
2514
|
group: "block",
|
|
2409
2515
|
atom: true,
|
|
@@ -2428,7 +2534,7 @@ var UnknownBlock = Node2.create({
|
|
|
2428
2534
|
function UnknownBlockView({ node }) {
|
|
2429
2535
|
const source = node.attrs.source;
|
|
2430
2536
|
const text = String(node.attrs.text ?? "");
|
|
2431
|
-
return /* @__PURE__ */
|
|
2537
|
+
return /* @__PURE__ */ jsx9(
|
|
2432
2538
|
NodeViewWrapper2,
|
|
2433
2539
|
{
|
|
2434
2540
|
"data-block-id": source?.id,
|
|
@@ -2438,7 +2544,7 @@ function UnknownBlockView({ node }) {
|
|
|
2438
2544
|
}
|
|
2439
2545
|
);
|
|
2440
2546
|
}
|
|
2441
|
-
var AttachmentNode =
|
|
2547
|
+
var AttachmentNode = Node3.create({
|
|
2442
2548
|
name: "attachment",
|
|
2443
2549
|
group: "block",
|
|
2444
2550
|
atom: true,
|
|
@@ -2468,7 +2574,7 @@ var AttachmentNode = Node2.create({
|
|
|
2468
2574
|
addNodeView() {
|
|
2469
2575
|
const View = this.options.view;
|
|
2470
2576
|
if (!View) return null;
|
|
2471
|
-
return ReactNodeViewRenderer2(({ node }) => /* @__PURE__ */
|
|
2577
|
+
return ReactNodeViewRenderer2(({ node }) => /* @__PURE__ */ jsx9(NodeViewWrapper2, { className: "my-2", children: /* @__PURE__ */ jsx9(View, { attrs: node.attrs }) }));
|
|
2472
2578
|
}
|
|
2473
2579
|
});
|
|
2474
2580
|
var TICK = "checklistTick";
|
|
@@ -2537,7 +2643,7 @@ function listItemView(editor, node, view, getPos) {
|
|
|
2537
2643
|
}
|
|
2538
2644
|
};
|
|
2539
2645
|
}
|
|
2540
|
-
var Checklist =
|
|
2646
|
+
var Checklist = Extension11.create({
|
|
2541
2647
|
name: "checklist",
|
|
2542
2648
|
// Before the list item's own Enter and Backspace.
|
|
2543
2649
|
priority: 101,
|
|
@@ -2609,7 +2715,7 @@ var Checklist = Extension10.create({
|
|
|
2609
2715
|
];
|
|
2610
2716
|
}
|
|
2611
2717
|
});
|
|
2612
|
-
var Callout =
|
|
2718
|
+
var Callout = Extension11.create({
|
|
2613
2719
|
name: "callout",
|
|
2614
2720
|
addGlobalAttributes() {
|
|
2615
2721
|
return [
|
|
@@ -2641,6 +2747,7 @@ export {
|
|
|
2641
2747
|
EditorBlockHandle,
|
|
2642
2748
|
EditorTableControls,
|
|
2643
2749
|
FORMATS,
|
|
2750
|
+
InlineText,
|
|
2644
2751
|
KeptSelection,
|
|
2645
2752
|
LinkChips,
|
|
2646
2753
|
PastedImages,
|