@elabs-ai/components-editor 4.1.0 → 5.0.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/{chunk-C62O7IOQ.js → chunk-FO5S3YZM.js} +241 -158
- package/dist/chunk-FO5S3YZM.js.map +1 -0
- package/dist/index.d.ts +5 -4
- package/dist/index.js +57 -39
- package/dist/index.js.map +1 -1
- package/dist/markdown/index.d.ts +2 -2
- package/dist/markdown/index.js +265 -188
- package/dist/markdown/index.js.map +1 -1
- package/dist/{markdown-editor-CBp_4eDv.d.ts → markdown-editor-Dn-0L_MM.d.ts} +8 -1
- package/dist/monaco.d.ts +2 -0
- package/dist/monaco.js +9 -0
- package/dist/monaco.js.map +1 -0
- package/package.json +9 -5
- package/src/ai-objects/decision-card.tsx +15 -9
- package/src/ai-objects/knowledge-card.tsx +18 -9
- package/src/barrel-monaco-lazy.test.ts +50 -0
- package/src/calc-block/calc-block.tsx +11 -7
- package/src/code-editor/code-editor.test.tsx +141 -14
- package/src/code-editor/code-editor.tsx +166 -35
- package/src/code-workspace/code-workspace.test.tsx +31 -12
- package/src/copy-button/copy-button.tsx +6 -3
- package/src/diff-editor/diff-editor.test.tsx +9 -3
- package/src/diff-editor/diff-editor.tsx +47 -23
- package/src/editor-toolbar/editor-toolbar.tsx +8 -2
- package/src/index.ts +4 -3
- package/src/markdown-academic/citations.tsx +14 -7
- package/src/markdown-academic/footnotes.tsx +1 -1
- package/src/markdown-academic/math.tsx +7 -4
- package/src/markdown-editor/completions/completions-menu.tsx +5 -2
- package/src/markdown-editor/directive-views.tsx +33 -19
- package/src/markdown-editor/markdown-editor.stories.tsx +9 -3
- package/src/markdown-editor/slash/slash-menu.tsx +5 -2
- package/src/markdown-editor/table-view.tsx +28 -15
- package/src/markdown-iteration/iteration-builder-dialog.tsx +39 -18
- package/src/markdown-iteration/template-dialog.tsx +25 -7
- package/src/markdown-outline/document-outline.tsx +6 -2
- package/src/markdown-preview/markdown-preview-academic.test.tsx +3 -3
- package/src/markdown-toolbar/markdown-toolbar.tsx +42 -24
- package/src/markdown-workspace/markdown-workspace.test.tsx +22 -3
- package/src/markdown-workspace/markdown-workspace.tsx +6 -3
- package/src/mermaid-diagram/mermaid-diagram-fixes.test.tsx +130 -0
- package/src/mermaid-diagram/mermaid-diagram.test.tsx +2 -1
- package/src/mermaid-diagram/mermaid-diagram.tsx +89 -40
- package/src/mermaid-diagram/mermaid-viewer.tsx +21 -20
- package/src/monaco.ts +21 -0
- package/dist/chunk-C62O7IOQ.js.map +0 -1
|
@@ -11,12 +11,12 @@ import {
|
|
|
11
11
|
} from "@elabs-ai/components-ui";
|
|
12
12
|
import "react";
|
|
13
13
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
14
|
-
function EditorContextMenu({ editor
|
|
14
|
+
function EditorContextMenu({ editor, readOnly = false, children }) {
|
|
15
15
|
const selection = () => {
|
|
16
|
-
if (!
|
|
17
|
-
const model =
|
|
18
|
-
const sel =
|
|
19
|
-
return model && sel ? { editor
|
|
16
|
+
if (!editor) return null;
|
|
17
|
+
const model = editor.getModel();
|
|
18
|
+
const sel = editor.getSelection();
|
|
19
|
+
return model && sel ? { editor, model, sel } : null;
|
|
20
20
|
};
|
|
21
21
|
const copy = async () => {
|
|
22
22
|
const ctx2 = selection();
|
|
@@ -51,8 +51,8 @@ function EditorContextMenu({ editor: editor2, readOnly = false, children }) {
|
|
|
51
51
|
ctx2.editor.focus();
|
|
52
52
|
};
|
|
53
53
|
const runAction = (id) => {
|
|
54
|
-
|
|
55
|
-
void
|
|
54
|
+
editor?.focus();
|
|
55
|
+
void editor?.getAction(id)?.run();
|
|
56
56
|
};
|
|
57
57
|
return /* @__PURE__ */ jsxs(ContextMenu, { children: [
|
|
58
58
|
/* @__PURE__ */ jsx(ContextMenuTrigger, { asChild: true, children }),
|
|
@@ -360,12 +360,12 @@ function buildBrandThemeData(rootEl) {
|
|
|
360
360
|
function brandThemeId(theme) {
|
|
361
361
|
return `brand-${theme}`;
|
|
362
362
|
}
|
|
363
|
-
function applyBrandTheme(
|
|
363
|
+
function applyBrandTheme(monaco, theme, rootEl) {
|
|
364
364
|
const id = brandThemeId(theme);
|
|
365
365
|
const data = buildBrandThemeData(rootEl);
|
|
366
366
|
data.base = builtinBase(rootEl);
|
|
367
|
-
|
|
368
|
-
|
|
367
|
+
monaco.editor.defineTheme(id, data);
|
|
368
|
+
monaco.editor.setTheme(id);
|
|
369
369
|
return id;
|
|
370
370
|
}
|
|
371
371
|
|
|
@@ -402,7 +402,6 @@ function useDataTheme(target) {
|
|
|
402
402
|
}
|
|
403
403
|
|
|
404
404
|
// src/code-editor/code-editor.tsx
|
|
405
|
-
import * as monaco from "monaco-editor";
|
|
406
405
|
import { cn } from "@elabs-ai/components-ui/lib/cn";
|
|
407
406
|
import {
|
|
408
407
|
forwardRef,
|
|
@@ -412,6 +411,20 @@ import {
|
|
|
412
411
|
useState as useState2
|
|
413
412
|
} from "react";
|
|
414
413
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
414
|
+
function computeMinimalEdit(oldValue, newValue) {
|
|
415
|
+
const maxCommon = Math.min(oldValue.length, newValue.length);
|
|
416
|
+
let start = 0;
|
|
417
|
+
while (start < maxCommon && oldValue.charCodeAt(start) === newValue.charCodeAt(start)) {
|
|
418
|
+
start++;
|
|
419
|
+
}
|
|
420
|
+
let endOld = oldValue.length;
|
|
421
|
+
let endNew = newValue.length;
|
|
422
|
+
while (endOld > start && endNew > start && oldValue.charCodeAt(endOld - 1) === newValue.charCodeAt(endNew - 1)) {
|
|
423
|
+
endOld--;
|
|
424
|
+
endNew--;
|
|
425
|
+
}
|
|
426
|
+
return { start, endOld, text: newValue.slice(start, endNew) };
|
|
427
|
+
}
|
|
415
428
|
var BASE_OPTIONS = {
|
|
416
429
|
automaticLayout: true,
|
|
417
430
|
minimap: { enabled: false },
|
|
@@ -443,70 +456,123 @@ var CodeEditor = forwardRef(function CodeEditor2({
|
|
|
443
456
|
...props
|
|
444
457
|
}, ref) {
|
|
445
458
|
const containerRef = useRef(null);
|
|
446
|
-
const [
|
|
459
|
+
const [editor, setEditor] = useState2(null);
|
|
447
460
|
const { theme, revision } = useDataTheme();
|
|
461
|
+
const modelRef = useRef(null);
|
|
462
|
+
const monacoRef = useRef(null);
|
|
448
463
|
const onChangeRef = useRef(onChange);
|
|
449
464
|
onChangeRef.current = onChange;
|
|
450
465
|
const onMountRef = useRef(onMount);
|
|
451
466
|
onMountRef.current = onMount;
|
|
452
|
-
useImperativeHandle(ref, () =>
|
|
453
|
-
|
|
467
|
+
useImperativeHandle(ref, () => editor, [
|
|
468
|
+
editor
|
|
454
469
|
]);
|
|
455
470
|
useEffect2(() => {
|
|
456
471
|
const container = containerRef.current;
|
|
457
472
|
if (!container) return;
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
)
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
473
|
+
let cancelled = false;
|
|
474
|
+
let instance = null;
|
|
475
|
+
let model = null;
|
|
476
|
+
let sub = null;
|
|
477
|
+
import("monaco-editor").then((monacoApi) => {
|
|
478
|
+
if (cancelled) return;
|
|
479
|
+
monacoRef.current = monacoApi;
|
|
480
|
+
model = monacoApi.editor.createModel(
|
|
481
|
+
value ?? defaultValue ?? "",
|
|
482
|
+
language,
|
|
483
|
+
path ? monacoApi.Uri.parse(`inmemory://brand/${path}`) : void 0
|
|
484
|
+
);
|
|
485
|
+
modelRef.current = model;
|
|
486
|
+
instance = monacoApi.editor.create(container, {
|
|
487
|
+
...BASE_OPTIONS,
|
|
488
|
+
readOnly,
|
|
489
|
+
// Disable Monaco's own menu unless explicitly opted into; "brand" renders
|
|
490
|
+
// brand-ui's ContextMenu around the editor instead.
|
|
491
|
+
contextmenu: contextMenu === "monaco",
|
|
492
|
+
// Monaco's accessible name comes from this construction option (it writes it
|
|
493
|
+
// onto its inner screen-reader <textarea>), not from a wrapper-div attribute.
|
|
494
|
+
...ariaLabel !== void 0 ? { ariaLabel } : null,
|
|
495
|
+
model,
|
|
496
|
+
...options
|
|
497
|
+
});
|
|
498
|
+
sub = instance.onDidChangeModelContent(() => {
|
|
499
|
+
onChangeRef.current?.(instance.getValue());
|
|
500
|
+
});
|
|
501
|
+
const textarea = instance.getDomNode()?.querySelector("textarea");
|
|
502
|
+
if (textarea) {
|
|
503
|
+
if (ariaLabel !== void 0) textarea.setAttribute("aria-label", ariaLabel);
|
|
504
|
+
if (ariaInvalid !== void 0) textarea.setAttribute("aria-invalid", String(ariaInvalid));
|
|
505
|
+
if (ariaDescribedBy !== void 0)
|
|
506
|
+
textarea.setAttribute("aria-describedby", ariaDescribedBy);
|
|
507
|
+
}
|
|
508
|
+
setEditor(instance);
|
|
509
|
+
onMountRef.current?.(instance, monacoApi);
|
|
477
510
|
});
|
|
478
|
-
setEditor(instance);
|
|
479
|
-
onMountRef.current?.(instance, monaco);
|
|
480
511
|
return () => {
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
512
|
+
cancelled = true;
|
|
513
|
+
sub?.dispose();
|
|
514
|
+
instance?.dispose();
|
|
515
|
+
model?.dispose();
|
|
516
|
+
modelRef.current = null;
|
|
517
|
+
monacoRef.current = null;
|
|
484
518
|
setEditor(null);
|
|
485
519
|
};
|
|
486
520
|
}, []);
|
|
487
521
|
useEffect2(() => {
|
|
488
|
-
|
|
489
|
-
if (
|
|
490
|
-
|
|
522
|
+
const monacoApi = monacoRef.current;
|
|
523
|
+
if (!editor || !monacoApi) return;
|
|
524
|
+
const current = modelRef.current;
|
|
525
|
+
const currentUri = current?.uri?.toString();
|
|
526
|
+
const nextUri = path ? monacoApi.Uri.parse(`inmemory://brand/${path}`).toString() : void 0;
|
|
527
|
+
if (currentUri === nextUri) return;
|
|
528
|
+
const nextModel = monacoApi.editor.createModel(
|
|
529
|
+
current?.getValue() ?? value ?? defaultValue ?? "",
|
|
530
|
+
language,
|
|
531
|
+
path ? monacoApi.Uri.parse(`inmemory://brand/${path}`) : void 0
|
|
532
|
+
);
|
|
533
|
+
editor.setModel(nextModel);
|
|
534
|
+
modelRef.current = nextModel;
|
|
535
|
+
current?.dispose();
|
|
536
|
+
}, [editor, path]);
|
|
537
|
+
useEffect2(() => {
|
|
538
|
+
const monacoApi = monacoRef.current;
|
|
539
|
+
if (!editor || !monacoApi || value === void 0) return;
|
|
540
|
+
const model = editor.getModel();
|
|
541
|
+
if (!model) return;
|
|
542
|
+
const current = model.getValue();
|
|
543
|
+
if (value === current) return;
|
|
544
|
+
const { start, endOld, text } = computeMinimalEdit(current, value);
|
|
545
|
+
const range = monacoApi.Range.fromPositions(
|
|
546
|
+
model.getPositionAt(start),
|
|
547
|
+
model.getPositionAt(endOld)
|
|
548
|
+
);
|
|
549
|
+
editor.executeEdits("controlled-value-sync", [{ range, text }]);
|
|
550
|
+
}, [editor, value]);
|
|
551
|
+
useEffect2(() => {
|
|
552
|
+
const monacoApi = monacoRef.current;
|
|
553
|
+
const model = editor?.getModel();
|
|
554
|
+
if (model && monacoApi) monacoApi.editor.setModelLanguage(model, language);
|
|
555
|
+
}, [editor, language]);
|
|
491
556
|
useEffect2(() => {
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
}, [editor2, language]);
|
|
557
|
+
editor?.updateOptions({ readOnly, contextmenu: contextMenu === "monaco" });
|
|
558
|
+
}, [editor, readOnly, contextMenu]);
|
|
495
559
|
useEffect2(() => {
|
|
496
|
-
|
|
497
|
-
|
|
560
|
+
if (!editor || !options) return;
|
|
561
|
+
editor.updateOptions(options);
|
|
562
|
+
}, [editor, options]);
|
|
498
563
|
useEffect2(() => {
|
|
499
|
-
|
|
564
|
+
const monacoApi = monacoRef.current;
|
|
565
|
+
if (!editor || !monacoApi) return;
|
|
500
566
|
try {
|
|
501
|
-
applyBrandTheme(
|
|
567
|
+
applyBrandTheme(monacoApi, theme);
|
|
502
568
|
} catch (err) {
|
|
503
569
|
console.error("[@elabs-ai/components-editor] failed to apply brand theme", err);
|
|
504
570
|
}
|
|
505
|
-
}, [
|
|
571
|
+
}, [editor, theme, revision]);
|
|
506
572
|
useEffect2(() => {
|
|
507
|
-
if (!
|
|
508
|
-
if (ariaLabel !== void 0)
|
|
509
|
-
const textarea =
|
|
573
|
+
if (!editor) return;
|
|
574
|
+
if (ariaLabel !== void 0) editor.updateOptions({ ariaLabel });
|
|
575
|
+
const textarea = editor.getDomNode()?.querySelector("textarea");
|
|
510
576
|
if (!textarea) return;
|
|
511
577
|
if (ariaLabel === void 0) textarea.removeAttribute("aria-label");
|
|
512
578
|
else textarea.setAttribute("aria-label", ariaLabel);
|
|
@@ -514,12 +580,12 @@ var CodeEditor = forwardRef(function CodeEditor2({
|
|
|
514
580
|
else textarea.setAttribute("aria-invalid", String(ariaInvalid));
|
|
515
581
|
if (ariaDescribedBy === void 0) textarea.removeAttribute("aria-describedby");
|
|
516
582
|
else textarea.setAttribute("aria-describedby", ariaDescribedBy);
|
|
517
|
-
}, [
|
|
583
|
+
}, [editor, ariaLabel, ariaInvalid, ariaDescribedBy]);
|
|
518
584
|
useEffect2(() => {
|
|
519
|
-
if (!
|
|
520
|
-
const disposables = actions.map((a) =>
|
|
585
|
+
if (!editor || !actions || actions.length === 0) return;
|
|
586
|
+
const disposables = actions.map((a) => editor.addAction(a));
|
|
521
587
|
return () => disposables.forEach((d) => d.dispose());
|
|
522
|
-
}, [
|
|
588
|
+
}, [editor, actions]);
|
|
523
589
|
const resolvedStyle = {
|
|
524
590
|
height: typeof height === "number" ? `${height}px` : height,
|
|
525
591
|
...style
|
|
@@ -535,7 +601,7 @@ var CodeEditor = forwardRef(function CodeEditor2({
|
|
|
535
601
|
}
|
|
536
602
|
);
|
|
537
603
|
if (contextMenu === "brand") {
|
|
538
|
-
return /* @__PURE__ */ jsx2(EditorContextMenu, { editor
|
|
604
|
+
return /* @__PURE__ */ jsx2(EditorContextMenu, { editor, readOnly, children: editorEl });
|
|
539
605
|
}
|
|
540
606
|
return editorEl;
|
|
541
607
|
});
|
|
@@ -950,6 +1016,7 @@ function parseMarkdownOutline(markdown) {
|
|
|
950
1016
|
}
|
|
951
1017
|
|
|
952
1018
|
// src/markdown-outline/document-outline.tsx
|
|
1019
|
+
import { useLocale } from "@elabs-ai/components-ui";
|
|
953
1020
|
import { cn as cn2 } from "@elabs-ai/components-ui/lib/cn";
|
|
954
1021
|
import { forwardRef as forwardRef2, useMemo } from "react";
|
|
955
1022
|
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
@@ -958,12 +1025,13 @@ function useMarkdownOutline(markdown) {
|
|
|
958
1025
|
}
|
|
959
1026
|
var DocumentOutline = forwardRef2(
|
|
960
1027
|
function DocumentOutline2({ items, activeId, onSelect, itemActions, className, ...props }, ref) {
|
|
1028
|
+
const { t } = useLocale();
|
|
961
1029
|
const minLevel = items.reduce((min, it) => Math.min(min, it.level), 6);
|
|
962
1030
|
return /* @__PURE__ */ jsxs2(
|
|
963
1031
|
"nav",
|
|
964
1032
|
{
|
|
965
1033
|
ref,
|
|
966
|
-
"aria-label": "
|
|
1034
|
+
"aria-label": t("editor.documentOutline.label"),
|
|
967
1035
|
className: cn2("text-body", className),
|
|
968
1036
|
...props,
|
|
969
1037
|
children: [
|
|
@@ -990,7 +1058,7 @@ var DocumentOutline = forwardRef2(
|
|
|
990
1058
|
actions ? /* @__PURE__ */ jsx3("span", { className: "absolute end-0.5 top-1/2 -translate-y-1/2 opacity-0 transition-opacity duration-fast ease-standard focus-within:opacity-100 group-hover/outline-item:opacity-100 has-[[aria-pressed=true]]:opacity-100 motion-reduce:transition-none", children: actions }) : null
|
|
991
1059
|
] }, item.id);
|
|
992
1060
|
}) }),
|
|
993
|
-
items.length === 0 ? /* @__PURE__ */ jsx3("p", { className: "px-2 py-1 text-caption text-muted-foreground", children: "
|
|
1061
|
+
items.length === 0 ? /* @__PURE__ */ jsx3("p", { className: "px-2 py-1 text-caption text-muted-foreground", children: t("editor.documentOutline.empty") }) : null
|
|
994
1062
|
]
|
|
995
1063
|
}
|
|
996
1064
|
);
|
|
@@ -1765,6 +1833,7 @@ function groupSlashCommands(commands) {
|
|
|
1765
1833
|
}
|
|
1766
1834
|
|
|
1767
1835
|
// src/markdown-editor/slash/slash-menu.tsx
|
|
1836
|
+
import { useLocale as useLocale2 } from "@elabs-ai/components-ui";
|
|
1768
1837
|
import { cn as cn4 } from "@elabs-ai/components-ui/lib/cn";
|
|
1769
1838
|
import { forwardRef as forwardRef4 } from "react";
|
|
1770
1839
|
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
@@ -1776,17 +1845,19 @@ var SlashMenu = forwardRef4(function SlashMenu2({
|
|
|
1776
1845
|
activeId,
|
|
1777
1846
|
onSelect,
|
|
1778
1847
|
idPrefix = "brand-slash",
|
|
1779
|
-
emptyLabel
|
|
1848
|
+
emptyLabel: emptyLabelProp,
|
|
1780
1849
|
className,
|
|
1781
1850
|
...props
|
|
1782
1851
|
}, ref) {
|
|
1852
|
+
const { t } = useLocale2();
|
|
1853
|
+
const emptyLabel = emptyLabelProp ?? t("editor.slashMenu.noMatchingBlocks");
|
|
1783
1854
|
const groups = groupSlashCommands(commands);
|
|
1784
1855
|
return /* @__PURE__ */ jsx5(
|
|
1785
1856
|
"div",
|
|
1786
1857
|
{
|
|
1787
1858
|
ref,
|
|
1788
1859
|
role: "listbox",
|
|
1789
|
-
"aria-label": "
|
|
1860
|
+
"aria-label": t("editor.slashMenu.insertBlock"),
|
|
1790
1861
|
className: cn4(
|
|
1791
1862
|
"max-h-[min(320px,60vh)] w-72 overflow-y-auto overflow-x-hidden rounded-md bg-popover p-1 text-popover-foreground shadow-ring-md",
|
|
1792
1863
|
className
|
|
@@ -2335,6 +2406,7 @@ import { useWidgetViewContext as useWidgetViewContext2 } from "@prosemirror-adap
|
|
|
2335
2406
|
import { useLayoutEffect as useLayoutEffect2, useRef as useRef3 } from "react";
|
|
2336
2407
|
|
|
2337
2408
|
// src/markdown-editor/completions/completions-menu.tsx
|
|
2409
|
+
import { useLocale as useLocale3 } from "@elabs-ai/components-ui";
|
|
2338
2410
|
import { cn as cn5 } from "@elabs-ai/components-ui/lib/cn";
|
|
2339
2411
|
import { forwardRef as forwardRef5 } from "react";
|
|
2340
2412
|
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
@@ -2347,16 +2419,18 @@ var CompletionMenu = forwardRef5(
|
|
|
2347
2419
|
activeIndex,
|
|
2348
2420
|
onSelect,
|
|
2349
2421
|
idPrefix = "brand-completions",
|
|
2350
|
-
emptyLabel
|
|
2422
|
+
emptyLabel: emptyLabelProp,
|
|
2351
2423
|
className,
|
|
2352
2424
|
...props
|
|
2353
2425
|
}, ref) {
|
|
2426
|
+
const { t } = useLocale3();
|
|
2427
|
+
const emptyLabel = emptyLabelProp ?? t("editor.completions.noSuggestions");
|
|
2354
2428
|
return /* @__PURE__ */ jsx7(
|
|
2355
2429
|
"div",
|
|
2356
2430
|
{
|
|
2357
2431
|
ref,
|
|
2358
2432
|
role: "listbox",
|
|
2359
|
-
"aria-label": "
|
|
2433
|
+
"aria-label": t("editor.completions.suggestions"),
|
|
2360
2434
|
className: cn5(
|
|
2361
2435
|
"max-h-[min(280px,50vh)] w-64 overflow-y-auto overflow-x-hidden rounded-md bg-popover p-1 text-popover-foreground shadow-ring-md",
|
|
2362
2436
|
className
|
|
@@ -2474,7 +2548,8 @@ import {
|
|
|
2474
2548
|
DropdownMenuSub,
|
|
2475
2549
|
DropdownMenuSubContent,
|
|
2476
2550
|
DropdownMenuSubTrigger,
|
|
2477
|
-
DropdownMenuTrigger
|
|
2551
|
+
DropdownMenuTrigger,
|
|
2552
|
+
useLocale as useLocale4
|
|
2478
2553
|
} from "@elabs-ai/components-ui";
|
|
2479
2554
|
import { cn as cn6 } from "@elabs-ai/components-ui/lib/cn";
|
|
2480
2555
|
import { editorViewCtx as editorViewCtx2, parserCtx as parserCtx2, serializerCtx } from "@milkdown/kit/core";
|
|
@@ -2511,16 +2586,16 @@ function useGetEditor() {
|
|
|
2511
2586
|
if (!getEditor) return;
|
|
2512
2587
|
if (!div) return;
|
|
2513
2588
|
dom.current = div;
|
|
2514
|
-
const
|
|
2515
|
-
if (!
|
|
2589
|
+
const editor = getEditor(div);
|
|
2590
|
+
if (!editor) return;
|
|
2516
2591
|
setLoading(true);
|
|
2517
|
-
|
|
2518
|
-
editorRef.current =
|
|
2592
|
+
editor.create().then((editor2) => {
|
|
2593
|
+
editorRef.current = editor2;
|
|
2519
2594
|
}).finally(() => {
|
|
2520
2595
|
setLoading(false);
|
|
2521
2596
|
}).catch(console.error);
|
|
2522
2597
|
return () => {
|
|
2523
|
-
const destroyPromise =
|
|
2598
|
+
const destroyPromise = editor.destroy().catch(console.error);
|
|
2524
2599
|
pendingDestroys.add(destroyPromise);
|
|
2525
2600
|
void destroyPromise.finally(() => {
|
|
2526
2601
|
pendingDestroys.delete(destroyPromise);
|
|
@@ -2539,10 +2614,10 @@ var Milkdown = () => {
|
|
|
2539
2614
|
var MilkdownProvider = ({ children }) => {
|
|
2540
2615
|
const dom = useRef5(void 0);
|
|
2541
2616
|
const [editorFactory, setEditorFactory] = useState3(void 0);
|
|
2542
|
-
const
|
|
2617
|
+
const editor = useRef5(void 0);
|
|
2543
2618
|
const [loading, setLoading] = useState3(true);
|
|
2544
2619
|
const editorInfoCtx = useMemo2(
|
|
2545
|
-
() => ({ loading, dom, editor
|
|
2620
|
+
() => ({ loading, dom, editor, setLoading, editorFactory, setEditorFactory }),
|
|
2546
2621
|
[loading, editorFactory]
|
|
2547
2622
|
);
|
|
2548
2623
|
return /* @__PURE__ */ jsx9(editorInfoContext.Provider, { value: editorInfoCtx, children });
|
|
@@ -2642,6 +2717,7 @@ function InlineEdit({ value, onCommit, ariaLabel, placeholder, className }) {
|
|
|
2642
2717
|
);
|
|
2643
2718
|
}
|
|
2644
2719
|
function ContainerDirectiveView() {
|
|
2720
|
+
const { t } = useLocale4();
|
|
2645
2721
|
const { contentRef } = useNodeViewContext();
|
|
2646
2722
|
const { name, attributes, update } = useDirectiveAttrs();
|
|
2647
2723
|
const body = /* @__PURE__ */ jsx10("div", { className: "brand-directive__body", ref: contentRef });
|
|
@@ -2650,8 +2726,8 @@ function ContainerDirectiveView() {
|
|
|
2650
2726
|
/* @__PURE__ */ jsx10(CardHeader, { className: "pb-3", children: /* @__PURE__ */ jsx10(CardTitle, { children: /* @__PURE__ */ jsx10(
|
|
2651
2727
|
InlineEdit,
|
|
2652
2728
|
{
|
|
2653
|
-
ariaLabel: "
|
|
2654
|
-
placeholder: "
|
|
2729
|
+
ariaLabel: t("editor.directiveViews.cardTitle"),
|
|
2730
|
+
placeholder: t("editor.directiveViews.cardTitle"),
|
|
2655
2731
|
value: attributes.title ?? "",
|
|
2656
2732
|
onCommit: (v) => update("title", v)
|
|
2657
2733
|
}
|
|
@@ -2671,7 +2747,7 @@ function ContainerDirectiveView() {
|
|
|
2671
2747
|
/* @__PURE__ */ jsx10("div", { className: "mb-1 font-medium leading-none tracking-tight", children: /* @__PURE__ */ jsx10(
|
|
2672
2748
|
InlineEdit,
|
|
2673
2749
|
{
|
|
2674
|
-
ariaLabel: "
|
|
2750
|
+
ariaLabel: t("editor.directiveViews.calloutTitle"),
|
|
2675
2751
|
placeholder: capitalize(attributes.type ?? "note"),
|
|
2676
2752
|
value: attributes.title ?? "",
|
|
2677
2753
|
onCommit: (v) => update("title", v)
|
|
@@ -2696,10 +2772,7 @@ function ContainerDirectiveView() {
|
|
|
2696
2772
|
className: "brand-directive brand-directive--unknown",
|
|
2697
2773
|
"data-brand-directive": name,
|
|
2698
2774
|
children: [
|
|
2699
|
-
/* @__PURE__ */
|
|
2700
|
-
"Unknown block: ",
|
|
2701
|
-
name
|
|
2702
|
-
] }),
|
|
2775
|
+
/* @__PURE__ */ jsx10("div", { className: "mb-1 font-medium leading-none tracking-tight", children: t("editor.directiveViews.unknownBlock", { name }) }),
|
|
2703
2776
|
/* @__PURE__ */ jsx10(AlertDescription, { children: body })
|
|
2704
2777
|
]
|
|
2705
2778
|
}
|
|
@@ -2707,9 +2780,9 @@ function ContainerDirectiveView() {
|
|
|
2707
2780
|
}
|
|
2708
2781
|
function readBodyMarkdown(getInstance, node) {
|
|
2709
2782
|
try {
|
|
2710
|
-
const
|
|
2711
|
-
if (!
|
|
2712
|
-
return
|
|
2783
|
+
const editor = getInstance();
|
|
2784
|
+
if (!editor) return node.textContent;
|
|
2785
|
+
return editor.action((ctx2) => {
|
|
2713
2786
|
const serialize = ctx2.get(
|
|
2714
2787
|
serializerCtx
|
|
2715
2788
|
);
|
|
@@ -2722,10 +2795,10 @@ function readBodyMarkdown(getInstance, node) {
|
|
|
2722
2795
|
}
|
|
2723
2796
|
function writeBodyMarkdown(getInstance, getPos, template) {
|
|
2724
2797
|
try {
|
|
2725
|
-
const
|
|
2798
|
+
const editor = getInstance();
|
|
2726
2799
|
const pos = getPos();
|
|
2727
|
-
if (!
|
|
2728
|
-
|
|
2800
|
+
if (!editor || pos == null) return;
|
|
2801
|
+
editor.action((ctx2) => {
|
|
2729
2802
|
const parse = ctx2.get(
|
|
2730
2803
|
parserCtx2
|
|
2731
2804
|
);
|
|
@@ -2753,10 +2826,10 @@ function mergeAttrsOmittingEmpty(attrs, next) {
|
|
|
2753
2826
|
function replaceNodeWithMarkdown(getInstance, getPos, markdown) {
|
|
2754
2827
|
if (!markdown.trim()) return;
|
|
2755
2828
|
try {
|
|
2756
|
-
const
|
|
2829
|
+
const editor = getInstance();
|
|
2757
2830
|
const pos = getPos();
|
|
2758
|
-
if (!
|
|
2759
|
-
|
|
2831
|
+
if (!editor || pos == null) return;
|
|
2832
|
+
editor.action((ctx2) => {
|
|
2760
2833
|
const parse = ctx2.get(
|
|
2761
2834
|
parserCtx2
|
|
2762
2835
|
);
|
|
@@ -2806,6 +2879,7 @@ function IterationMenuItems({
|
|
|
2806
2879
|
}) });
|
|
2807
2880
|
}
|
|
2808
2881
|
function IterationDirectiveView() {
|
|
2882
|
+
const { t } = useLocale4();
|
|
2809
2883
|
const { contentRef, node, getPos, setAttrs } = useNodeViewContext();
|
|
2810
2884
|
const { name, attributes } = useDirectiveAttrs();
|
|
2811
2885
|
const [, getInstance] = useInstance();
|
|
@@ -2860,7 +2934,7 @@ function IterationDirectiveView() {
|
|
|
2860
2934
|
as: attributes.as || "item",
|
|
2861
2935
|
attributes
|
|
2862
2936
|
}).cells.length > 0;
|
|
2863
|
-
const disabledHint = "
|
|
2937
|
+
const disabledHint = t("editor.directiveViews.needsEmbeddedValues");
|
|
2864
2938
|
const convertToStatic = () => {
|
|
2865
2939
|
const template = readBodyMarkdown(getInstance, node);
|
|
2866
2940
|
const value = builderValueFromParts(kind, attributes, template);
|
|
@@ -2870,14 +2944,14 @@ function IterationDirectiveView() {
|
|
|
2870
2944
|
{
|
|
2871
2945
|
type: "item",
|
|
2872
2946
|
id: "edit",
|
|
2873
|
-
label: "
|
|
2947
|
+
label: t("editor.directiveViews.editIteration"),
|
|
2874
2948
|
icon: /* @__PURE__ */ jsx10(Pencil, { className: "size-4", "aria-hidden": "true" }),
|
|
2875
2949
|
onSelect: requestEdit
|
|
2876
2950
|
},
|
|
2877
2951
|
{
|
|
2878
2952
|
type: "layout",
|
|
2879
2953
|
id: "layout",
|
|
2880
|
-
label: "
|
|
2954
|
+
label: t("editor.directiveViews.changeLayout"),
|
|
2881
2955
|
icon: /* @__PURE__ */ jsx10(LayoutGrid, { className: "size-4", "aria-hidden": "true" }),
|
|
2882
2956
|
value: attributes.layout || ITERATION_LAYOUTS[kind][0],
|
|
2883
2957
|
options: ITERATION_LAYOUTS[kind],
|
|
@@ -2887,7 +2961,7 @@ function IterationDirectiveView() {
|
|
|
2887
2961
|
{
|
|
2888
2962
|
type: "item",
|
|
2889
2963
|
id: "transpose",
|
|
2890
|
-
label: hasEmbeddedData ? "
|
|
2964
|
+
label: hasEmbeddedData ? t("editor.directiveViews.transpose") : `${t("editor.directiveViews.transpose")} ${disabledHint}`,
|
|
2891
2965
|
icon: /* @__PURE__ */ jsx10(ArrowLeftRight, { className: "size-4", "aria-hidden": "true" }),
|
|
2892
2966
|
onSelect: transpose,
|
|
2893
2967
|
disabled: !hasEmbeddedData
|
|
@@ -2896,7 +2970,7 @@ function IterationDirectiveView() {
|
|
|
2896
2970
|
{
|
|
2897
2971
|
type: "item",
|
|
2898
2972
|
id: "convert-to-static",
|
|
2899
|
-
label: hasEmbeddedData ? "
|
|
2973
|
+
label: hasEmbeddedData ? t("editor.directiveViews.convertToStatic") : `${t("editor.directiveViews.convertToStatic")} ${disabledHint}`,
|
|
2900
2974
|
icon: /* @__PURE__ */ jsx10(FileText, { className: "size-4", "aria-hidden": "true" }),
|
|
2901
2975
|
onSelect: convertToStatic,
|
|
2902
2976
|
disabled: !hasEmbeddedData
|
|
@@ -2904,20 +2978,17 @@ function IterationDirectiveView() {
|
|
|
2904
2978
|
];
|
|
2905
2979
|
const header = /* @__PURE__ */ jsxs6("div", { className: "mb-1.5 flex items-center gap-1.5 text-meta font-medium text-info-text", children: [
|
|
2906
2980
|
/* @__PURE__ */ jsx10(Icon, { className: "size-3.5 shrink-0", "aria-hidden": "true" }),
|
|
2907
|
-
/* @__PURE__ */ jsx10("span", { children: isPivot ? "
|
|
2908
|
-
!isPivot && attributes.as ? /* @__PURE__ */
|
|
2909
|
-
|
|
2910
|
-
attributes.as
|
|
2911
|
-
] }) : null,
|
|
2912
|
-
/* @__PURE__ */ jsx10("span", { className: "font-normal text-muted-foreground", children: "\u2014 template" }),
|
|
2981
|
+
/* @__PURE__ */ jsx10("span", { children: isPivot ? t("editor.directiveViews.pivot") : t("editor.directiveViews.iterate") }),
|
|
2982
|
+
!isPivot && attributes.as ? /* @__PURE__ */ jsx10("span", { className: "font-normal text-muted-foreground", children: t("editor.directiveViews.perItem", { as: attributes.as }) }) : null,
|
|
2983
|
+
/* @__PURE__ */ jsx10("span", { className: "font-normal text-muted-foreground", children: t("editor.directiveViews.templateSuffix") }),
|
|
2913
2984
|
onEdit ? /* @__PURE__ */ jsxs6(DropdownMenu, { children: [
|
|
2914
2985
|
/* @__PURE__ */ jsx10(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx10(
|
|
2915
2986
|
"button",
|
|
2916
2987
|
{
|
|
2917
2988
|
type: "button",
|
|
2918
2989
|
"data-directive-chrome": "",
|
|
2919
|
-
"aria-label": "
|
|
2920
|
-
title: "
|
|
2990
|
+
"aria-label": t("editor.directiveViews.iterationActions"),
|
|
2991
|
+
title: t("editor.directiveViews.iterationActionsTitle"),
|
|
2921
2992
|
className: "ms-auto inline-flex size-5 items-center justify-center rounded-sm text-muted-foreground hover:bg-accent hover:text-foreground focus-ring",
|
|
2922
2993
|
children: /* @__PURE__ */ jsx10(MoreHorizontal, { className: "size-4", "aria-hidden": "true" })
|
|
2923
2994
|
}
|
|
@@ -2958,6 +3029,7 @@ function IterationDirectiveView() {
|
|
|
2958
3029
|
] });
|
|
2959
3030
|
}
|
|
2960
3031
|
function LeafDirectiveView() {
|
|
3032
|
+
const { t } = useLocale4();
|
|
2961
3033
|
const { name, attributes, update } = useDirectiveAttrs();
|
|
2962
3034
|
if (name !== "metric") {
|
|
2963
3035
|
return /* @__PURE__ */ jsxs6(
|
|
@@ -2966,7 +3038,8 @@ function LeafDirectiveView() {
|
|
|
2966
3038
|
className: "brand-directive brand-directive--leaf brand-directive--unknown rounded-md border border-destructive/40 bg-surface-muted p-3 text-sm text-muted-foreground",
|
|
2967
3039
|
"data-brand-leaf": name,
|
|
2968
3040
|
children: [
|
|
2969
|
-
"
|
|
3041
|
+
t("editor.directiveViews.unknownInlineBlock"),
|
|
3042
|
+
" ",
|
|
2970
3043
|
/* @__PURE__ */ jsxs6("code", { children: [
|
|
2971
3044
|
"::",
|
|
2972
3045
|
name
|
|
@@ -2984,8 +3057,8 @@ function LeafDirectiveView() {
|
|
|
2984
3057
|
label: /* @__PURE__ */ jsx10(
|
|
2985
3058
|
InlineEdit,
|
|
2986
3059
|
{
|
|
2987
|
-
ariaLabel: "
|
|
2988
|
-
placeholder: "
|
|
3060
|
+
ariaLabel: t("editor.directiveViews.metricLabel"),
|
|
3061
|
+
placeholder: t("editor.directiveViews.metricLabelPlaceholder"),
|
|
2989
3062
|
value: attributes.label ?? "",
|
|
2990
3063
|
onCommit: (v) => update("label", v)
|
|
2991
3064
|
}
|
|
@@ -2993,8 +3066,8 @@ function LeafDirectiveView() {
|
|
|
2993
3066
|
value: /* @__PURE__ */ jsx10(
|
|
2994
3067
|
InlineEdit,
|
|
2995
3068
|
{
|
|
2996
|
-
ariaLabel: "
|
|
2997
|
-
placeholder: "
|
|
3069
|
+
ariaLabel: t("editor.directiveViews.metricValue"),
|
|
3070
|
+
placeholder: t("editor.directiveViews.metricValuePlaceholder"),
|
|
2998
3071
|
value: attributes.value ?? "",
|
|
2999
3072
|
onCommit: (v) => update("value", v),
|
|
3000
3073
|
className: "min-w-[1ch]"
|
|
@@ -3313,6 +3386,7 @@ import {
|
|
|
3313
3386
|
import { Plugin as Plugin7, PluginKey as PluginKey6 } from "@milkdown/kit/prose/state";
|
|
3314
3387
|
import { $prose as $prose7 } from "@milkdown/kit/utils";
|
|
3315
3388
|
import { isInTable } from "@milkdown/kit/prose/tables";
|
|
3389
|
+
import { useLocale as useLocale5 } from "@elabs-ai/components-ui";
|
|
3316
3390
|
import { cn as cn7 } from "@elabs-ai/components-ui/lib/cn";
|
|
3317
3391
|
import { usePluginViewContext } from "@prosemirror-adapter/react";
|
|
3318
3392
|
import { jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
@@ -3358,25 +3432,32 @@ function ToolbarDivider() {
|
|
|
3358
3432
|
}
|
|
3359
3433
|
function TableControlsView() {
|
|
3360
3434
|
const { view } = usePluginViewContext();
|
|
3435
|
+
const { t } = useLocale5();
|
|
3361
3436
|
const inTable = isInTable(view.state);
|
|
3362
3437
|
const run = (key) => () => dispatchCommand(view, key);
|
|
3363
3438
|
if (!inTable) return null;
|
|
3439
|
+
const addRowAbove = t("editor.tableView.addRowAbove");
|
|
3440
|
+
const addRowBelow = t("editor.tableView.addRowBelow");
|
|
3441
|
+
const deleteRow = t("editor.tableView.deleteRow");
|
|
3442
|
+
const addColLeft = t("editor.tableView.addColumnLeft");
|
|
3443
|
+
const addColRight = t("editor.tableView.addColumnRight");
|
|
3444
|
+
const deleteCol = t("editor.tableView.deleteColumn");
|
|
3364
3445
|
return /* @__PURE__ */ jsxs7(
|
|
3365
3446
|
"div",
|
|
3366
3447
|
{
|
|
3367
3448
|
role: "toolbar",
|
|
3368
|
-
"aria-label": "
|
|
3449
|
+
"aria-label": t("editor.tableView.tableControls"),
|
|
3369
3450
|
className: cn7(
|
|
3370
3451
|
"flex flex-wrap items-center gap-1 px-2 py-1.5",
|
|
3371
3452
|
"border-t border-border-strong bg-surface-muted"
|
|
3372
3453
|
),
|
|
3373
3454
|
children: [
|
|
3374
|
-
/* @__PURE__ */ jsx11("span", { className: "mr-1 select-none text-caption text-muted-foreground", children: "
|
|
3455
|
+
/* @__PURE__ */ jsx11("span", { className: "mr-1 select-none text-caption text-muted-foreground", children: t("editor.tableView.row") }),
|
|
3375
3456
|
/* @__PURE__ */ jsx11(
|
|
3376
3457
|
ToolbarButton,
|
|
3377
3458
|
{
|
|
3378
|
-
ariaLabel:
|
|
3379
|
-
title:
|
|
3459
|
+
ariaLabel: addRowAbove,
|
|
3460
|
+
title: addRowAbove,
|
|
3380
3461
|
onClick: run(addRowBeforeCommand.key),
|
|
3381
3462
|
children: "\u2191+"
|
|
3382
3463
|
}
|
|
@@ -3384,8 +3465,8 @@ function TableControlsView() {
|
|
|
3384
3465
|
/* @__PURE__ */ jsx11(
|
|
3385
3466
|
ToolbarButton,
|
|
3386
3467
|
{
|
|
3387
|
-
ariaLabel:
|
|
3388
|
-
title:
|
|
3468
|
+
ariaLabel: addRowBelow,
|
|
3469
|
+
title: addRowBelow,
|
|
3389
3470
|
onClick: run(addRowAfterCommand.key),
|
|
3390
3471
|
children: "\u2193+"
|
|
3391
3472
|
}
|
|
@@ -3393,20 +3474,20 @@ function TableControlsView() {
|
|
|
3393
3474
|
/* @__PURE__ */ jsx11(
|
|
3394
3475
|
ToolbarButton,
|
|
3395
3476
|
{
|
|
3396
|
-
ariaLabel:
|
|
3397
|
-
title:
|
|
3477
|
+
ariaLabel: deleteRow,
|
|
3478
|
+
title: deleteRow,
|
|
3398
3479
|
variant: "destructive",
|
|
3399
3480
|
onClick: run(deleteSelectedCellsCommand.key),
|
|
3400
3481
|
children: "\xD7row"
|
|
3401
3482
|
}
|
|
3402
3483
|
),
|
|
3403
3484
|
/* @__PURE__ */ jsx11(ToolbarDivider, {}),
|
|
3404
|
-
/* @__PURE__ */ jsx11("span", { className: "mr-1 select-none text-caption text-muted-foreground", children: "
|
|
3485
|
+
/* @__PURE__ */ jsx11("span", { className: "mr-1 select-none text-caption text-muted-foreground", children: t("editor.tableView.col") }),
|
|
3405
3486
|
/* @__PURE__ */ jsx11(
|
|
3406
3487
|
ToolbarButton,
|
|
3407
3488
|
{
|
|
3408
|
-
ariaLabel:
|
|
3409
|
-
title:
|
|
3489
|
+
ariaLabel: addColLeft,
|
|
3490
|
+
title: addColLeft,
|
|
3410
3491
|
onClick: run(addColBeforeCommand.key),
|
|
3411
3492
|
children: "\u2190+"
|
|
3412
3493
|
}
|
|
@@ -3414,8 +3495,8 @@ function TableControlsView() {
|
|
|
3414
3495
|
/* @__PURE__ */ jsx11(
|
|
3415
3496
|
ToolbarButton,
|
|
3416
3497
|
{
|
|
3417
|
-
ariaLabel:
|
|
3418
|
-
title:
|
|
3498
|
+
ariaLabel: addColRight,
|
|
3499
|
+
title: addColRight,
|
|
3419
3500
|
onClick: run(addColAfterCommand.key),
|
|
3420
3501
|
children: "\u2192+"
|
|
3421
3502
|
}
|
|
@@ -3423,8 +3504,8 @@ function TableControlsView() {
|
|
|
3423
3504
|
/* @__PURE__ */ jsx11(
|
|
3424
3505
|
ToolbarButton,
|
|
3425
3506
|
{
|
|
3426
|
-
ariaLabel:
|
|
3427
|
-
title:
|
|
3507
|
+
ariaLabel: deleteCol,
|
|
3508
|
+
title: deleteCol,
|
|
3428
3509
|
variant: "destructive",
|
|
3429
3510
|
onClick: run(deleteSelectedCellsCommand.key),
|
|
3430
3511
|
children: "\xD7col"
|
|
@@ -3460,8 +3541,8 @@ function tableViewPlugins(pluginViewFactory) {
|
|
|
3460
3541
|
|
|
3461
3542
|
// src/markdown-editor/markdown-editor.tsx
|
|
3462
3543
|
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
3463
|
-
function scrollHeadingBySlug(
|
|
3464
|
-
|
|
3544
|
+
function scrollHeadingBySlug(editor, slug) {
|
|
3545
|
+
editor.action((ctx2) => {
|
|
3465
3546
|
const view = ctx2.get(editorViewCtx3);
|
|
3466
3547
|
const { doc } = view.state;
|
|
3467
3548
|
const used = /* @__PURE__ */ new Map();
|
|
@@ -3521,7 +3602,7 @@ var MarkdownEditorView = forwardRef6(function MarkdownEditorView2({
|
|
|
3521
3602
|
const embedPlugin = pasteEmbedPlugin(
|
|
3522
3603
|
onEmbedAssetRef.current ? (file) => onEmbedAssetRef.current(file) : void 0
|
|
3523
3604
|
);
|
|
3524
|
-
let
|
|
3605
|
+
let editor = Editor.make().config((ctx2) => {
|
|
3525
3606
|
ctx2.set(rootCtx, root);
|
|
3526
3607
|
ctx2.set(defaultValueCtx, lastMarkdown.current);
|
|
3527
3608
|
ctx2.update(editorViewOptionsCtx, (prev) => ({
|
|
@@ -3542,7 +3623,7 @@ var MarkdownEditorView = forwardRef6(function MarkdownEditorView2({
|
|
|
3542
3623
|
)
|
|
3543
3624
|
);
|
|
3544
3625
|
if (slashEnabled) {
|
|
3545
|
-
|
|
3626
|
+
editor = editor.use(
|
|
3546
3627
|
brandSlashViewPlugins(widgetViewFactory, {
|
|
3547
3628
|
...slashConfigRef.current,
|
|
3548
3629
|
getIterationEditHandler: () => iterationEditHandlerRef.current
|
|
@@ -3550,14 +3631,14 @@ var MarkdownEditorView = forwardRef6(function MarkdownEditorView2({
|
|
|
3550
3631
|
);
|
|
3551
3632
|
}
|
|
3552
3633
|
if (calcEnabled) {
|
|
3553
|
-
|
|
3634
|
+
editor = editor.use(calcProsePlugins(() => calcRef.current));
|
|
3554
3635
|
}
|
|
3555
3636
|
if (completionsEnabled) {
|
|
3556
|
-
|
|
3637
|
+
editor = editor.use(
|
|
3557
3638
|
completionsViewPlugins(widgetViewFactory, () => completionsRef.current)
|
|
3558
3639
|
);
|
|
3559
3640
|
}
|
|
3560
|
-
return
|
|
3641
|
+
return editor;
|
|
3561
3642
|
},
|
|
3562
3643
|
[readOnly, ariaLabel, slashEnabled, calcEnabled, completionsEnabled]
|
|
3563
3644
|
);
|
|
@@ -3565,21 +3646,21 @@ var MarkdownEditorView = forwardRef6(function MarkdownEditorView2({
|
|
|
3565
3646
|
useEffect5(() => {
|
|
3566
3647
|
if (loading || value === void 0) return;
|
|
3567
3648
|
if (value === lastMarkdown.current) return;
|
|
3568
|
-
const
|
|
3569
|
-
if (!
|
|
3649
|
+
const editor = getInstance();
|
|
3650
|
+
if (!editor) return;
|
|
3570
3651
|
lastMarkdown.current = value;
|
|
3571
|
-
|
|
3652
|
+
editor.action(replaceAll(value));
|
|
3572
3653
|
}, [loading, value, getInstance]);
|
|
3573
3654
|
useImperativeHandle2(
|
|
3574
3655
|
ref,
|
|
3575
3656
|
() => {
|
|
3576
3657
|
const serializeSlice = (view) => {
|
|
3577
|
-
const
|
|
3578
|
-
if (!
|
|
3658
|
+
const editor = getInstance();
|
|
3659
|
+
if (!editor) return "";
|
|
3579
3660
|
const { selection } = view.state;
|
|
3580
3661
|
if (selection.empty) return "";
|
|
3581
3662
|
try {
|
|
3582
|
-
return
|
|
3663
|
+
return editor.action((ctx2) => {
|
|
3583
3664
|
const serialize = ctx2.get(serializerCtx2);
|
|
3584
3665
|
const doc = selection.content().content;
|
|
3585
3666
|
const wrapper = view.state.doc.type.schema.topNodeType.create(null, doc);
|
|
@@ -3591,10 +3672,10 @@ var MarkdownEditorView = forwardRef6(function MarkdownEditorView2({
|
|
|
3591
3672
|
};
|
|
3592
3673
|
serializeSliceRef.current = serializeSlice;
|
|
3593
3674
|
const parseAndReplace = (view, md) => {
|
|
3594
|
-
const
|
|
3595
|
-
if (!
|
|
3675
|
+
const editor = getInstance();
|
|
3676
|
+
if (!editor) return;
|
|
3596
3677
|
try {
|
|
3597
|
-
|
|
3678
|
+
editor.action((ctx2) => {
|
|
3598
3679
|
const parse = ctx2.get(parserCtx3);
|
|
3599
3680
|
const parsed = parse(md);
|
|
3600
3681
|
if (!parsed) {
|
|
@@ -3612,10 +3693,10 @@ var MarkdownEditorView = forwardRef6(function MarkdownEditorView2({
|
|
|
3612
3693
|
}
|
|
3613
3694
|
};
|
|
3614
3695
|
const getView = () => {
|
|
3615
|
-
const
|
|
3616
|
-
if (!
|
|
3696
|
+
const editor = getInstance();
|
|
3697
|
+
if (!editor) return null;
|
|
3617
3698
|
try {
|
|
3618
|
-
return
|
|
3699
|
+
return editor.action((ctx2) => ctx2.get(editorViewCtx3));
|
|
3619
3700
|
} catch {
|
|
3620
3701
|
return null;
|
|
3621
3702
|
}
|
|
@@ -3639,15 +3720,15 @@ var MarkdownEditorView = forwardRef6(function MarkdownEditorView2({
|
|
|
3639
3720
|
getMarkdown: () => getInstance()?.action(getMarkdown()) ?? lastMarkdown.current,
|
|
3640
3721
|
serialized: () => getInstance()?.action(getMarkdown()) ?? null,
|
|
3641
3722
|
scrollToHeading: (slug) => {
|
|
3642
|
-
const
|
|
3643
|
-
if (
|
|
3723
|
+
const editor = getInstance();
|
|
3724
|
+
if (editor) scrollHeadingBySlug(editor, slug);
|
|
3644
3725
|
},
|
|
3645
3726
|
revealLine: (line, _opts) => {
|
|
3646
|
-
const
|
|
3647
|
-
if (!
|
|
3648
|
-
const md =
|
|
3727
|
+
const editor = getInstance();
|
|
3728
|
+
if (!editor) return;
|
|
3729
|
+
const md = editor.action(getMarkdown());
|
|
3649
3730
|
const preceding = parseMarkdownOutline(md).filter((item) => item.line <= line).at(-1);
|
|
3650
|
-
if (preceding) scrollHeadingBySlug(
|
|
3731
|
+
if (preceding) scrollHeadingBySlug(editor, preceding.id);
|
|
3651
3732
|
}
|
|
3652
3733
|
};
|
|
3653
3734
|
},
|
|
@@ -3709,16 +3790,18 @@ var MarkdownEditor = forwardRef6(
|
|
|
3709
3790
|
);
|
|
3710
3791
|
|
|
3711
3792
|
// src/copy-button/copy-button.tsx
|
|
3712
|
-
import { Button, useCopyToClipboard } from "@elabs-ai/components-ui";
|
|
3793
|
+
import { Button, useCopyToClipboard, useLocale as useLocale6 } from "@elabs-ai/components-ui";
|
|
3713
3794
|
import { cn as cn9 } from "@elabs-ai/components-ui/lib/cn";
|
|
3714
3795
|
import { CheckIcon, CopyIcon } from "lucide-react";
|
|
3715
3796
|
import { useCallback as useCallback3 } from "react";
|
|
3716
3797
|
import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
3717
3798
|
function CopyButton({ value, label = true, className, ...props }) {
|
|
3718
3799
|
const { copied, copy } = useCopyToClipboard();
|
|
3800
|
+
const { t } = useLocale6();
|
|
3719
3801
|
const onClick = useCallback3(() => {
|
|
3720
3802
|
void copy(value);
|
|
3721
3803
|
}, [copy, value]);
|
|
3804
|
+
const text = copied ? t("editor.copyButton.copied") : t("copy");
|
|
3722
3805
|
return /* @__PURE__ */ jsxs8(
|
|
3723
3806
|
Button,
|
|
3724
3807
|
{
|
|
@@ -3728,7 +3811,7 @@ function CopyButton({ value, label = true, className, ...props }) {
|
|
|
3728
3811
|
type: "button",
|
|
3729
3812
|
className: cn9("h-7 gap-1.5", className),
|
|
3730
3813
|
onClick,
|
|
3731
|
-
"aria-label":
|
|
3814
|
+
"aria-label": text,
|
|
3732
3815
|
children: [
|
|
3733
3816
|
copied ? /* @__PURE__ */ jsx13(
|
|
3734
3817
|
CheckIcon,
|
|
@@ -3738,37 +3821,37 @@ function CopyButton({ value, label = true, className, ...props }) {
|
|
|
3738
3821
|
},
|
|
3739
3822
|
String(copied)
|
|
3740
3823
|
) : /* @__PURE__ */ jsx13(CopyIcon, { className: "size-4", "aria-hidden": "true" }),
|
|
3741
|
-
label ? /* @__PURE__ */ jsx13("span", { className: "text-xs", children:
|
|
3824
|
+
label ? /* @__PURE__ */ jsx13("span", { className: "text-xs", children: text }) : null
|
|
3742
3825
|
]
|
|
3743
3826
|
}
|
|
3744
3827
|
);
|
|
3745
3828
|
}
|
|
3746
3829
|
|
|
3747
3830
|
// src/lib/editor-content-access.ts
|
|
3748
|
-
function monacoContentAccess(
|
|
3831
|
+
function monacoContentAccess(editor) {
|
|
3749
3832
|
const readSelection = () => {
|
|
3750
|
-
const model =
|
|
3751
|
-
const selection =
|
|
3833
|
+
const model = editor.getModel();
|
|
3834
|
+
const selection = editor.getSelection();
|
|
3752
3835
|
if (!model || !selection) return { text: "", empty: true };
|
|
3753
3836
|
const text = model.getValueInRange(selection);
|
|
3754
3837
|
return { text, empty: selection.isEmpty() };
|
|
3755
3838
|
};
|
|
3756
3839
|
const applyAtSelection = (text) => {
|
|
3757
|
-
const selection =
|
|
3840
|
+
const selection = editor.getSelection();
|
|
3758
3841
|
if (!selection) return;
|
|
3759
|
-
|
|
3842
|
+
editor.executeEdits("editor-content-access", [
|
|
3760
3843
|
{ range: selection, text, forceMoveMarkers: true }
|
|
3761
3844
|
]);
|
|
3762
|
-
|
|
3845
|
+
editor.pushUndoStop();
|
|
3763
3846
|
};
|
|
3764
3847
|
return {
|
|
3765
|
-
getText: () =>
|
|
3848
|
+
getText: () => editor.getValue(),
|
|
3766
3849
|
getSelection: readSelection,
|
|
3767
3850
|
replaceSelection: applyAtSelection,
|
|
3768
3851
|
insertAtCursor: applyAtSelection,
|
|
3769
|
-
focus: () =>
|
|
3852
|
+
focus: () => editor.focus(),
|
|
3770
3853
|
onSelectionChange: (listener2) => {
|
|
3771
|
-
const sub =
|
|
3854
|
+
const sub = editor.onDidChangeCursorSelection(() => listener2(readSelection()));
|
|
3772
3855
|
return () => sub.dispose();
|
|
3773
3856
|
}
|
|
3774
3857
|
};
|
|
@@ -3834,4 +3917,4 @@ export {
|
|
|
3834
3917
|
CopyButton,
|
|
3835
3918
|
monacoContentAccess
|
|
3836
3919
|
};
|
|
3837
|
-
//# sourceMappingURL=chunk-
|
|
3920
|
+
//# sourceMappingURL=chunk-FO5S3YZM.js.map
|