@bettercms-ai/kit 2.0.0-next.0 → 2.0.0-next.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/adapters/lossy.d.ts +5 -1
- package/dist/adapters/lossy.js +10 -5
- package/dist/adapters/lossy.js.map +1 -1
- package/dist/adapters/prod-types.d.ts +9 -22
- package/dist/adapters/prod-types.js +36 -35
- package/dist/adapters/prod-types.js.map +1 -1
- package/dist/adapters/schema.js +56 -39
- package/dist/adapters/schema.js.map +1 -1
- package/dist/context.d.ts +39 -0
- package/dist/context.js +40 -1
- package/dist/context.js.map +1 -1
- package/dist/controls/link.js +112 -196
- package/dist/controls/link.js.map +1 -1
- package/dist/controls/location.js +3 -8
- package/dist/controls/location.js.map +1 -1
- package/dist/controls/media.d.ts +0 -14
- package/dist/controls/media.js +52 -95
- package/dist/controls/media.js.map +1 -1
- package/dist/controls/rich-text/article-shell.d.ts +145 -0
- package/dist/controls/rich-text/article-shell.js +510 -0
- package/dist/controls/rich-text/article-shell.js.map +1 -0
- package/dist/controls/rich-text/author.d.ts +25 -0
- package/dist/controls/rich-text/author.js +104 -0
- package/dist/controls/rich-text/author.js.map +1 -0
- package/dist/controls/rich-text/blocks.d.ts +13 -2
- package/dist/controls/rich-text/blocks.js +86 -638
- package/dist/controls/rich-text/blocks.js.map +1 -1
- package/dist/controls/rich-text/button.d.ts +23 -0
- package/dist/controls/rich-text/button.js +85 -0
- package/dist/controls/rich-text/button.js.map +1 -0
- package/dist/controls/rich-text/catalog.d.ts +3 -3
- package/dist/controls/rich-text/catalog.js +20 -4
- package/dist/controls/rich-text/catalog.js.map +1 -1
- package/dist/controls/rich-text/checklist.d.ts +24 -0
- package/dist/controls/rich-text/checklist.js +115 -0
- package/dist/controls/rich-text/checklist.js.map +1 -0
- package/dist/controls/rich-text/codec.d.ts +1 -1
- package/dist/controls/rich-text/codec.js +4 -1
- package/dist/controls/rich-text/codec.js.map +1 -1
- package/dist/controls/rich-text/columns.d.ts +41 -0
- package/dist/controls/rich-text/columns.js +181 -0
- package/dist/controls/rich-text/columns.js.map +1 -0
- package/dist/controls/rich-text/dom.d.ts +5 -4
- package/dist/controls/rich-text/dom.js +13 -4
- package/dist/controls/rich-text/dom.js.map +1 -1
- package/dist/controls/rich-text/editor.js +92 -10
- package/dist/controls/rich-text/editor.js.map +1 -1
- package/dist/controls/rich-text/embed.d.ts +28 -0
- package/dist/controls/rich-text/embed.js +210 -0
- package/dist/controls/rich-text/embed.js.map +1 -0
- package/dist/controls/rich-text/footnote.d.ts +41 -0
- package/dist/controls/rich-text/footnote.js +185 -0
- package/dist/controls/rich-text/footnote.js.map +1 -0
- package/dist/controls/rich-text/gallery.d.ts +28 -0
- package/dist/controls/rich-text/gallery.js +167 -0
- package/dist/controls/rich-text/gallery.js.map +1 -0
- package/dist/controls/rich-text/link-form.d.ts +3 -1
- package/dist/controls/rich-text/link-form.js +2 -2
- package/dist/controls/rich-text/link-form.js.map +1 -1
- package/dist/controls/rich-text/related.d.ts +36 -0
- package/dist/controls/rich-text/related.js +213 -0
- package/dist/controls/rich-text/related.js.map +1 -0
- package/dist/controls/rich-text/toc.d.ts +46 -0
- package/dist/controls/rich-text/toc.js +161 -0
- package/dist/controls/rich-text/toc.js.map +1 -0
- package/dist/core/core.d.ts +10 -3
- package/dist/core/core.js +22 -6
- package/dist/core/core.js.map +1 -1
- package/dist/core/facets.d.ts +8 -0
- package/dist/core/facets.js +9 -1
- package/dist/core/facets.js.map +1 -1
- package/dist/core/index.js +2 -2
- package/dist/index.js +4 -4
- package/dist/library/kit-catalog.json +45 -44
- package/dist/schema/types.d.ts +7 -0
- package/dist/schema/types.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/ui/autocomplete.d.ts +29 -1
- package/dist/ui/autocomplete.js +102 -47
- package/dist/ui/autocomplete.js.map +1 -1
- package/dist/ui/button.js +3 -5
- package/dist/ui/button.js.map +1 -1
- package/dist/ui/index.js +2 -2
- package/dist/ui/toast.js +1 -1
- package/package.json +3 -1
|
@@ -12,9 +12,11 @@ import { LinkForm } from "./link-form.js";
|
|
|
12
12
|
import { CatalogComponentsProvider, InsertMenuContent, SlashMenuPanel, blockAllowed, catalogKey, noteRecent, useCatalog } from "./catalog.js";
|
|
13
13
|
import { openComponentPanel } from "./component-panel.js";
|
|
14
14
|
import { Island } from "./blocks.js";
|
|
15
|
+
import { duplicateBlock, ensureLineAfter, insertBasic, insertIsland, liveInlineCode, liveMarkdown, moveBlock, restrictHtml, turnInto } from "./ops.js";
|
|
16
|
+
import { ButtonLinkPanel, applyButton, buttonAt, buttonInitial, insertButton, removeButton } from "./button.js";
|
|
17
|
+
import { checklistShortcut, insertChecklist, syncTaskA11y, toggleTaskAtPointer, toggleTaskFromKey } from "./checklist.js";
|
|
15
18
|
import { ALL_FEATURES } from "./codec.js";
|
|
16
19
|
import { htmlToMarkdown, looksLikeMarkdown, markdownToHtml } from "./markdown.js";
|
|
17
|
-
import { duplicateBlock, ensureLineAfter, insertBasic, insertIsland, liveInlineCode, liveMarkdown, moveBlock, restrictHtml, turnInto } from "./ops.js";
|
|
18
20
|
import { EMPTY_FMT, FormatToolbar, MARK_FEATURE, stylesFor } from "./toolbar.js";
|
|
19
21
|
import { SelectionBubble } from "./floating.js";
|
|
20
22
|
import * as React from "react";
|
|
@@ -112,11 +114,23 @@ function insertHtmlAtCaret(html) {
|
|
|
112
114
|
s.addRange(r);
|
|
113
115
|
}
|
|
114
116
|
}
|
|
115
|
-
var NOT_COUNTED =
|
|
117
|
+
var NOT_COUNTED = [
|
|
118
|
+
"[data-rt=component]",
|
|
119
|
+
"[data-rt=pullquote]",
|
|
120
|
+
"[data-rt=takeaways]",
|
|
121
|
+
"[data-rt=toc]",
|
|
122
|
+
"[data-rt=related]",
|
|
123
|
+
"[data-rt=author]",
|
|
124
|
+
"[data-rt=embed]",
|
|
125
|
+
"[data-rt=video]",
|
|
126
|
+
"[data-rt=file]",
|
|
127
|
+
"[data-rt=footnotes]",
|
|
128
|
+
"sup[data-rt=fn]"
|
|
129
|
+
].join(",");
|
|
116
130
|
var WORDS = (s) => s.replace(/\u200b/g, "").trim().split(/\s+/).filter(Boolean).length;
|
|
117
131
|
function countWords(html) {
|
|
118
132
|
if (!html) return 0;
|
|
119
|
-
if (!/data-rt="(?:component|pullquote|takeaways|embed|video|file)"/.test(html) || typeof DOMParser === "undefined") return WORDS(html.replace(
|
|
133
|
+
if (!/data-rt="(?:component|pullquote|takeaways|toc|related|author|embed|video|file|footnotes|fn)"/.test(html) || typeof DOMParser === "undefined") return WORDS(html.replace(/<[^>]+>/g, " ").replace(/ |&[a-z]+;/g, " "));
|
|
120
134
|
const doc = new DOMParser().parseFromString(`<body>${html}</body>`, "text/html");
|
|
121
135
|
doc.body.querySelectorAll(NOT_COUNTED).forEach((n) => n.remove());
|
|
122
136
|
doc.body.querySelectorAll("p,li,h1,h2,h3,h4,h5,h6,td,th,figcaption,summary,pre,blockquote,div").forEach((n) => n.append(" "));
|
|
@@ -128,7 +142,7 @@ var countComponents = (html) => (html.match(/data-rt="component"/g) ?? []).lengt
|
|
|
128
142
|
var bodyCountLabel = (html) => {
|
|
129
143
|
const w = countWords(html);
|
|
130
144
|
const c = countComponents(html);
|
|
131
|
-
return `${w.toLocaleString("en-US")} ${w === 1 ? "word" : "words"}${c ? ` · ${c} ${c === 1 ? "
|
|
145
|
+
return `${w.toLocaleString("en-US")} ${w === 1 ? "word" : "words"}${c ? ` · ${c} ${c === 1 ? "component" : "components"}` : ""}`;
|
|
132
146
|
};
|
|
133
147
|
function insertTextAtCaret(text) {
|
|
134
148
|
if (exec("insertText", text)) return;
|
|
@@ -273,6 +287,7 @@ function RichTextEditor({ value, onChange, readOnly, placeholder, docKey, featur
|
|
|
273
287
|
if (!el) return;
|
|
274
288
|
el.innerHTML = sanitize(html || "") || "<p><br></p>";
|
|
275
289
|
hydrate(el);
|
|
290
|
+
syncTaskA11y(el);
|
|
276
291
|
known.current = html;
|
|
277
292
|
setEmpty(isEmptyHtml(html));
|
|
278
293
|
setWords(countWords(html));
|
|
@@ -283,6 +298,7 @@ function RichTextEditor({ value, onChange, readOnly, placeholder, docKey, featur
|
|
|
283
298
|
const el = ref.current;
|
|
284
299
|
if (!el) return;
|
|
285
300
|
syncIslands();
|
|
301
|
+
syncTaskA11y(el);
|
|
286
302
|
const html = serialize(el);
|
|
287
303
|
setEmpty(isEmptyHtml(html) && !el.querySelector(":scope > [data-rt-island], :scope > hr"));
|
|
288
304
|
setWords(countWords(html));
|
|
@@ -568,7 +584,14 @@ function RichTextEditor({ value, onChange, readOnly, placeholder, docKey, featur
|
|
|
568
584
|
}
|
|
569
585
|
if (!it.id || !blockAllowed(it.id, allows)) return;
|
|
570
586
|
noteRecent(it);
|
|
571
|
-
|
|
587
|
+
if (it.id === "task") insertChecklist(el);
|
|
588
|
+
else if (it.id === "button") {
|
|
589
|
+
const a = insertButton(el);
|
|
590
|
+
emit();
|
|
591
|
+
refresh();
|
|
592
|
+
openButton(a);
|
|
593
|
+
return;
|
|
594
|
+
} else insertBasic(el, it.id);
|
|
572
595
|
emit();
|
|
573
596
|
refresh();
|
|
574
597
|
};
|
|
@@ -645,6 +668,11 @@ function RichTextEditor({ value, onChange, readOnly, placeholder, docKey, featur
|
|
|
645
668
|
}
|
|
646
669
|
const mod = e.metaKey || e.ctrlKey;
|
|
647
670
|
const k = eventKey(e);
|
|
671
|
+
if (!mod && !e.altKey && !readOnly && ref.current && toggleTaskFromKey(ref.current, e.key)) {
|
|
672
|
+
e.preventDefault();
|
|
673
|
+
emit();
|
|
674
|
+
return;
|
|
675
|
+
}
|
|
648
676
|
if (mod && !e.altKey && k === "k") {
|
|
649
677
|
e.preventDefault();
|
|
650
678
|
saveSel();
|
|
@@ -750,6 +778,11 @@ function RichTextEditor({ value, onChange, readOnly, placeholder, docKey, featur
|
|
|
750
778
|
hist.current.textAt = Date.now();
|
|
751
779
|
hist.current.future = [];
|
|
752
780
|
}
|
|
781
|
+
if (!single && ne.inputType === "insertText" && allows("checklist") && checklistShortcut(ref.current, ne.data)) {
|
|
782
|
+
setSlash(null);
|
|
783
|
+
emit();
|
|
784
|
+
return;
|
|
785
|
+
}
|
|
753
786
|
if (!single && ne.inputType === "insertText" && (ne.data === " " || ne.data === "-") && liveMarkdown(ref.current, ne.data, allows)) {
|
|
754
787
|
setSlash(null);
|
|
755
788
|
emit();
|
|
@@ -789,6 +822,7 @@ function RichTextEditor({ value, onChange, readOnly, placeholder, docKey, featur
|
|
|
789
822
|
restoreSel();
|
|
790
823
|
const s = window.getSelection();
|
|
791
824
|
const anchor = (s?.anchorNode?.nodeType === 1 ? s.anchorNode : s?.anchorNode?.parentElement)?.closest("a") ?? null;
|
|
825
|
+
if (anchor && ref.current && buttonAt(ref.current, anchor)) return openButton(anchor);
|
|
792
826
|
if (!anchor && (!s || s.isCollapsed || !s.toString().trim())) {
|
|
793
827
|
notify("Select some text first", { description: hints ? "Then press ⌘K to link it." : "Then link it." });
|
|
794
828
|
return;
|
|
@@ -804,6 +838,28 @@ function RichTextEditor({ value, onChange, readOnly, placeholder, docKey, featur
|
|
|
804
838
|
} : { href: "" }
|
|
805
839
|
});
|
|
806
840
|
};
|
|
841
|
+
/** V2 rich-text-editor.tsx:865-873: a button's popover, its label above the link form */
|
|
842
|
+
const openButton = (a) => {
|
|
843
|
+
if (readOnly) return;
|
|
844
|
+
const { link: initial, label } = buttonInitial(a);
|
|
845
|
+
setBubble(null);
|
|
846
|
+
setLink({
|
|
847
|
+
rect: a.getBoundingClientRect(),
|
|
848
|
+
existing: a,
|
|
849
|
+
initial,
|
|
850
|
+
button: {
|
|
851
|
+
a,
|
|
852
|
+
label
|
|
853
|
+
}
|
|
854
|
+
});
|
|
855
|
+
};
|
|
856
|
+
const saveButton = (v, label) => {
|
|
857
|
+
const b = link?.button;
|
|
858
|
+
setLink(null);
|
|
859
|
+
if (!b) return;
|
|
860
|
+
applyButton(b.a, v, label);
|
|
861
|
+
emit();
|
|
862
|
+
};
|
|
807
863
|
const saveLink = (v) => {
|
|
808
864
|
const l = link;
|
|
809
865
|
setLink(null);
|
|
@@ -1072,7 +1128,8 @@ function RichTextEditor({ value, onChange, readOnly, placeholder, docKey, featur
|
|
|
1072
1128
|
moveBlock: moveBlock$1,
|
|
1073
1129
|
islandUndo,
|
|
1074
1130
|
islandRedo,
|
|
1075
|
-
startDrag
|
|
1131
|
+
startDrag,
|
|
1132
|
+
allows
|
|
1076
1133
|
});
|
|
1077
1134
|
api.current = {
|
|
1078
1135
|
emit,
|
|
@@ -1085,7 +1142,8 @@ function RichTextEditor({ value, onChange, readOnly, placeholder, docKey, featur
|
|
|
1085
1142
|
moveBlock: moveBlock$1,
|
|
1086
1143
|
islandUndo,
|
|
1087
1144
|
islandRedo,
|
|
1088
|
-
startDrag
|
|
1145
|
+
startDrag,
|
|
1146
|
+
allows
|
|
1089
1147
|
};
|
|
1090
1148
|
const islandCtx = React.useMemo(() => ({
|
|
1091
1149
|
readOnly,
|
|
@@ -1100,7 +1158,8 @@ function RichTextEditor({ value, onChange, readOnly, placeholder, docKey, featur
|
|
|
1100
1158
|
move: (x, dir) => api.current.moveBlock(x, dir),
|
|
1101
1159
|
undo: () => api.current.islandUndo(),
|
|
1102
1160
|
redo: () => api.current.islandRedo(),
|
|
1103
|
-
drag: (x, e) => api.current.startDrag(x, e)
|
|
1161
|
+
drag: (x, e) => api.current.startDrag(x, e),
|
|
1162
|
+
allows: (f) => api.current.allows(f)
|
|
1104
1163
|
}), [readOnly, dense]);
|
|
1105
1164
|
const commentSel = onComment ? () => {
|
|
1106
1165
|
restoreSel();
|
|
@@ -1305,6 +1364,17 @@ function RichTextEditor({ value, onChange, readOnly, placeholder, docKey, featur
|
|
|
1305
1364
|
onKeyDown,
|
|
1306
1365
|
onKeyUp: refresh,
|
|
1307
1366
|
onMouseUp: refresh,
|
|
1367
|
+
onMouseDown: (e) => {
|
|
1368
|
+
if (readOnly || !ref.current || !toggleTaskAtPointer(ref.current, e.target, e.clientX)) return;
|
|
1369
|
+
e.preventDefault();
|
|
1370
|
+
emit();
|
|
1371
|
+
},
|
|
1372
|
+
onClick: (e) => {
|
|
1373
|
+
const a = ref.current ? buttonAt(ref.current, e.target) : null;
|
|
1374
|
+
if (!a || readOnly) return;
|
|
1375
|
+
e.preventDefault();
|
|
1376
|
+
openButton(a);
|
|
1377
|
+
},
|
|
1308
1378
|
onPaste: (e) => {
|
|
1309
1379
|
if (readOnly) return;
|
|
1310
1380
|
if (Array.from(e.clipboardData.files).filter((f) => f.type.startsWith("image/")).length) {
|
|
@@ -1506,7 +1576,7 @@ function RichTextEditor({ value, onChange, readOnly, placeholder, docKey, featur
|
|
|
1506
1576
|
words.toLocaleString("en-US"),
|
|
1507
1577
|
" ",
|
|
1508
1578
|
words === 1 ? "word" : "words",
|
|
1509
|
-
comps ? ` · ${comps} ${comps === 1 ? "
|
|
1579
|
+
comps ? ` · ${comps} ${comps === 1 ? "component" : "components"}` : "",
|
|
1510
1580
|
" · ",
|
|
1511
1581
|
Math.max(1, Math.round(words / 220)),
|
|
1512
1582
|
" min read"
|
|
@@ -1579,7 +1649,19 @@ function RichTextEditor({ value, onChange, readOnly, placeholder, docKey, featur
|
|
|
1579
1649
|
}) }), /* @__PURE__ */ jsx(PopoverContent, {
|
|
1580
1650
|
className: "w-[340px] rounded-kit-lg p-3",
|
|
1581
1651
|
finalFocus: false,
|
|
1582
|
-
children: link ? /* @__PURE__ */ jsx(
|
|
1652
|
+
children: link?.button ? /* @__PURE__ */ jsx(ButtonLinkPanel, {
|
|
1653
|
+
initial: link.initial,
|
|
1654
|
+
label: link.button.label,
|
|
1655
|
+
allowNewTab,
|
|
1656
|
+
onSave: saveButton,
|
|
1657
|
+
onCancel: () => setLink(null),
|
|
1658
|
+
onDetach: () => {
|
|
1659
|
+
const a = link.button.a;
|
|
1660
|
+
setLink(null);
|
|
1661
|
+
if (ref.current) removeButton(ref.current, a);
|
|
1662
|
+
emit();
|
|
1663
|
+
}
|
|
1664
|
+
}) : link ? /* @__PURE__ */ jsx("div", {
|
|
1583
1665
|
className: "flex flex-col gap-2",
|
|
1584
1666
|
children: /* @__PURE__ */ jsx(LinkForm, {
|
|
1585
1667
|
initial: link.initial,
|