@estiva-app/ui 0.72.0 → 0.73.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +232 -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 +208 -0
- package/src/InlineText.tsx +204 -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,127 @@ 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, value });
|
|
564
|
+
latest.current = { onEnter, onText, onCommit, clearable, value };
|
|
565
|
+
const pending = useRef3(null);
|
|
566
|
+
const save = useCallback3(async (text) => {
|
|
567
|
+
const next = oneLine(text);
|
|
568
|
+
if (next === saved.current || next === pending.current) return;
|
|
569
|
+
if (!next && !latest.current.clearable) return;
|
|
570
|
+
pending.current = next;
|
|
571
|
+
try {
|
|
572
|
+
if (await latest.current.onCommit(next)) saved.current = next;
|
|
573
|
+
} finally {
|
|
574
|
+
if (pending.current === next) pending.current = null;
|
|
575
|
+
}
|
|
576
|
+
}, []);
|
|
577
|
+
const editor = useEditor({
|
|
578
|
+
extensions: [OneLine, Paragraph, Text, Undo],
|
|
579
|
+
content: doc(value),
|
|
580
|
+
editable: !readOnly,
|
|
581
|
+
editorProps: {
|
|
582
|
+
attributes: {
|
|
583
|
+
"aria-label": label,
|
|
584
|
+
role: "textbox",
|
|
585
|
+
"aria-multiline": "false",
|
|
586
|
+
"aria-placeholder": placeholder,
|
|
587
|
+
...readOnly ? { "aria-readonly": "true" } : {},
|
|
588
|
+
class: "outline-none"
|
|
589
|
+
},
|
|
590
|
+
handleKeyDown: (view, event) => {
|
|
591
|
+
if (event.key === "Enter") {
|
|
592
|
+
event.preventDefault();
|
|
593
|
+
void save(view.state.doc.textContent);
|
|
594
|
+
latest.current.onEnter?.();
|
|
595
|
+
return true;
|
|
596
|
+
}
|
|
597
|
+
if (event.key === "Escape") {
|
|
598
|
+
view.dom.blur();
|
|
599
|
+
return true;
|
|
600
|
+
}
|
|
601
|
+
return false;
|
|
602
|
+
},
|
|
603
|
+
// A paste is its plain text on this one line, whatever it was copied from.
|
|
604
|
+
handlePaste: (view, event) => {
|
|
605
|
+
const text = event.clipboardData?.getData("text/plain");
|
|
606
|
+
if (text == null) return false;
|
|
607
|
+
view.dispatch(view.state.tr.insertText(text.replace(/\s+/g, " ")));
|
|
608
|
+
return true;
|
|
609
|
+
}
|
|
610
|
+
},
|
|
611
|
+
onFocus: ({ editor: e }) => latest.current.onText?.(e.getText()),
|
|
612
|
+
onUpdate: ({ editor: e }) => {
|
|
613
|
+
setEmpty(e.isEmpty);
|
|
614
|
+
latest.current.onText?.(e.getText());
|
|
615
|
+
},
|
|
616
|
+
onBlur: ({ editor: e }) => {
|
|
617
|
+
latest.current.onText?.(null);
|
|
618
|
+
if (e.isEmpty && saved.current && !latest.current.clearable) {
|
|
619
|
+
e.commands.setContent(doc(saved.current), { emitUpdate: false });
|
|
620
|
+
setEmpty(false);
|
|
621
|
+
return;
|
|
622
|
+
}
|
|
623
|
+
const { value: current } = latest.current;
|
|
624
|
+
if (oneLine(e.getText()) === saved.current && current !== saved.current && pending.current === null) {
|
|
625
|
+
e.commands.setContent(doc(current), { emitUpdate: false });
|
|
626
|
+
saved.current = current;
|
|
627
|
+
setEmpty(!current);
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
630
|
+
void save(e.getText());
|
|
631
|
+
}
|
|
632
|
+
}, [readOnly]);
|
|
633
|
+
useEffect3(() => {
|
|
634
|
+
if (!editor || editor.isDestroyed || value === saved.current || editor.isFocused) return;
|
|
635
|
+
if (oneLine(editor.getText()) !== saved.current) return;
|
|
636
|
+
editor.commands.setContent(doc(value), { emitUpdate: false });
|
|
637
|
+
saved.current = value;
|
|
638
|
+
setEmpty(!value);
|
|
639
|
+
}, [editor, value]);
|
|
640
|
+
useImperativeHandle2(ref, () => ({
|
|
641
|
+
focus: (at = "start") => editor?.commands.focus(at)
|
|
642
|
+
}), [editor]);
|
|
643
|
+
return /* @__PURE__ */ jsxs3("div", { className: cn2("relative", VARIANT[variant], className), children: [
|
|
644
|
+
/* @__PURE__ */ jsx4(EditorContent2, { editor, className: cn2(ROOM, !readOnly && "cursor-text") }),
|
|
645
|
+
empty && !readOnly && /* @__PURE__ */ jsx4("span", { "aria-hidden": true, className: "pointer-events-none absolute left-0 top-1 text-text-muted", children: placeholder })
|
|
646
|
+
] });
|
|
647
|
+
}
|
|
648
|
+
|
|
530
649
|
// src/CommentHighlights.ts
|
|
531
|
-
import { Extension as
|
|
650
|
+
import { Extension as Extension4 } from "@tiptap/core";
|
|
532
651
|
import { Plugin as Plugin2, PluginKey as PluginKey2 } from "@tiptap/pm/state";
|
|
533
652
|
import { Decoration as Decoration2, DecorationSet as DecorationSet2 } from "@tiptap/pm/view";
|
|
534
653
|
var commentHighlightsKey = new PluginKey2("commentHighlights");
|
|
@@ -539,7 +658,7 @@ var COMMENT_HIGHLIGHT_CLASSES = {
|
|
|
539
658
|
var QUOTE_WHOLE_MAX = 1e3;
|
|
540
659
|
var QUOTE_END_LENGTH = 150;
|
|
541
660
|
var QUOTE_CONTEXT_LENGTH = 32;
|
|
542
|
-
function placesIn(
|
|
661
|
+
function placesIn(doc2) {
|
|
543
662
|
const places = /* @__PURE__ */ new Map();
|
|
544
663
|
const walk = (parent, parentPos) => {
|
|
545
664
|
parent.forEach((node, offset, index) => {
|
|
@@ -549,7 +668,7 @@ function placesIn(doc) {
|
|
|
549
668
|
if (!node.isTextblock && !node.isLeaf) walk(node, pos + 1);
|
|
550
669
|
});
|
|
551
670
|
};
|
|
552
|
-
walk(
|
|
671
|
+
walk(doc2, 0);
|
|
553
672
|
return places;
|
|
554
673
|
}
|
|
555
674
|
function textOf(block) {
|
|
@@ -578,7 +697,7 @@ function find(text, words, from, context) {
|
|
|
578
697
|
}
|
|
579
698
|
return first;
|
|
580
699
|
}
|
|
581
|
-
function runIn(
|
|
700
|
+
function runIn(doc2, places, ids) {
|
|
582
701
|
const present = ids.map((id) => places.get(id)).filter((p) => !!p);
|
|
583
702
|
if (present.length === 0) return null;
|
|
584
703
|
const byParent = /* @__PURE__ */ new Map();
|
|
@@ -587,7 +706,7 @@ function runIn(doc, places, ids) {
|
|
|
587
706
|
const low = Math.min(...group.map((p) => p.index));
|
|
588
707
|
const high = Math.max(...group.map((p) => p.index));
|
|
589
708
|
const contentStart = group[0].parent;
|
|
590
|
-
const parent = contentStart === 0 ?
|
|
709
|
+
const parent = contentStart === 0 ? doc2 : doc2.nodeAt(contentStart - 1);
|
|
591
710
|
if (!parent) return group;
|
|
592
711
|
const run = [];
|
|
593
712
|
parent.forEach((node, offset, index) => {
|
|
@@ -595,8 +714,8 @@ function runIn(doc, places, ids) {
|
|
|
595
714
|
});
|
|
596
715
|
return run;
|
|
597
716
|
}
|
|
598
|
-
function placeOf(
|
|
599
|
-
const run = runIn(
|
|
717
|
+
function placeOf(doc2, anchor, places = placesIn(doc2)) {
|
|
718
|
+
const run = runIn(doc2, places, anchor.blocks);
|
|
600
719
|
if (!run) return { state: "detached" };
|
|
601
720
|
const from = run[0].pos;
|
|
602
721
|
const to = run[run.length - 1].pos + run[run.length - 1].node.nodeSize;
|
|
@@ -626,7 +745,7 @@ function placeOf(doc, anchor, places = placesIn(doc)) {
|
|
|
626
745
|
if (endAt === -1 || quote.end === "") return reworded;
|
|
627
746
|
return { state: "resolved", from: a.starts[startAt], to: b.ends[endAt + quote.end.length - 1], words: true };
|
|
628
747
|
}
|
|
629
|
-
var CommentHighlights =
|
|
748
|
+
var CommentHighlights = Extension4.create({
|
|
630
749
|
name: "commentHighlights",
|
|
631
750
|
addOptions() {
|
|
632
751
|
return { onSelect: null };
|
|
@@ -723,10 +842,10 @@ function offsetIn(block, pos) {
|
|
|
723
842
|
return at === -1 ? block.starts.length : at;
|
|
724
843
|
}
|
|
725
844
|
function anchorOfSelection(editor) {
|
|
726
|
-
const { doc, selection } = editor.state;
|
|
845
|
+
const { doc: doc2, selection } = editor.state;
|
|
727
846
|
if (selection.empty) return null;
|
|
728
847
|
const { $from, $to } = selection;
|
|
729
|
-
const places = placesIn(
|
|
848
|
+
const places = placesIn(doc2);
|
|
730
849
|
const around = (depth) => {
|
|
731
850
|
for (let d = depth; d > 0; d--) {
|
|
732
851
|
const id = $from.node(d).attrs.blockId;
|
|
@@ -785,7 +904,7 @@ function anchorOfSelection(editor) {
|
|
|
785
904
|
}
|
|
786
905
|
|
|
787
906
|
// src/PastedImages.ts
|
|
788
|
-
import { Extension as
|
|
907
|
+
import { Extension as Extension5 } from "@tiptap/core";
|
|
789
908
|
import { Plugin as Plugin3, PluginKey as PluginKey3 } from "@tiptap/pm/state";
|
|
790
909
|
var IMAGE_EXTENSIONS = {
|
|
791
910
|
"image/png": "png",
|
|
@@ -821,7 +940,7 @@ function pastedImages(source, at = /* @__PURE__ */ new Date()) {
|
|
|
821
940
|
(file) => hasUsableName(file.name) ? file : new File([file], pastedImageName(file.type, at, generated++), { type: file.type, lastModified: file.lastModified })
|
|
822
941
|
);
|
|
823
942
|
}
|
|
824
|
-
var PastedImages =
|
|
943
|
+
var PastedImages = Extension5.create({
|
|
825
944
|
name: "pastedImages",
|
|
826
945
|
addOptions() {
|
|
827
946
|
return { onImages: () => false };
|
|
@@ -843,7 +962,7 @@ var PastedImages = Extension4.create({
|
|
|
843
962
|
});
|
|
844
963
|
|
|
845
964
|
// src/PastedMarkdown.ts
|
|
846
|
-
import { Extension as
|
|
965
|
+
import { Extension as Extension6 } from "@tiptap/core";
|
|
847
966
|
import { Slice } from "@tiptap/pm/model";
|
|
848
967
|
import { Plugin as Plugin4, PluginKey as PluginKey4 } from "@tiptap/pm/state";
|
|
849
968
|
function inTableCell($context) {
|
|
@@ -854,7 +973,7 @@ function inTableCell($context) {
|
|
|
854
973
|
return false;
|
|
855
974
|
}
|
|
856
975
|
var hasTable = (blocks) => blocks.some((block) => block.type === "table" || hasTable(block.content ?? []));
|
|
857
|
-
var PastedMarkdown =
|
|
976
|
+
var PastedMarkdown = Extension6.create({
|
|
858
977
|
name: "pastedMarkdown",
|
|
859
978
|
addOptions() {
|
|
860
979
|
return { read: () => void 0 };
|
|
@@ -911,7 +1030,7 @@ import { Selection } from "@tiptap/pm/state";
|
|
|
911
1030
|
import { MenuItem, MenuSub } from "@estiva-app/ui";
|
|
912
1031
|
|
|
913
1032
|
// src/ComposerTriggers.tsx
|
|
914
|
-
import { Extension as
|
|
1033
|
+
import { Extension as Extension7 } from "@tiptap/core";
|
|
915
1034
|
import { PluginKey as PluginKey5 } from "@tiptap/pm/state";
|
|
916
1035
|
import Mention from "@tiptap/extension-mention";
|
|
917
1036
|
import Suggestion from "@tiptap/suggestion";
|
|
@@ -920,7 +1039,7 @@ import { Avatar } from "@estiva-app/ui";
|
|
|
920
1039
|
import { EnterHint } from "@estiva-app/ui";
|
|
921
1040
|
import { inlineChipClassName } from "@estiva-app/ui";
|
|
922
1041
|
import { WithTooltip } from "@estiva-app/ui";
|
|
923
|
-
import { jsx as
|
|
1042
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
924
1043
|
var PEOPLE_LIMIT = 6;
|
|
925
1044
|
function filterPeople(people, query) {
|
|
926
1045
|
const q = query.toLowerCase();
|
|
@@ -938,8 +1057,8 @@ function peopleMenu(urgent) {
|
|
|
938
1057
|
row: (person) => ({
|
|
939
1058
|
label: person.name,
|
|
940
1059
|
description: person.description,
|
|
941
|
-
leading: person.avatar ?? /* @__PURE__ */
|
|
942
|
-
hint: /* @__PURE__ */
|
|
1060
|
+
leading: person.avatar ?? /* @__PURE__ */ jsx5(Avatar, { size: 32, alt: person.name }),
|
|
1061
|
+
hint: /* @__PURE__ */ jsx5(EnterHint, {}),
|
|
943
1062
|
size: "tall"
|
|
944
1063
|
})
|
|
945
1064
|
};
|
|
@@ -1068,9 +1187,9 @@ var CaptionedReference = Mention.extend({
|
|
|
1068
1187
|
return ReactNodeViewRenderer(
|
|
1069
1188
|
({ node }) => (
|
|
1070
1189
|
// 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__ */
|
|
1190
|
+
/* @__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: [
|
|
1191
|
+
/* @__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 }),
|
|
1192
|
+
/* @__PURE__ */ jsx5("span", { className: "truncate", children: captionOf(node.attrs.label, node.attrs.snippet) })
|
|
1074
1193
|
] }) }) })
|
|
1075
1194
|
),
|
|
1076
1195
|
{ as: "span" }
|
|
@@ -1093,11 +1212,11 @@ function referenceMenu({ ariaLabel, sectionLabel, icon, iconFor }) {
|
|
|
1093
1212
|
return groups;
|
|
1094
1213
|
},
|
|
1095
1214
|
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__ */
|
|
1215
|
+
row: (item) => ({ leading: item.icon ?? iconFor?.(item.uri) ?? icon, label: captionOf(item.label, item.snippet), description: item.description, hint: /* @__PURE__ */ jsx5(EnterHint, {}) })
|
|
1097
1216
|
};
|
|
1098
1217
|
}
|
|
1099
1218
|
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 =
|
|
1219
|
+
var ReferenceTrigger = Extension7.create({
|
|
1101
1220
|
name: "referenceTrigger",
|
|
1102
1221
|
addOptions() {
|
|
1103
1222
|
return { items: () => [], nodeName: "captionedReference", ariaLabel: "References", sectionLabel: "References", icon: null };
|
|
@@ -1213,7 +1332,7 @@ function filterSlashSections(sections, query) {
|
|
|
1213
1332
|
const q = query.toLowerCase();
|
|
1214
1333
|
return sections.map((section) => ({ ...section, commands: q ? section.commands.filter((command) => matches(command, q)) : section.commands }));
|
|
1215
1334
|
}
|
|
1216
|
-
var SlashCommands =
|
|
1335
|
+
var SlashCommands = Extension7.create({
|
|
1217
1336
|
name: "slashCommands",
|
|
1218
1337
|
addOptions() {
|
|
1219
1338
|
return { sections: [formatSection()] };
|
|
@@ -1247,7 +1366,7 @@ var SlashCommands = Extension6.create({
|
|
|
1247
1366
|
});
|
|
1248
1367
|
|
|
1249
1368
|
// src/EditorBlockHandle.tsx
|
|
1250
|
-
import { Fragment, jsx as
|
|
1369
|
+
import { Fragment, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1251
1370
|
function editorBlocks(view) {
|
|
1252
1371
|
const out = [];
|
|
1253
1372
|
view.state.doc.forEach((node, pos) => {
|
|
@@ -1314,8 +1433,8 @@ function EditorBlockHandle({ editor, turnInto = turnIntoRows, actions, children,
|
|
|
1314
1433
|
const node = pos === void 0 ? null : editor.state.doc.nodeAt(pos);
|
|
1315
1434
|
if (pos === void 0 || !node) return null;
|
|
1316
1435
|
const turnRows = typeof turnInto === "function" ? turnInto(node, editor) : node.isTextblock ? turnInto : [];
|
|
1317
|
-
return /* @__PURE__ */
|
|
1318
|
-
turnRows.length > 0 && /* @__PURE__ */
|
|
1436
|
+
return /* @__PURE__ */ jsxs5(Fragment, { children: [
|
|
1437
|
+
turnRows.length > 0 && /* @__PURE__ */ jsx6(MenuSub, { label: "Turn into", children: turnRows.map((row) => /* @__PURE__ */ jsx6(
|
|
1319
1438
|
MenuItem,
|
|
1320
1439
|
{
|
|
1321
1440
|
label: row.label,
|
|
@@ -1327,8 +1446,8 @@ function EditorBlockHandle({ editor, turnInto = turnIntoRows, actions, children,
|
|
|
1327
1446
|
},
|
|
1328
1447
|
row.label
|
|
1329
1448
|
)) }),
|
|
1330
|
-
/* @__PURE__ */
|
|
1331
|
-
/* @__PURE__ */
|
|
1449
|
+
/* @__PURE__ */ jsx6(MenuItem, { label: "Duplicate", leading: /* @__PURE__ */ jsx6(IconCopy, { size: 16, stroke: 1.5, className: "text-text-secondary" }), onClick: () => duplicateBlock(editor, pos) }),
|
|
1450
|
+
/* @__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
1451
|
] });
|
|
1333
1452
|
},
|
|
1334
1453
|
startDrag: (block, event) => {
|
|
@@ -1350,7 +1469,7 @@ function EditorBlockHandle({ editor, turnInto = turnIntoRows, actions, children,
|
|
|
1350
1469
|
}
|
|
1351
1470
|
};
|
|
1352
1471
|
}, [editor, turnInto]);
|
|
1353
|
-
return /* @__PURE__ */
|
|
1472
|
+
return /* @__PURE__ */ jsx6(BlockHandle, { editing, actions, className, children });
|
|
1354
1473
|
}
|
|
1355
1474
|
var LISTS = ["bulletList", "orderedList"];
|
|
1356
1475
|
var isList = (node) => LISTS.includes(node.type.name);
|
|
@@ -1456,14 +1575,14 @@ function turnIntoRows(node, editor) {
|
|
|
1456
1575
|
}
|
|
1457
1576
|
|
|
1458
1577
|
// src/EditorTableControls.tsx
|
|
1459
|
-
import { useCallback as
|
|
1578
|
+
import { useCallback as useCallback4, useEffect as useEffect4, useRef as useRef4, useState as useState4 } from "react";
|
|
1460
1579
|
import { TextSelection } from "@tiptap/pm/state";
|
|
1461
1580
|
import { addColumnAfter, addColumnBefore, addRowAfter, addRowBefore, deleteColumn, deleteRow, deleteTable, toggleHeader } from "@tiptap/pm/tables";
|
|
1462
1581
|
import { IconColumnInsertLeft, IconColumnInsertRight, IconGripHorizontal, IconGripVertical, IconPlus, IconRowInsertBottom, IconRowInsertTop, IconTrash as IconTrash2 } from "@tabler/icons-react";
|
|
1463
|
-
import { cn as
|
|
1582
|
+
import { cn as cn3 } from "@estiva-app/ui";
|
|
1464
1583
|
import { IconButton as IconButton2 } from "@estiva-app/ui";
|
|
1465
1584
|
import { Menu, MenuItem as MenuItem2, MenuSeparator } from "@estiva-app/ui";
|
|
1466
|
-
import { Fragment as Fragment2, jsx as
|
|
1585
|
+
import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1467
1586
|
function inCell(editor, cell, command) {
|
|
1468
1587
|
const { view } = editor;
|
|
1469
1588
|
if (!view.dom.contains(cell)) return false;
|
|
@@ -1509,13 +1628,13 @@ function place(frame, { table, row, cell }) {
|
|
|
1509
1628
|
}
|
|
1510
1629
|
var ICON = { size: 16, stroke: 1.5, className: "text-text-secondary" };
|
|
1511
1630
|
var keepFocus = (e) => e.preventDefault();
|
|
1512
|
-
var HANDLE_BOX =
|
|
1631
|
+
var HANDLE_BOX = cn3(FLOATING_SURFACE_CLASSES, "shadow-none");
|
|
1513
1632
|
function EditorTableControls({ editor, children, className }) {
|
|
1514
|
-
const frame =
|
|
1515
|
-
const [hovered, setHovered] =
|
|
1516
|
-
const [menu, setMenu] =
|
|
1633
|
+
const frame = useRef4(null);
|
|
1634
|
+
const [hovered, setHovered] = useState4(null);
|
|
1635
|
+
const [menu, setMenu] = useState4(null);
|
|
1517
1636
|
const editable = !!editor && editor.isEditable;
|
|
1518
|
-
const follow =
|
|
1637
|
+
const follow = useCallback4(
|
|
1519
1638
|
(target) => {
|
|
1520
1639
|
if (!editor || !frame.current || !(target instanceof Element)) return;
|
|
1521
1640
|
if (target.closest("[data-table-control]")) return;
|
|
@@ -1531,7 +1650,7 @@ function EditorTableControls({ editor, children, className }) {
|
|
|
1531
1650
|
},
|
|
1532
1651
|
[editor]
|
|
1533
1652
|
);
|
|
1534
|
-
|
|
1653
|
+
useEffect4(() => {
|
|
1535
1654
|
if (!editor) return;
|
|
1536
1655
|
const changed = ({ transaction }) => {
|
|
1537
1656
|
if (transaction.docChanged && !menu) setHovered(null);
|
|
@@ -1547,11 +1666,11 @@ function EditorTableControls({ editor, children, className }) {
|
|
|
1547
1666
|
setMenu(null);
|
|
1548
1667
|
setHovered(null);
|
|
1549
1668
|
};
|
|
1550
|
-
return /* @__PURE__ */
|
|
1669
|
+
return /* @__PURE__ */ jsxs6(
|
|
1551
1670
|
"div",
|
|
1552
1671
|
{
|
|
1553
1672
|
ref: frame,
|
|
1554
|
-
className:
|
|
1673
|
+
className: cn3("relative", className),
|
|
1555
1674
|
onMouseMove: (e) => {
|
|
1556
1675
|
if (!menu) follow(e.target);
|
|
1557
1676
|
},
|
|
@@ -1560,39 +1679,39 @@ function EditorTableControls({ editor, children, className }) {
|
|
|
1560
1679
|
},
|
|
1561
1680
|
children: [
|
|
1562
1681
|
children,
|
|
1563
|
-
shown && editor && /* @__PURE__ */
|
|
1564
|
-
/* @__PURE__ */
|
|
1682
|
+
shown && editor && /* @__PURE__ */ jsxs6(Fragment2, { children: [
|
|
1683
|
+
/* @__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
1684
|
Menu,
|
|
1566
1685
|
{
|
|
1567
1686
|
open: menu === "row",
|
|
1568
1687
|
onOpenChange: (open) => setMenu(open ? "row" : null),
|
|
1569
|
-
trigger: /* @__PURE__ */
|
|
1688
|
+
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
1689
|
children: [
|
|
1571
|
-
!isHeaderRow(shown.row) && /* @__PURE__ */
|
|
1572
|
-
/* @__PURE__ */
|
|
1573
|
-
/* @__PURE__ */
|
|
1574
|
-
/* @__PURE__ */
|
|
1575
|
-
/* @__PURE__ */
|
|
1690
|
+
!isHeaderRow(shown.row) && /* @__PURE__ */ jsx7(MenuItem2, { label: "Insert above", leading: /* @__PURE__ */ jsx7(IconRowInsertTop, { ...ICON }), onClick: run(() => inCell(editor, shown.cell, addRowBefore)) }),
|
|
1691
|
+
/* @__PURE__ */ jsx7(MenuItem2, { label: "Insert below", leading: /* @__PURE__ */ jsx7(IconRowInsertBottom, { ...ICON }), onClick: run(() => inCell(editor, shown.cell, addRowAfter)) }),
|
|
1692
|
+
/* @__PURE__ */ jsx7(MenuSeparator, {}),
|
|
1693
|
+
/* @__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)) }),
|
|
1694
|
+
/* @__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
1695
|
]
|
|
1577
1696
|
}
|
|
1578
1697
|
) }),
|
|
1579
|
-
/* @__PURE__ */
|
|
1698
|
+
/* @__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
1699
|
Menu,
|
|
1581
1700
|
{
|
|
1582
1701
|
open: menu === "column",
|
|
1583
1702
|
onOpenChange: (open) => setMenu(open ? "column" : null),
|
|
1584
|
-
trigger: /* @__PURE__ */
|
|
1703
|
+
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
1704
|
children: [
|
|
1586
|
-
/* @__PURE__ */
|
|
1587
|
-
/* @__PURE__ */
|
|
1588
|
-
/* @__PURE__ */
|
|
1589
|
-
/* @__PURE__ */
|
|
1590
|
-
/* @__PURE__ */
|
|
1705
|
+
/* @__PURE__ */ jsx7(MenuItem2, { label: "Insert left", leading: /* @__PURE__ */ jsx7(IconColumnInsertLeft, { ...ICON }), onClick: run(() => inCell(editor, shown.cell, addColumnBefore)) }),
|
|
1706
|
+
/* @__PURE__ */ jsx7(MenuItem2, { label: "Insert right", leading: /* @__PURE__ */ jsx7(IconColumnInsertRight, { ...ICON }), onClick: run(() => inCell(editor, shown.cell, addColumnAfter)) }),
|
|
1707
|
+
/* @__PURE__ */ jsx7(MenuSeparator, {}),
|
|
1708
|
+
/* @__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)) }),
|
|
1709
|
+
/* @__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
1710
|
]
|
|
1592
1711
|
}
|
|
1593
1712
|
) }),
|
|
1594
|
-
shown.row === shown.table.rows[shown.table.rows.length - 1] && /* @__PURE__ */
|
|
1595
|
-
shown.cell === shown.row.cells[shown.row.cells.length - 1] && /* @__PURE__ */
|
|
1713
|
+
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 }) }) }),
|
|
1714
|
+
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
1715
|
] })
|
|
1597
1716
|
]
|
|
1598
1717
|
}
|
|
@@ -1600,7 +1719,7 @@ function EditorTableControls({ editor, children, className }) {
|
|
|
1600
1719
|
}
|
|
1601
1720
|
|
|
1602
1721
|
// src/BlockNodes.tsx
|
|
1603
|
-
import { Extension as
|
|
1722
|
+
import { Extension as Extension11, InputRule, Node as Node3 } from "@tiptap/core";
|
|
1604
1723
|
import { DOMSerializer } from "@tiptap/pm/model";
|
|
1605
1724
|
import { Plugin as Plugin8, PluginKey as PluginKey9 } from "@tiptap/pm/state";
|
|
1606
1725
|
import { Mapping, ReplaceAroundStep } from "@tiptap/pm/transform";
|
|
@@ -1609,15 +1728,15 @@ import { Checkbox } from "@estiva-app/ui";
|
|
|
1609
1728
|
import { calloutLook } from "@estiva-app/ui";
|
|
1610
1729
|
|
|
1611
1730
|
// src/ReferenceMenu.tsx
|
|
1612
|
-
import { useCallback as
|
|
1613
|
-
import { Extension as
|
|
1731
|
+
import { useCallback as useCallback5 } from "react";
|
|
1732
|
+
import { Extension as Extension10 } from "@tiptap/core";
|
|
1614
1733
|
import { useEditorState } from "@tiptap/react";
|
|
1615
1734
|
import { NodeSelection as NodeSelection2, Plugin as Plugin7, PluginKey as PluginKey8, TextSelection as TextSelection2 } from "@tiptap/pm/state";
|
|
1616
1735
|
import { ReplaceStep } from "@tiptap/pm/transform";
|
|
1617
1736
|
import { IconCheck } from "@tabler/icons-react";
|
|
1618
1737
|
|
|
1619
1738
|
// src/LinkChips.ts
|
|
1620
|
-
import { Extension as
|
|
1739
|
+
import { Extension as Extension8 } from "@tiptap/core";
|
|
1621
1740
|
import { closeHistory } from "@tiptap/pm/history";
|
|
1622
1741
|
import { Plugin as Plugin5, PluginKey as PluginKey6 } from "@tiptap/pm/state";
|
|
1623
1742
|
var key = new PluginKey6("linkChips");
|
|
@@ -1638,10 +1757,10 @@ function urlRuns(text) {
|
|
|
1638
1757
|
}
|
|
1639
1758
|
return out;
|
|
1640
1759
|
}
|
|
1641
|
-
function findLinkChips(
|
|
1760
|
+
function findLinkChips(doc2, selection, referenceOf, pasted = []) {
|
|
1642
1761
|
const found = { chips: [], fills: [], open: [] };
|
|
1643
1762
|
const open = /* @__PURE__ */ new Set();
|
|
1644
|
-
|
|
1763
|
+
doc2.descendants((node, pos) => {
|
|
1645
1764
|
if (node.type.spec.code) return false;
|
|
1646
1765
|
if (node.type.name === "reference") {
|
|
1647
1766
|
const href = typeof node.attrs.href === "string" ? node.attrs.href : "";
|
|
@@ -1695,7 +1814,7 @@ function refreshLinkChips(editor) {
|
|
|
1695
1814
|
const tr = apply(editor.state, findLinkChips(editor.state.doc, editor.state.selection, chips.options.referenceOf, chips.pasted));
|
|
1696
1815
|
if (tr) editor.view.dispatch(tr);
|
|
1697
1816
|
}
|
|
1698
|
-
var LinkChips =
|
|
1817
|
+
var LinkChips = Extension8.create({
|
|
1699
1818
|
name: "linkChips",
|
|
1700
1819
|
addOptions() {
|
|
1701
1820
|
return { referenceOf: null, ask: null, limit: 24 };
|
|
@@ -1768,18 +1887,18 @@ import { MenuItem as MenuItem3, MenuSection, MenuSeparator as MenuSeparator2 } f
|
|
|
1768
1887
|
import { Popover as Popover2 } from "@estiva-app/ui";
|
|
1769
1888
|
|
|
1770
1889
|
// src/ReferenceCards.ts
|
|
1771
|
-
import { Extension as
|
|
1890
|
+
import { Extension as Extension9 } from "@tiptap/core";
|
|
1772
1891
|
import { NodeSelection, Plugin as Plugin6, PluginKey as PluginKey7 } from "@tiptap/pm/state";
|
|
1773
1892
|
import { Decoration as Decoration3, DecorationSet as DecorationSet3 } from "@tiptap/pm/view";
|
|
1774
|
-
import { useEffect as
|
|
1893
|
+
import { useEffect as useEffect5, useState as useState5 } from "react";
|
|
1775
1894
|
function layoutOf(raw) {
|
|
1776
1895
|
if (typeof raw !== "string" || raw === "" || raw === "none") return void 0;
|
|
1777
1896
|
return raw === "detailed" ? "detailed" : "compact";
|
|
1778
1897
|
}
|
|
1779
|
-
function referenceCardPlacements(
|
|
1898
|
+
function referenceCardPlacements(doc2) {
|
|
1780
1899
|
const out = [];
|
|
1781
1900
|
const seen = /* @__PURE__ */ new Map();
|
|
1782
|
-
|
|
1901
|
+
doc2.descendants((node, pos, parent) => {
|
|
1783
1902
|
if (!node.isTextblock) return true;
|
|
1784
1903
|
const cards = [];
|
|
1785
1904
|
node.forEach((child) => {
|
|
@@ -1812,16 +1931,16 @@ function elementFor(storage, slotKey) {
|
|
|
1812
1931
|
function storageOf(editor) {
|
|
1813
1932
|
return editor.storage.referenceCards;
|
|
1814
1933
|
}
|
|
1815
|
-
var ReferenceCards =
|
|
1934
|
+
var ReferenceCards = Extension9.create({
|
|
1816
1935
|
name: "referenceCards",
|
|
1817
1936
|
addStorage() {
|
|
1818
1937
|
return { elements: /* @__PURE__ */ new Map() };
|
|
1819
1938
|
},
|
|
1820
1939
|
addProseMirrorPlugins() {
|
|
1821
1940
|
const storage = this.storage;
|
|
1822
|
-
const decorate = (
|
|
1823
|
-
|
|
1824
|
-
referenceCardPlacements(
|
|
1941
|
+
const decorate = (doc2) => DecorationSet3.create(
|
|
1942
|
+
doc2,
|
|
1943
|
+
referenceCardPlacements(doc2).map(
|
|
1825
1944
|
(p) => Decoration3.widget(p.pos, () => elementFor(storage, p.key), {
|
|
1826
1945
|
key: p.key,
|
|
1827
1946
|
side: 1,
|
|
@@ -1844,8 +1963,8 @@ var ReferenceCards = Extension8.create({
|
|
|
1844
1963
|
}
|
|
1845
1964
|
});
|
|
1846
1965
|
function useReferenceCards(editor) {
|
|
1847
|
-
const [slots, setSlots] =
|
|
1848
|
-
|
|
1966
|
+
const [slots, setSlots] = useState5([]);
|
|
1967
|
+
useEffect5(() => {
|
|
1849
1968
|
if (!editor) return;
|
|
1850
1969
|
const storage = storageOf(editor);
|
|
1851
1970
|
if (!storage) return;
|
|
@@ -1910,7 +2029,7 @@ function setReferenceCardAt(editor, pos, layout) {
|
|
|
1910
2029
|
}
|
|
1911
2030
|
|
|
1912
2031
|
// src/ReferenceMenu.tsx
|
|
1913
|
-
import { Fragment as Fragment3, jsx as
|
|
2032
|
+
import { Fragment as Fragment3, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1914
2033
|
var key3 = new PluginKey8("referenceMenu");
|
|
1915
2034
|
var LAYOUTS = [
|
|
1916
2035
|
{ layout: "none", label: "None" },
|
|
@@ -1990,7 +2109,7 @@ function caretAfter(state, pos) {
|
|
|
1990
2109
|
const node = state.doc.nodeAt(pos);
|
|
1991
2110
|
return state.tr.setSelection(TextSelection2.create(state.doc, pos + (node?.nodeSize ?? 1)));
|
|
1992
2111
|
}
|
|
1993
|
-
var ReferenceMenu =
|
|
2112
|
+
var ReferenceMenu = Extension10.create({
|
|
1994
2113
|
name: "referenceMenu",
|
|
1995
2114
|
// Before the editor's own keys, so Enter on a highlighted row is the row's, not a new line.
|
|
1996
2115
|
priority: 1e3,
|
|
@@ -2072,7 +2191,7 @@ function ReferenceMenuView({ editor }) {
|
|
|
2072
2191
|
return { pos: open.pos, active: open.active, named: !!node.attrs.uri, layout };
|
|
2073
2192
|
}
|
|
2074
2193
|
});
|
|
2075
|
-
const keepFocus2 =
|
|
2194
|
+
const keepFocus2 = useCallback5((list) => {
|
|
2076
2195
|
const panel = list?.closest('[role="dialog"]');
|
|
2077
2196
|
if (!panel) return;
|
|
2078
2197
|
const keep = (event) => event.preventDefault();
|
|
@@ -2089,7 +2208,7 @@ function ReferenceMenuView({ editor }) {
|
|
|
2089
2208
|
};
|
|
2090
2209
|
return (
|
|
2091
2210
|
// finalFocus={false}: focus never left the text.
|
|
2092
|
-
/* @__PURE__ */
|
|
2211
|
+
/* @__PURE__ */ jsx8(
|
|
2093
2212
|
Popover2,
|
|
2094
2213
|
{
|
|
2095
2214
|
anchor,
|
|
@@ -2101,8 +2220,8 @@ function ReferenceMenuView({ editor }) {
|
|
|
2101
2220
|
align: "left",
|
|
2102
2221
|
ariaLabel: "Link",
|
|
2103
2222
|
finalFocus: false,
|
|
2104
|
-
children: shown && /* @__PURE__ */
|
|
2105
|
-
opens && /* @__PURE__ */
|
|
2223
|
+
children: shown && /* @__PURE__ */ jsxs7("div", { ref: keepFocus2, role: "menu", "aria-label": "Link", className: "flex flex-col gap-0.5", children: [
|
|
2224
|
+
opens && /* @__PURE__ */ jsx8(
|
|
2106
2225
|
MenuItem3,
|
|
2107
2226
|
{
|
|
2108
2227
|
role: "menuitem",
|
|
@@ -2115,9 +2234,9 @@ function ReferenceMenuView({ editor }) {
|
|
|
2115
2234
|
}
|
|
2116
2235
|
}
|
|
2117
2236
|
),
|
|
2118
|
-
shown.named && /* @__PURE__ */
|
|
2119
|
-
opens && /* @__PURE__ */
|
|
2120
|
-
/* @__PURE__ */
|
|
2237
|
+
shown.named && /* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
2238
|
+
opens && /* @__PURE__ */ jsx8(MenuSeparator2, {}),
|
|
2239
|
+
/* @__PURE__ */ jsx8("div", { role: "group", "aria-label": "Card", children: /* @__PURE__ */ jsx8(MenuSection, { label: "Card", children: LAYOUTS.map(({ layout, label }, i) => /* @__PURE__ */ jsx8(
|
|
2121
2240
|
MenuItem3,
|
|
2122
2241
|
{
|
|
2123
2242
|
role: "menuitemradio",
|
|
@@ -2125,7 +2244,7 @@ function ReferenceMenuView({ editor }) {
|
|
|
2125
2244
|
tabIndex: -1,
|
|
2126
2245
|
label,
|
|
2127
2246
|
selected: shown.active === i + (opens ? 1 : 0),
|
|
2128
|
-
trailing: shown.layout === layout ? /* @__PURE__ */
|
|
2247
|
+
trailing: shown.layout === layout ? /* @__PURE__ */ jsx8(IconCheck, { size: 16, "aria-hidden": true }) : void 0,
|
|
2129
2248
|
onMouseDown: (event) => {
|
|
2130
2249
|
event.preventDefault();
|
|
2131
2250
|
run(layout);
|
|
@@ -2141,7 +2260,7 @@ function ReferenceMenuView({ editor }) {
|
|
|
2141
2260
|
}
|
|
2142
2261
|
|
|
2143
2262
|
// src/BlockNodes.tsx
|
|
2144
|
-
import { jsx as
|
|
2263
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
2145
2264
|
var BLOCK_TYPES = [
|
|
2146
2265
|
"paragraph",
|
|
2147
2266
|
"heading",
|
|
@@ -2174,9 +2293,9 @@ function holdsText(node) {
|
|
|
2174
2293
|
});
|
|
2175
2294
|
return found;
|
|
2176
2295
|
}
|
|
2177
|
-
function claimsIn(
|
|
2296
|
+
function claimsIn(doc2) {
|
|
2178
2297
|
const claims = /* @__PURE__ */ new Map();
|
|
2179
|
-
|
|
2298
|
+
doc2.descendants((node, pos, parent) => {
|
|
2180
2299
|
const fixed = node.type.name === "unknownBlock";
|
|
2181
2300
|
if (!fixed && !BLOCK_TYPE_SET.has(node.type.name)) return;
|
|
2182
2301
|
if (parent?.type.name === "listItem" && LISTS2.has(node.type.name)) return;
|
|
@@ -2211,8 +2330,8 @@ function textStart({ pos, node }) {
|
|
|
2211
2330
|
}
|
|
2212
2331
|
return start;
|
|
2213
2332
|
}
|
|
2214
|
-
function repeatedBlockIds(
|
|
2215
|
-
const claims = claimsIn(
|
|
2333
|
+
function repeatedBlockIds(doc2, before, mapping) {
|
|
2334
|
+
const claims = claimsIn(doc2);
|
|
2216
2335
|
let previous;
|
|
2217
2336
|
const losers = [];
|
|
2218
2337
|
for (const [id, copies] of claims) {
|
|
@@ -2238,7 +2357,7 @@ var idOf = (node) => {
|
|
|
2238
2357
|
const id = node.attrs.blockId;
|
|
2239
2358
|
return typeof id === "string" && id !== "" ? id : void 0;
|
|
2240
2359
|
};
|
|
2241
|
-
function addressedBlocks(
|
|
2360
|
+
function addressedBlocks(doc2) {
|
|
2242
2361
|
const out = [];
|
|
2243
2362
|
const visit = (node, pos) => {
|
|
2244
2363
|
if (!BLOCK_TYPE_SET.has(node.type.name)) return;
|
|
@@ -2248,15 +2367,15 @@ function addressedBlocks(doc) {
|
|
|
2248
2367
|
for (const list of innerLists(node, pos)) list.node.forEach((child, offset) => visit(child, list.pos + 1 + offset));
|
|
2249
2368
|
}
|
|
2250
2369
|
};
|
|
2251
|
-
|
|
2370
|
+
doc2.forEach((node, offset) => visit(node, offset));
|
|
2252
2371
|
return out;
|
|
2253
2372
|
}
|
|
2254
|
-
function unnamedBlocks(
|
|
2255
|
-
return addressedBlocks(
|
|
2373
|
+
function unnamedBlocks(doc2) {
|
|
2374
|
+
return addressedBlocks(doc2).filter((b) => idOf(b.node) === void 0).map((b) => b.pos);
|
|
2256
2375
|
}
|
|
2257
|
-
function hiddenIds(
|
|
2376
|
+
function hiddenIds(doc2) {
|
|
2258
2377
|
const out = [];
|
|
2259
|
-
|
|
2378
|
+
doc2.descendants((node, pos) => {
|
|
2260
2379
|
if (!FLATTENED.has(node.type.name)) return;
|
|
2261
2380
|
node.forEach((child, offset) => {
|
|
2262
2381
|
const inner = child.isTextblock || node.type.name === "listItem" && LISTS2.has(child.type.name);
|
|
@@ -2265,10 +2384,10 @@ function hiddenIds(doc) {
|
|
|
2265
2384
|
});
|
|
2266
2385
|
return out;
|
|
2267
2386
|
}
|
|
2268
|
-
function handedOver(
|
|
2387
|
+
function handedOver(doc2, before, mapping, unnamed) {
|
|
2269
2388
|
const out = /* @__PURE__ */ new Map();
|
|
2270
2389
|
if (unnamed.length === 0) return out;
|
|
2271
|
-
const now = new Set(addressedBlocks(
|
|
2390
|
+
const now = new Set(addressedBlocks(doc2).map((b) => idOf(b.node)));
|
|
2272
2391
|
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
2392
|
for (const old of gone) {
|
|
2274
2393
|
const id = idOf(old.node);
|
|
@@ -2277,7 +2396,7 @@ function handedOver(doc, before, mapping, unnamed) {
|
|
|
2277
2396
|
let inner;
|
|
2278
2397
|
for (const pos of unnamed) {
|
|
2279
2398
|
if (out.has(pos)) continue;
|
|
2280
|
-
if (pos < at && at < pos +
|
|
2399
|
+
if (pos < at && at < pos + doc2.nodeAt(pos).nodeSize && (inner === void 0 || pos > inner)) inner = pos;
|
|
2281
2400
|
}
|
|
2282
2401
|
if (inner !== void 0) {
|
|
2283
2402
|
out.set(inner, id);
|
|
@@ -2299,7 +2418,7 @@ function bringsInBlocks(transactions) {
|
|
|
2299
2418
|
})
|
|
2300
2419
|
);
|
|
2301
2420
|
}
|
|
2302
|
-
var BlockId =
|
|
2421
|
+
var BlockId = Extension11.create({
|
|
2303
2422
|
name: "blockId",
|
|
2304
2423
|
onCreate() {
|
|
2305
2424
|
const { state, view } = this.editor;
|
|
@@ -2347,7 +2466,7 @@ var BlockId = Extension10.create({
|
|
|
2347
2466
|
}
|
|
2348
2467
|
});
|
|
2349
2468
|
var webUrl = (raw) => raw && /^https?:\/\/\S+$/i.test(raw) ? raw : null;
|
|
2350
|
-
var ReferenceNode =
|
|
2469
|
+
var ReferenceNode = Node3.create({
|
|
2351
2470
|
name: "reference",
|
|
2352
2471
|
group: "inline",
|
|
2353
2472
|
inline: true,
|
|
@@ -2386,7 +2505,7 @@ var ReferenceNode = Node2.create({
|
|
|
2386
2505
|
return ReactNodeViewRenderer2(({ node, editor, getPos }) => {
|
|
2387
2506
|
const uri = String(node.attrs.uri ?? "");
|
|
2388
2507
|
const href = typeof node.attrs.href === "string" && node.attrs.href ? node.attrs.href : void 0;
|
|
2389
|
-
return /* @__PURE__ */
|
|
2508
|
+
return /* @__PURE__ */ jsx9(
|
|
2390
2509
|
NodeViewWrapper2,
|
|
2391
2510
|
{
|
|
2392
2511
|
as: "span",
|
|
@@ -2397,13 +2516,13 @@ var ReferenceNode = Node2.create({
|
|
|
2397
2516
|
event.preventDefault();
|
|
2398
2517
|
event.stopPropagation();
|
|
2399
2518
|
},
|
|
2400
|
-
children: uri ? /* @__PURE__ */
|
|
2519
|
+
children: uri ? /* @__PURE__ */ jsx9(View, { uri, ...href ? { href } : {} }) : /* @__PURE__ */ jsx9("span", { children: href })
|
|
2401
2520
|
}
|
|
2402
2521
|
);
|
|
2403
2522
|
});
|
|
2404
2523
|
}
|
|
2405
2524
|
});
|
|
2406
|
-
var UnknownBlock =
|
|
2525
|
+
var UnknownBlock = Node3.create({
|
|
2407
2526
|
name: "unknownBlock",
|
|
2408
2527
|
group: "block",
|
|
2409
2528
|
atom: true,
|
|
@@ -2428,7 +2547,7 @@ var UnknownBlock = Node2.create({
|
|
|
2428
2547
|
function UnknownBlockView({ node }) {
|
|
2429
2548
|
const source = node.attrs.source;
|
|
2430
2549
|
const text = String(node.attrs.text ?? "");
|
|
2431
|
-
return /* @__PURE__ */
|
|
2550
|
+
return /* @__PURE__ */ jsx9(
|
|
2432
2551
|
NodeViewWrapper2,
|
|
2433
2552
|
{
|
|
2434
2553
|
"data-block-id": source?.id,
|
|
@@ -2438,7 +2557,7 @@ function UnknownBlockView({ node }) {
|
|
|
2438
2557
|
}
|
|
2439
2558
|
);
|
|
2440
2559
|
}
|
|
2441
|
-
var AttachmentNode =
|
|
2560
|
+
var AttachmentNode = Node3.create({
|
|
2442
2561
|
name: "attachment",
|
|
2443
2562
|
group: "block",
|
|
2444
2563
|
atom: true,
|
|
@@ -2468,7 +2587,7 @@ var AttachmentNode = Node2.create({
|
|
|
2468
2587
|
addNodeView() {
|
|
2469
2588
|
const View = this.options.view;
|
|
2470
2589
|
if (!View) return null;
|
|
2471
|
-
return ReactNodeViewRenderer2(({ node }) => /* @__PURE__ */
|
|
2590
|
+
return ReactNodeViewRenderer2(({ node }) => /* @__PURE__ */ jsx9(NodeViewWrapper2, { className: "my-2", children: /* @__PURE__ */ jsx9(View, { attrs: node.attrs }) }));
|
|
2472
2591
|
}
|
|
2473
2592
|
});
|
|
2474
2593
|
var TICK = "checklistTick";
|
|
@@ -2537,7 +2656,7 @@ function listItemView(editor, node, view, getPos) {
|
|
|
2537
2656
|
}
|
|
2538
2657
|
};
|
|
2539
2658
|
}
|
|
2540
|
-
var Checklist =
|
|
2659
|
+
var Checklist = Extension11.create({
|
|
2541
2660
|
name: "checklist",
|
|
2542
2661
|
// Before the list item's own Enter and Backspace.
|
|
2543
2662
|
priority: 101,
|
|
@@ -2609,7 +2728,7 @@ var Checklist = Extension10.create({
|
|
|
2609
2728
|
];
|
|
2610
2729
|
}
|
|
2611
2730
|
});
|
|
2612
|
-
var Callout =
|
|
2731
|
+
var Callout = Extension11.create({
|
|
2613
2732
|
name: "callout",
|
|
2614
2733
|
addGlobalAttributes() {
|
|
2615
2734
|
return [
|
|
@@ -2641,6 +2760,7 @@ export {
|
|
|
2641
2760
|
EditorBlockHandle,
|
|
2642
2761
|
EditorTableControls,
|
|
2643
2762
|
FORMATS,
|
|
2763
|
+
InlineText,
|
|
2644
2764
|
KeptSelection,
|
|
2645
2765
|
LinkChips,
|
|
2646
2766
|
PastedImages,
|