@pixerate/editor-react 0.11.0 → 0.13.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/README.md +29 -2
- package/dist/canvas/index.cjs +283 -36
- package/dist/canvas/index.cjs.map +1 -1
- package/dist/canvas/index.d.cts +135 -3
- package/dist/canvas/index.d.ts +135 -3
- package/dist/canvas/index.js +251 -1
- package/dist/canvas/index.js.map +1 -1
- package/dist/chunk-MHTAR3RS.js +1103 -0
- package/dist/chunk-MHTAR3RS.js.map +1 -0
- package/dist/index.cjs +1424 -389
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +181 -50
- package/dist/index.d.ts +181 -50
- package/dist/index.js +604 -647
- package/dist/index.js.map +1 -1
- package/dist/spreadsheet/index.cjs +1134 -0
- package/dist/spreadsheet/index.cjs.map +1 -0
- package/dist/spreadsheet/index.d.cts +160 -0
- package/dist/spreadsheet/index.d.ts +160 -0
- package/dist/spreadsheet/index.js +19 -0
- package/dist/spreadsheet/index.js.map +1 -0
- package/package.json +15 -2
package/dist/index.js
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FormulaHints,
|
|
3
|
+
SpreadsheetContextMenu,
|
|
4
|
+
SpreadsheetEditor,
|
|
5
|
+
SpreadsheetGroupRow,
|
|
6
|
+
useFillHandle,
|
|
7
|
+
useSpreadsheetClipboard,
|
|
8
|
+
useSpreadsheetEditor
|
|
9
|
+
} from "./chunk-MHTAR3RS.js";
|
|
1
10
|
import {
|
|
2
11
|
ImageEditor,
|
|
3
12
|
useImageEditor
|
|
@@ -16,7 +25,8 @@ import {
|
|
|
16
25
|
plainTextToTipTapHtml,
|
|
17
26
|
plainTextToSlice,
|
|
18
27
|
getEditorText,
|
|
19
|
-
tokenizePrompt
|
|
28
|
+
tokenizePrompt,
|
|
29
|
+
FileImport
|
|
20
30
|
} from "@pixerate/editor";
|
|
21
31
|
var DEFAULT_TEMPLATES = [];
|
|
22
32
|
var DEFAULT_COLOR_MAP = /* @__PURE__ */ new Map([
|
|
@@ -41,8 +51,12 @@ function usePromptEditor({
|
|
|
41
51
|
onMilestone,
|
|
42
52
|
containerId = "editor-container",
|
|
43
53
|
jsonVariables,
|
|
44
|
-
speed = 2
|
|
54
|
+
speed = 2,
|
|
55
|
+
fileImport
|
|
45
56
|
}) {
|
|
57
|
+
const fileImportRef = useRef(fileImport);
|
|
58
|
+
fileImportRef.current = fileImport;
|
|
59
|
+
const fileImportEnabled = !!fileImport;
|
|
46
60
|
const slashCommandActiveRef = useRef(slashCommandActive);
|
|
47
61
|
slashCommandActiveRef.current = slashCommandActive;
|
|
48
62
|
const clearSlashCommandRef = useRef(clearSlashCommand);
|
|
@@ -97,7 +111,14 @@ function usePromptEditor({
|
|
|
97
111
|
TemplateSuggestions.configure({
|
|
98
112
|
templates
|
|
99
113
|
}),
|
|
100
|
-
LoadingNode
|
|
114
|
+
LoadingNode,
|
|
115
|
+
...fileImportEnabled ? [
|
|
116
|
+
FileImport.configure({
|
|
117
|
+
...typeof fileImportRef.current === "object" ? fileImportRef.current : {},
|
|
118
|
+
// Prompt editors only ever receive plain text.
|
|
119
|
+
asPlainText: true
|
|
120
|
+
})
|
|
121
|
+
] : []
|
|
101
122
|
],
|
|
102
123
|
content: plainTextToTipTapHtml(content),
|
|
103
124
|
onUpdate: ({ editor: ed }) => {
|
|
@@ -194,7 +215,7 @@ function usePromptEditor({
|
|
|
194
215
|
},
|
|
195
216
|
// Only options baked into extensions recreate the editor; editable state,
|
|
196
217
|
// placeholder, class names and content are applied to the live instance.
|
|
197
|
-
[resolvedColorMap, templateKey, speed, jsonVariablesKey]
|
|
218
|
+
[resolvedColorMap, templateKey, speed, jsonVariablesKey, fileImportEnabled]
|
|
198
219
|
);
|
|
199
220
|
useEffect(() => {
|
|
200
221
|
if (editor && !editor.isDestroyed) {
|
|
@@ -240,10 +261,22 @@ function usePromptEditor({
|
|
|
240
261
|
|
|
241
262
|
// src/hooks/useEditor.ts
|
|
242
263
|
import { useEditor as useTipTapEditor } from "@tiptap/react";
|
|
243
|
-
import {
|
|
264
|
+
import {
|
|
265
|
+
createRichTextPreset
|
|
266
|
+
} from "@pixerate/editor";
|
|
244
267
|
function useEditor2(options = {}) {
|
|
245
|
-
const {
|
|
246
|
-
|
|
268
|
+
const {
|
|
269
|
+
richTextOptions,
|
|
270
|
+
fileImport,
|
|
271
|
+
richClipboard,
|
|
272
|
+
extensions = [],
|
|
273
|
+
...editorOptions
|
|
274
|
+
} = options;
|
|
275
|
+
const preset = createRichTextPreset({
|
|
276
|
+
...fileImport !== void 0 ? { fileImport } : {},
|
|
277
|
+
...richClipboard !== void 0 ? { richClipboard } : {},
|
|
278
|
+
...richTextOptions
|
|
279
|
+
});
|
|
247
280
|
const combinedExtensions = [...preset, ...extensions];
|
|
248
281
|
return useTipTapEditor({
|
|
249
282
|
extensions: combinedExtensions,
|
|
@@ -473,6 +506,42 @@ function useHistoryShortcuts(manager, options = {}) {
|
|
|
473
506
|
}, [manager, enabled, target, ignoreEditableElements]);
|
|
474
507
|
}
|
|
475
508
|
|
|
509
|
+
// src/hooks/useFileImport.ts
|
|
510
|
+
import { useEffect as useEffect4, useMemo as useMemo2, useRef as useRef5, useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
511
|
+
import {
|
|
512
|
+
FileImportController
|
|
513
|
+
} from "@pixerate/editor";
|
|
514
|
+
function useFileImport(editor, options = {}) {
|
|
515
|
+
const editorRef = useRef5(editor);
|
|
516
|
+
editorRef.current = editor;
|
|
517
|
+
const controller = useMemo2(
|
|
518
|
+
() => new FileImportController(() => {
|
|
519
|
+
const current = editorRef.current;
|
|
520
|
+
return current && !current.isDestroyed ? current : null;
|
|
521
|
+
}, options),
|
|
522
|
+
[]
|
|
523
|
+
);
|
|
524
|
+
useEffect4(() => {
|
|
525
|
+
controller.setOptions(options);
|
|
526
|
+
});
|
|
527
|
+
const state = useSyncExternalStore2(controller.subscribe, controller.getState, controller.getState);
|
|
528
|
+
return {
|
|
529
|
+
...state,
|
|
530
|
+
accept: controller.accept,
|
|
531
|
+
openFilePicker: controller.openFilePicker,
|
|
532
|
+
importFiles: controller.importFiles
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
// src/hooks/useAgentToolProvider.ts
|
|
537
|
+
import { useEffect as useEffect5 } from "react";
|
|
538
|
+
function useAgentToolProvider(registry, provider) {
|
|
539
|
+
useEffect5(() => {
|
|
540
|
+
if (!registry || !provider) return;
|
|
541
|
+
return registry.register(provider);
|
|
542
|
+
}, [registry, provider]);
|
|
543
|
+
}
|
|
544
|
+
|
|
476
545
|
// src/components/EditorContent.tsx
|
|
477
546
|
import {
|
|
478
547
|
EditorContent as TipTapEditorContent
|
|
@@ -487,7 +556,7 @@ var EditorContent = ({
|
|
|
487
556
|
};
|
|
488
557
|
|
|
489
558
|
// src/components/BubbleMenu.tsx
|
|
490
|
-
import { useEffect as
|
|
559
|
+
import { useEffect as useEffect6, useRef as useRef6, useState as useState3 } from "react";
|
|
491
560
|
import { createPortal } from "react-dom";
|
|
492
561
|
import {
|
|
493
562
|
BubbleMenuPlugin
|
|
@@ -501,12 +570,12 @@ var BubbleMenu = ({
|
|
|
501
570
|
pluginKey = "bubbleMenu",
|
|
502
571
|
updateDelay
|
|
503
572
|
}) => {
|
|
504
|
-
const menuEl =
|
|
573
|
+
const menuEl = useRef6(null);
|
|
505
574
|
const [mounted, setMounted] = useState3(false);
|
|
506
575
|
if (!menuEl.current && typeof document !== "undefined") {
|
|
507
576
|
menuEl.current = document.createElement("div");
|
|
508
577
|
}
|
|
509
|
-
|
|
578
|
+
useEffect6(() => {
|
|
510
579
|
if (!editor || !menuEl.current || editor.isDestroyed) {
|
|
511
580
|
return;
|
|
512
581
|
}
|
|
@@ -537,28 +606,31 @@ var BubbleMenu = ({
|
|
|
537
606
|
};
|
|
538
607
|
|
|
539
608
|
// src/components/TemplateRenderer.tsx
|
|
540
|
-
import { useMemo as
|
|
609
|
+
import { useMemo as useMemo3 } from "react";
|
|
541
610
|
import {
|
|
542
|
-
|
|
611
|
+
evaluatePromptTokens,
|
|
543
612
|
resolveTemplates
|
|
544
613
|
} from "@pixerate/editor";
|
|
545
|
-
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
614
|
+
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
615
|
+
var CONDITIONAL_PREFIX = { if: "?", unless: "!", end: "/" };
|
|
546
616
|
var TemplateRenderer = ({
|
|
547
617
|
content,
|
|
548
618
|
templates = [],
|
|
549
619
|
templateColorMap,
|
|
550
620
|
resolve = false,
|
|
621
|
+
bindings,
|
|
622
|
+
values,
|
|
551
623
|
className = "font-mono text-sm leading-relaxed whitespace-pre-wrap break-words",
|
|
552
624
|
onTemplateClick,
|
|
553
625
|
onVariableClick
|
|
554
626
|
}) => {
|
|
555
|
-
const displayText =
|
|
627
|
+
const displayText = useMemo3(() => {
|
|
556
628
|
if (!resolve || templates.length === 0) return content;
|
|
557
|
-
return resolveTemplates(content, templates);
|
|
558
|
-
}, [content, templates, resolve]);
|
|
559
|
-
const tokens =
|
|
560
|
-
return
|
|
561
|
-
}, [displayText]);
|
|
629
|
+
return resolveTemplates(content, templates, { bindings });
|
|
630
|
+
}, [content, templates, resolve, bindings]);
|
|
631
|
+
const tokens = useMemo3(() => {
|
|
632
|
+
return evaluatePromptTokens(displayText, values);
|
|
633
|
+
}, [displayText, values]);
|
|
562
634
|
return /* @__PURE__ */ jsx2("div", { className, children: tokens.map((token, index) => {
|
|
563
635
|
if (token.type === "template") {
|
|
564
636
|
const colors = templateColorMap?.get(token.value) || {
|
|
@@ -582,13 +654,49 @@ var TemplateRenderer = ({
|
|
|
582
654
|
);
|
|
583
655
|
}
|
|
584
656
|
if (token.type === "variable") {
|
|
585
|
-
|
|
657
|
+
const details = [
|
|
658
|
+
`Variable: ${token.value}`,
|
|
659
|
+
token.description,
|
|
660
|
+
token.defaultValue !== void 0 ? `Default: ${token.defaultValue || "(empty)"}` : void 0
|
|
661
|
+
].filter(Boolean).join("\n");
|
|
662
|
+
if (token.resolvedValue !== void 0) {
|
|
663
|
+
return /* @__PURE__ */ jsx2(
|
|
664
|
+
"span",
|
|
665
|
+
{
|
|
666
|
+
onClick: () => onVariableClick?.(token.value),
|
|
667
|
+
"data-variable": token.value,
|
|
668
|
+
"data-value-source": token.valueSource,
|
|
669
|
+
className: token.valueSource === "value" ? "inline px-1 mx-0.5 rounded-md bg-emerald-400/15 text-emerald-700 dark:text-emerald-300 border-b border-emerald-400/60 cursor-pointer" : "inline px-1 mx-0.5 rounded-md bg-violet-400/10 text-violet-600 dark:text-violet-300 italic border-b border-dashed border-violet-400/60 cursor-pointer",
|
|
670
|
+
title: details,
|
|
671
|
+
children: token.resolvedValue
|
|
672
|
+
},
|
|
673
|
+
index
|
|
674
|
+
);
|
|
675
|
+
}
|
|
676
|
+
return /* @__PURE__ */ jsxs(
|
|
586
677
|
"span",
|
|
587
678
|
{
|
|
588
679
|
onClick: () => onVariableClick?.(token.value),
|
|
680
|
+
"data-variable": token.value,
|
|
589
681
|
className: "inline-flex items-center px-1.5 py-0.5 mx-0.5 text-xs font-medium rounded-md border border-violet-400/40 bg-violet-400/15 text-violet-600 dark:text-violet-300 hover:brightness-110 cursor-pointer transition-all",
|
|
590
|
-
title:
|
|
591
|
-
children:
|
|
682
|
+
title: details,
|
|
683
|
+
children: [
|
|
684
|
+
`{${token.value}`,
|
|
685
|
+
token.defaultValue !== void 0 && /* @__PURE__ */ jsx2("span", { className: "opacity-60", children: `|${token.defaultValue}` }),
|
|
686
|
+
"}"
|
|
687
|
+
]
|
|
688
|
+
},
|
|
689
|
+
index
|
|
690
|
+
);
|
|
691
|
+
}
|
|
692
|
+
if (token.type === "conditional" && token.conditional) {
|
|
693
|
+
return /* @__PURE__ */ jsx2(
|
|
694
|
+
"span",
|
|
695
|
+
{
|
|
696
|
+
"data-conditional": token.conditional,
|
|
697
|
+
className: "inline-flex items-center px-1 py-0.5 mx-0.5 text-xs font-medium rounded-md border border-amber-400/40 bg-amber-400/15 text-amber-700 dark:text-amber-300",
|
|
698
|
+
title: token.conditional === "end" ? `End of section: ${token.value}` : token.conditional === "if" ? `Shown when "${token.value}" has a value` : `Shown when "${token.value}" is empty`,
|
|
699
|
+
children: `{${CONDITIONAL_PREFIX[token.conditional]}${token.value}}`
|
|
592
700
|
},
|
|
593
701
|
index
|
|
594
702
|
);
|
|
@@ -608,6 +716,143 @@ var TemplateRenderer = ({
|
|
|
608
716
|
}) });
|
|
609
717
|
};
|
|
610
718
|
|
|
719
|
+
// src/components/VariableForm.tsx
|
|
720
|
+
import { useId, useMemo as useMemo4, useState as useState4 } from "react";
|
|
721
|
+
import {
|
|
722
|
+
compactVariableValues,
|
|
723
|
+
getVariableFormFields
|
|
724
|
+
} from "@pixerate/editor";
|
|
725
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
726
|
+
var VariableForm = ({
|
|
727
|
+
content,
|
|
728
|
+
templates,
|
|
729
|
+
bindings,
|
|
730
|
+
values,
|
|
731
|
+
defaultValues,
|
|
732
|
+
onChange,
|
|
733
|
+
className = "flex flex-col gap-3 text-sm"
|
|
734
|
+
}) => {
|
|
735
|
+
const idPrefix = useId();
|
|
736
|
+
const [internal, setInternal] = useState4(
|
|
737
|
+
() => defaultValues ?? {}
|
|
738
|
+
);
|
|
739
|
+
const entered = values ?? internal;
|
|
740
|
+
const fields = useMemo4(
|
|
741
|
+
() => getVariableFormFields(content, { templates, bindings }),
|
|
742
|
+
[content, templates, bindings]
|
|
743
|
+
);
|
|
744
|
+
const update = (name, value) => {
|
|
745
|
+
const next = { ...entered, [name]: value };
|
|
746
|
+
if (values === void 0) setInternal(next);
|
|
747
|
+
onChange?.(compactVariableValues(next), next);
|
|
748
|
+
};
|
|
749
|
+
if (fields.length === 0) return null;
|
|
750
|
+
return /* @__PURE__ */ jsx3("form", { className, onSubmit: (event) => event.preventDefault(), children: fields.map((field) => {
|
|
751
|
+
const id = `${idPrefix}-${field.name}`;
|
|
752
|
+
if (field.conditionOnly) {
|
|
753
|
+
return /* @__PURE__ */ jsxs2(
|
|
754
|
+
"label",
|
|
755
|
+
{
|
|
756
|
+
htmlFor: id,
|
|
757
|
+
className: "flex items-center gap-2",
|
|
758
|
+
"data-variable-field": field.name,
|
|
759
|
+
children: [
|
|
760
|
+
/* @__PURE__ */ jsx3(
|
|
761
|
+
"input",
|
|
762
|
+
{
|
|
763
|
+
id,
|
|
764
|
+
name: field.name,
|
|
765
|
+
type: "checkbox",
|
|
766
|
+
checked: (entered[field.name] ?? "") !== "",
|
|
767
|
+
onChange: (event) => update(field.name, event.target.checked ? "true" : "")
|
|
768
|
+
}
|
|
769
|
+
),
|
|
770
|
+
/* @__PURE__ */ jsx3("span", { children: field.label })
|
|
771
|
+
]
|
|
772
|
+
},
|
|
773
|
+
field.name
|
|
774
|
+
);
|
|
775
|
+
}
|
|
776
|
+
return /* @__PURE__ */ jsxs2(
|
|
777
|
+
"label",
|
|
778
|
+
{
|
|
779
|
+
htmlFor: id,
|
|
780
|
+
className: "flex flex-col gap-1",
|
|
781
|
+
"data-variable-field": field.name,
|
|
782
|
+
children: [
|
|
783
|
+
/* @__PURE__ */ jsxs2("span", { className: "font-medium", children: [
|
|
784
|
+
field.label,
|
|
785
|
+
field.required && /* @__PURE__ */ jsx3("span", { className: "text-rose-500", "aria-hidden": "true", children: " *" })
|
|
786
|
+
] }),
|
|
787
|
+
/* @__PURE__ */ jsx3(
|
|
788
|
+
"input",
|
|
789
|
+
{
|
|
790
|
+
id,
|
|
791
|
+
name: field.name,
|
|
792
|
+
type: "text",
|
|
793
|
+
value: entered[field.name] ?? "",
|
|
794
|
+
placeholder: field.placeholder,
|
|
795
|
+
"aria-required": field.required || void 0,
|
|
796
|
+
onChange: (event) => update(field.name, event.target.value),
|
|
797
|
+
className: "px-2 py-1 rounded-md border border-violet-400/40 bg-transparent"
|
|
798
|
+
}
|
|
799
|
+
)
|
|
800
|
+
]
|
|
801
|
+
},
|
|
802
|
+
field.name
|
|
803
|
+
);
|
|
804
|
+
}) });
|
|
805
|
+
};
|
|
806
|
+
|
|
807
|
+
// src/hooks/useOutline.ts
|
|
808
|
+
import { useMemo as useMemo5, useSyncExternalStore as useSyncExternalStore3 } from "react";
|
|
809
|
+
import { createOutlineStore } from "@pixerate/editor";
|
|
810
|
+
function useOutline(editor) {
|
|
811
|
+
const store = useMemo5(() => createOutlineStore(editor), [editor]);
|
|
812
|
+
return useSyncExternalStore3(store.subscribe, store.getSnapshot, store.getSnapshot);
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
// src/components/OutlinePanel.tsx
|
|
816
|
+
import { navigateToHeading } from "@pixerate/editor";
|
|
817
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
818
|
+
var OutlinePanel = ({
|
|
819
|
+
editor,
|
|
820
|
+
title = "Outline",
|
|
821
|
+
emptyState = "Add headings to see the outline.",
|
|
822
|
+
maxLevel = 6,
|
|
823
|
+
focusOnNavigate = true,
|
|
824
|
+
className = "flex flex-col gap-1 text-sm",
|
|
825
|
+
itemClassName = "w-full truncate rounded px-2 py-1 text-left hover:bg-black/5",
|
|
826
|
+
activeItemClassName = "font-semibold bg-black/5",
|
|
827
|
+
onNavigate
|
|
828
|
+
}) => {
|
|
829
|
+
const { headings, activeId } = useOutline(editor);
|
|
830
|
+
const visible = headings.filter((h) => h.level <= maxLevel);
|
|
831
|
+
return /* @__PURE__ */ jsxs3("nav", { className, "aria-label": "Document outline", "data-outline-panel": "", children: [
|
|
832
|
+
title != null && /* @__PURE__ */ jsx4("div", { className: "pixerate-outline-title", children: title }),
|
|
833
|
+
visible.length === 0 ? /* @__PURE__ */ jsx4("div", { className: "pixerate-outline-empty", children: emptyState }) : /* @__PURE__ */ jsx4("ul", { role: "list", style: { listStyle: "none", margin: 0, padding: 0 }, children: visible.map((heading) => {
|
|
834
|
+
const active = heading.id === activeId;
|
|
835
|
+
return /* @__PURE__ */ jsx4("li", { "data-level": heading.level, children: /* @__PURE__ */ jsx4(
|
|
836
|
+
"button",
|
|
837
|
+
{
|
|
838
|
+
type: "button",
|
|
839
|
+
className: active ? `${itemClassName} ${activeItemClassName}` : itemClassName,
|
|
840
|
+
style: { paddingLeft: `${0.5 + heading.depth * 0.75}rem` },
|
|
841
|
+
"aria-current": active ? "location" : void 0,
|
|
842
|
+
"data-heading-id": heading.id,
|
|
843
|
+
onClick: () => {
|
|
844
|
+
if (!editor) return;
|
|
845
|
+
if (navigateToHeading(editor, heading, { focus: focusOnNavigate })) {
|
|
846
|
+
onNavigate?.(heading);
|
|
847
|
+
}
|
|
848
|
+
},
|
|
849
|
+
children: heading.text || "Untitled"
|
|
850
|
+
}
|
|
851
|
+
) }, heading.id);
|
|
852
|
+
}) })
|
|
853
|
+
] });
|
|
854
|
+
};
|
|
855
|
+
|
|
611
856
|
// src/index.ts
|
|
612
857
|
import {
|
|
613
858
|
DirtyTracker,
|
|
@@ -617,680 +862,392 @@ import {
|
|
|
617
862
|
createHistoryManager as createHistoryManager2
|
|
618
863
|
} from "@pixerate/editor";
|
|
619
864
|
|
|
620
|
-
// src/
|
|
621
|
-
import {
|
|
865
|
+
// src/slots.tsx
|
|
866
|
+
import { createContext, useContext, useMemo as useMemo6 } from "react";
|
|
867
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
868
|
+
var defaultSlots = {
|
|
869
|
+
Button: (props) => /* @__PURE__ */ jsx5(
|
|
870
|
+
"button",
|
|
871
|
+
{
|
|
872
|
+
type: "button",
|
|
873
|
+
className: `pixerate-btn ${props.className || ""}`,
|
|
874
|
+
onClick: props.onClick,
|
|
875
|
+
disabled: props.disabled,
|
|
876
|
+
children: props.children
|
|
877
|
+
}
|
|
878
|
+
),
|
|
879
|
+
Tooltip: (props) => /* @__PURE__ */ jsx5("div", { className: `pixerate-tooltip-container ${props.className || ""}`, title: String(props.content), children: props.children }),
|
|
880
|
+
NodeHeader: (props) => /* @__PURE__ */ jsxs4("div", { className: `pixerate-node-header flex items-center justify-between ${props.className || ""}`, children: [
|
|
881
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2", children: [
|
|
882
|
+
props.icon,
|
|
883
|
+
/* @__PURE__ */ jsx5("span", { className: "font-semibold", children: props.title })
|
|
884
|
+
] }),
|
|
885
|
+
props.onClose && /* @__PURE__ */ jsx5("button", { type: "button", onClick: props.onClose, className: "opacity-70 hover:opacity-100", children: "\xD7" })
|
|
886
|
+
] })
|
|
887
|
+
};
|
|
888
|
+
var EditorSlotsContext = createContext(defaultSlots);
|
|
889
|
+
function EditorSlotsProvider({ slots, children }) {
|
|
890
|
+
const mergedSlots = useMemo6(() => ({ ...defaultSlots, ...slots }), [slots]);
|
|
891
|
+
return /* @__PURE__ */ jsx5(EditorSlotsContext.Provider, { value: mergedSlots, children });
|
|
892
|
+
}
|
|
893
|
+
function useEditorSlots() {
|
|
894
|
+
return useContext(EditorSlotsContext);
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
// src/review/useReview.ts
|
|
898
|
+
import { useCallback as useCallback4, useMemo as useMemo7, useSyncExternalStore as useSyncExternalStore4 } from "react";
|
|
622
899
|
import {
|
|
623
|
-
|
|
900
|
+
getCommentStore,
|
|
901
|
+
getTrackChangesStore
|
|
624
902
|
} from "@pixerate/editor";
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
903
|
+
var EMPTY_COMMENTS = Object.freeze({
|
|
904
|
+
threads: [],
|
|
905
|
+
activeThreadId: null
|
|
906
|
+
});
|
|
907
|
+
var EMPTY_TRACK_CHANGES = Object.freeze({
|
|
908
|
+
enabled: false,
|
|
909
|
+
author: { id: "anonymous", name: "Anonymous" },
|
|
910
|
+
changes: [],
|
|
911
|
+
currentChangeId: null
|
|
912
|
+
});
|
|
913
|
+
var noopUnsubscribe = () => {
|
|
914
|
+
};
|
|
915
|
+
function isCommentStore(value) {
|
|
916
|
+
return !!value && typeof value.getSnapshot === "function" && typeof value.createThread === "function";
|
|
917
|
+
}
|
|
918
|
+
function useComments(source) {
|
|
919
|
+
const store = isCommentStore(source) ? source : getCommentStore(source);
|
|
920
|
+
const subscribe = useCallback4(
|
|
921
|
+
(onChange) => store ? store.subscribe(() => onChange()) : noopUnsubscribe,
|
|
922
|
+
[store]
|
|
645
923
|
);
|
|
646
|
-
const
|
|
647
|
-
const
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
const
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
const
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
setDoc({ ...controller.document });
|
|
676
|
-
}, [controller]);
|
|
677
|
-
const cancelEditing = useCallback4(() => {
|
|
678
|
-
controller.cancelEditing();
|
|
679
|
-
setEditingCell(null);
|
|
680
|
-
setDraftValue("");
|
|
681
|
-
}, [controller]);
|
|
682
|
-
const moveCursor = useCallback4((dir, extend = false) => {
|
|
683
|
-
controller.moveCursor(dir, extend);
|
|
684
|
-
setActiveCell(controller.activeCell);
|
|
685
|
-
setSelectedRange(controller.selectedRange);
|
|
686
|
-
}, [controller]);
|
|
687
|
-
const insertColumn = useCallback4((index, config) => {
|
|
688
|
-
controller.insertColumn(index, config);
|
|
689
|
-
setDoc({ ...controller.document });
|
|
690
|
-
}, [controller]);
|
|
691
|
-
const deleteColumn = useCallback4((colId) => {
|
|
692
|
-
controller.deleteColumn(colId);
|
|
693
|
-
setDoc({ ...controller.document });
|
|
694
|
-
}, [controller]);
|
|
695
|
-
const insertRow = useCallback4((index, config) => {
|
|
696
|
-
controller.insertRow(index, config);
|
|
697
|
-
setDoc({ ...controller.document });
|
|
698
|
-
}, [controller]);
|
|
699
|
-
const deleteRow = useCallback4((rowId) => {
|
|
700
|
-
controller.deleteRow(rowId);
|
|
701
|
-
setDoc({ ...controller.document });
|
|
702
|
-
}, [controller]);
|
|
703
|
-
const setColumnWidth = useCallback4((colId, width) => {
|
|
704
|
-
controller.setColumnWidth(colId, width);
|
|
705
|
-
setDoc({ ...controller.document });
|
|
706
|
-
}, [controller]);
|
|
707
|
-
const autoFitColumnWidth = useCallback4((colId, customWidth) => {
|
|
708
|
-
controller.autoFitColumnWidth(colId, customWidth);
|
|
709
|
-
setDoc({ ...controller.document });
|
|
710
|
-
}, [controller]);
|
|
711
|
-
const registerDataSource = useCallback4((ds) => {
|
|
712
|
-
controller.registerDataSource(ds);
|
|
713
|
-
setDoc({ ...controller.document });
|
|
714
|
-
}, [controller]);
|
|
715
|
-
const setPrimaryDataSource = useCallback4((id) => {
|
|
716
|
-
controller.setPrimaryDataSource(id);
|
|
717
|
-
setDoc({ ...controller.document });
|
|
718
|
-
}, [controller]);
|
|
719
|
-
const recalculateAll = useCallback4(() => {
|
|
720
|
-
controller.recalculateAll();
|
|
721
|
-
setDoc({ ...controller.document });
|
|
722
|
-
}, [controller]);
|
|
723
|
-
const undo = useCallback4(() => {
|
|
724
|
-
controller.undo();
|
|
725
|
-
setDoc({ ...controller.document });
|
|
726
|
-
}, [controller]);
|
|
727
|
-
const redo = useCallback4(() => {
|
|
728
|
-
controller.redo();
|
|
729
|
-
setDoc({ ...controller.document });
|
|
730
|
-
}, [controller]);
|
|
731
|
-
return {
|
|
732
|
-
document: doc,
|
|
733
|
-
activeCell,
|
|
734
|
-
selectedRange,
|
|
735
|
-
editingCell,
|
|
736
|
-
draftValue,
|
|
737
|
-
setDraftValue,
|
|
738
|
-
controller,
|
|
739
|
-
getCell: (rowId, colId) => controller.getCell(rowId, colId),
|
|
740
|
-
setCellValue,
|
|
741
|
-
selectCell,
|
|
742
|
-
selectRange,
|
|
743
|
-
startEditing,
|
|
744
|
-
commitEditing,
|
|
745
|
-
cancelEditing,
|
|
746
|
-
moveCursor,
|
|
747
|
-
insertColumn,
|
|
748
|
-
deleteColumn,
|
|
749
|
-
insertRow,
|
|
750
|
-
deleteRow,
|
|
751
|
-
setColumnWidth,
|
|
752
|
-
autoFitColumnWidth,
|
|
753
|
-
loadDocument: (document2) => {
|
|
754
|
-
controller.loadDocument(document2);
|
|
755
|
-
setDoc({ ...controller.document });
|
|
756
|
-
setActiveCell(null);
|
|
757
|
-
setSelectedRange(null);
|
|
758
|
-
setEditingCell(null);
|
|
759
|
-
setDraftValue("");
|
|
760
|
-
},
|
|
761
|
-
syncWithDataSource: () => {
|
|
762
|
-
controller.syncWithDataSource();
|
|
763
|
-
controller.recalculateAll();
|
|
764
|
-
setDoc({ ...controller.document });
|
|
765
|
-
},
|
|
766
|
-
registerDataSource,
|
|
767
|
-
setPrimaryDataSource,
|
|
768
|
-
recalculateAll,
|
|
769
|
-
exportToTsv: (range) => controller.exportToTsv(range),
|
|
770
|
-
importFromTsv: (data) => {
|
|
771
|
-
controller.importFromTsv(data);
|
|
772
|
-
setDoc({ ...controller.document });
|
|
773
|
-
},
|
|
774
|
-
undo,
|
|
775
|
-
redo
|
|
776
|
-
};
|
|
924
|
+
const getSnapshot = () => store?.getSnapshot() ?? EMPTY_COMMENTS;
|
|
925
|
+
const snapshot = useSyncExternalStore4(subscribe, getSnapshot, getSnapshot);
|
|
926
|
+
return useMemo7(() => ({ ...snapshot, store }), [snapshot, store]);
|
|
927
|
+
}
|
|
928
|
+
function useTrackChanges(editor) {
|
|
929
|
+
const store = getTrackChangesStore(editor ?? null);
|
|
930
|
+
const subscribe = useCallback4(
|
|
931
|
+
(onChange) => store ? store.subscribe(() => onChange()) : noopUnsubscribe,
|
|
932
|
+
[store]
|
|
933
|
+
);
|
|
934
|
+
const getSnapshot = () => store?.getSnapshot() ?? EMPTY_TRACK_CHANGES;
|
|
935
|
+
const snapshot = useSyncExternalStore4(subscribe, getSnapshot, getSnapshot);
|
|
936
|
+
return useMemo7(() => {
|
|
937
|
+
const run = (fn) => () => {
|
|
938
|
+
if (editor && !editor.isDestroyed) fn(editor);
|
|
939
|
+
};
|
|
940
|
+
return {
|
|
941
|
+
...snapshot,
|
|
942
|
+
currentChange: snapshot.changes.find((c) => c.id === snapshot.currentChangeId) ?? null,
|
|
943
|
+
setEnabled: (enabled) => run((e) => e.commands.setTrackChanges(enabled))(),
|
|
944
|
+
toggle: run((e) => e.commands.toggleTrackChanges()),
|
|
945
|
+
accept: (id) => run((e) => e.commands.acceptChange(id))(),
|
|
946
|
+
reject: (id) => run((e) => e.commands.rejectChange(id))(),
|
|
947
|
+
acceptAll: run((e) => e.commands.acceptAllChanges()),
|
|
948
|
+
rejectAll: run((e) => e.commands.rejectAllChanges()),
|
|
949
|
+
next: run((e) => e.chain().focus().selectNextChange().run()),
|
|
950
|
+
previous: run((e) => e.chain().focus().selectPreviousChange().run())
|
|
951
|
+
};
|
|
952
|
+
}, [snapshot, editor]);
|
|
777
953
|
}
|
|
778
954
|
|
|
779
|
-
// src/
|
|
780
|
-
import {
|
|
955
|
+
// src/review/CommentsPanel.tsx
|
|
956
|
+
import { useState as useState5 } from "react";
|
|
781
957
|
import {
|
|
782
|
-
|
|
958
|
+
formatReviewTime,
|
|
959
|
+
getCommentAuthor
|
|
783
960
|
} from "@pixerate/editor";
|
|
784
|
-
import { jsx as
|
|
785
|
-
var
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
961
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
962
|
+
var buttonClass = "rounded px-2 py-1 text-xs text-muted-foreground hover:bg-muted hover:text-foreground disabled:opacity-50";
|
|
963
|
+
var primaryButtonClass = "rounded px-2 py-1 text-xs bg-primary/10 text-primary hover:bg-primary/20 disabled:opacity-50";
|
|
964
|
+
var textareaClass = "w-full resize-y rounded-md border border-input bg-background p-2 text-sm text-foreground focus:outline-none focus:ring-2 focus:ring-primary";
|
|
965
|
+
var CommentsPanel = ({
|
|
966
|
+
editor,
|
|
967
|
+
store: storeProp,
|
|
968
|
+
author: authorProp,
|
|
969
|
+
showResolved: showResolvedInitial = false,
|
|
970
|
+
className = "flex flex-col gap-2 text-sm text-foreground",
|
|
971
|
+
formatTime = (t) => formatReviewTime(t),
|
|
972
|
+
emptyMessage = "No comments yet. Select text and add a comment."
|
|
792
973
|
}) => {
|
|
793
|
-
const
|
|
794
|
-
const
|
|
795
|
-
const
|
|
796
|
-
const
|
|
797
|
-
const
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
const activeColumn = state.activeCell ? state.document.columns[state.activeCell.col] : void 0;
|
|
814
|
-
const formulaBarReadOnly = readOnly || !state.activeCell || !!activeColumn?.readOnly;
|
|
815
|
-
useEffect5(() => {
|
|
816
|
-
setFormulaDraft(null);
|
|
817
|
-
}, [state.activeCell?.row, state.activeCell?.col]);
|
|
818
|
-
const commitFormulaBar = () => {
|
|
819
|
-
if (state.editingCell) {
|
|
820
|
-
state.commitEditing();
|
|
821
|
-
return;
|
|
822
|
-
}
|
|
823
|
-
if (formulaDraft === null || !state.activeCell) return;
|
|
824
|
-
const row = state.document.rows[state.activeCell.row];
|
|
825
|
-
const col = state.document.columns[state.activeCell.col];
|
|
826
|
-
if (row && col && !formulaBarReadOnly && formulaDraft !== activeRawValue) {
|
|
827
|
-
state.setCellValue(row.id, col.id, formulaDraft);
|
|
828
|
-
}
|
|
829
|
-
setFormulaDraft(null);
|
|
830
|
-
};
|
|
831
|
-
const handleCellClick = useCallback5((rIdx, cIdx, e) => {
|
|
832
|
-
if (state.editingCell && (state.editingCell.row !== rIdx || state.editingCell.col !== cIdx)) {
|
|
833
|
-
state.commitEditing();
|
|
834
|
-
}
|
|
835
|
-
state.selectCell(rIdx, cIdx, e.shiftKey);
|
|
836
|
-
}, [state]);
|
|
837
|
-
const handleCellDblClick = useCallback5((rIdx, cIdx) => {
|
|
838
|
-
if (readOnly) return;
|
|
839
|
-
const col = state.document.columns[cIdx];
|
|
840
|
-
if (col?.readOnly) return;
|
|
841
|
-
state.startEditing(rIdx, cIdx);
|
|
842
|
-
}, [readOnly, state]);
|
|
843
|
-
const handleKeyDown = useCallback5((e) => {
|
|
844
|
-
if (state.editingCell) {
|
|
845
|
-
if (e.key === "Enter") {
|
|
846
|
-
e.preventDefault();
|
|
847
|
-
state.commitEditing();
|
|
848
|
-
state.moveCursor("down");
|
|
849
|
-
} else if (e.key === "Escape") {
|
|
850
|
-
e.preventDefault();
|
|
851
|
-
state.cancelEditing();
|
|
852
|
-
} else if (e.key === "Tab") {
|
|
853
|
-
e.preventDefault();
|
|
854
|
-
state.commitEditing();
|
|
855
|
-
state.moveCursor(e.shiftKey ? "left" : "right");
|
|
856
|
-
}
|
|
857
|
-
return;
|
|
858
|
-
}
|
|
859
|
-
if (!state.activeCell) return;
|
|
860
|
-
if (e.key === "ArrowUp") {
|
|
861
|
-
e.preventDefault();
|
|
862
|
-
state.moveCursor("up", e.shiftKey);
|
|
863
|
-
} else if (e.key === "ArrowDown") {
|
|
864
|
-
e.preventDefault();
|
|
865
|
-
state.moveCursor("down", e.shiftKey);
|
|
866
|
-
} else if (e.key === "ArrowLeft") {
|
|
867
|
-
e.preventDefault();
|
|
868
|
-
state.moveCursor("left", e.shiftKey);
|
|
869
|
-
} else if (e.key === "ArrowRight") {
|
|
870
|
-
e.preventDefault();
|
|
871
|
-
state.moveCursor("right", e.shiftKey);
|
|
872
|
-
} else if (e.key === "Tab") {
|
|
873
|
-
e.preventDefault();
|
|
874
|
-
state.moveCursor(e.shiftKey ? "left" : "right");
|
|
875
|
-
} else if (e.key === "Enter") {
|
|
876
|
-
e.preventDefault();
|
|
877
|
-
const col = state.document.columns[state.activeCell.col];
|
|
878
|
-
if (!readOnly && !col?.readOnly) {
|
|
879
|
-
state.startEditing();
|
|
880
|
-
}
|
|
881
|
-
} else if (e.key === "Backspace" || e.key === "Delete") {
|
|
882
|
-
if (readOnly) return;
|
|
883
|
-
const row = state.document.rows[state.activeCell.row];
|
|
884
|
-
const col = state.document.columns[state.activeCell.col];
|
|
885
|
-
if (row && col && !col.readOnly) {
|
|
886
|
-
e.preventDefault();
|
|
887
|
-
state.setCellValue(row.id, col.id, "");
|
|
888
|
-
}
|
|
889
|
-
} else if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "z") {
|
|
890
|
-
e.preventDefault();
|
|
891
|
-
if (e.shiftKey) {
|
|
892
|
-
state.redo();
|
|
893
|
-
} else {
|
|
894
|
-
state.undo();
|
|
895
|
-
}
|
|
896
|
-
} else if (e.ctrlKey && !e.metaKey && e.key.toLowerCase() === "y") {
|
|
897
|
-
e.preventDefault();
|
|
898
|
-
state.redo();
|
|
899
|
-
} else if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "c") {
|
|
900
|
-
e.preventDefault();
|
|
901
|
-
const tsv = state.exportToTsv(state.selectedRange);
|
|
902
|
-
navigator.clipboard?.writeText(tsv);
|
|
903
|
-
} else if (!readOnly && e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey) {
|
|
904
|
-
const col = state.document.columns[state.activeCell.col];
|
|
905
|
-
if (!col?.readOnly) {
|
|
906
|
-
state.startEditing(state.activeCell.row, state.activeCell.col, e.key);
|
|
907
|
-
}
|
|
908
|
-
}
|
|
909
|
-
}, [readOnly, state]);
|
|
910
|
-
const stateRef = useRef7(state);
|
|
911
|
-
stateRef.current = state;
|
|
912
|
-
const onColumnResizeRef = useRef7(onColumnResize);
|
|
913
|
-
onColumnResizeRef.current = onColumnResize;
|
|
914
|
-
useEffect5(() => {
|
|
915
|
-
if (!resizingColId) return;
|
|
916
|
-
if (typeof document !== "undefined") {
|
|
917
|
-
document.body.style.cursor = "col-resize";
|
|
918
|
-
document.body.style.userSelect = "none";
|
|
919
|
-
}
|
|
920
|
-
let rafId = null;
|
|
921
|
-
let pendingWidth = resizeStartWidth;
|
|
922
|
-
let hasDragged = false;
|
|
923
|
-
const handleMouseMove = (e) => {
|
|
924
|
-
const delta = e.clientX - resizeStartX;
|
|
925
|
-
if (Math.abs(delta) > 2) {
|
|
926
|
-
hasDragged = true;
|
|
927
|
-
}
|
|
928
|
-
pendingWidth = Math.max(30, resizeStartWidth + delta);
|
|
929
|
-
if (rafId === null) {
|
|
930
|
-
rafId = requestAnimationFrame(() => {
|
|
931
|
-
rafId = null;
|
|
932
|
-
stateRef.current.setColumnWidth(resizingColId, pendingWidth);
|
|
933
|
-
});
|
|
934
|
-
}
|
|
935
|
-
};
|
|
936
|
-
const handleMouseUp = () => {
|
|
937
|
-
if (rafId !== null) {
|
|
938
|
-
cancelAnimationFrame(rafId);
|
|
939
|
-
rafId = null;
|
|
940
|
-
}
|
|
941
|
-
if (hasDragged) {
|
|
942
|
-
stateRef.current.setColumnWidth(resizingColId, pendingWidth);
|
|
943
|
-
onColumnResizeRef.current?.(resizingColId, pendingWidth);
|
|
944
|
-
}
|
|
945
|
-
setResizingColId(null);
|
|
946
|
-
if (typeof document !== "undefined") {
|
|
947
|
-
document.body.style.cursor = "";
|
|
948
|
-
document.body.style.userSelect = "";
|
|
949
|
-
}
|
|
950
|
-
};
|
|
951
|
-
window.addEventListener("mousemove", handleMouseMove);
|
|
952
|
-
window.addEventListener("mouseup", handleMouseUp);
|
|
953
|
-
return () => {
|
|
954
|
-
if (rafId !== null) {
|
|
955
|
-
cancelAnimationFrame(rafId);
|
|
956
|
-
}
|
|
957
|
-
if (typeof document !== "undefined") {
|
|
958
|
-
document.body.style.cursor = "";
|
|
959
|
-
document.body.style.userSelect = "";
|
|
960
|
-
}
|
|
961
|
-
window.removeEventListener("mousemove", handleMouseMove);
|
|
962
|
-
window.removeEventListener("mouseup", handleMouseUp);
|
|
963
|
-
};
|
|
964
|
-
}, [resizingColId, resizeStartX, resizeStartWidth]);
|
|
965
|
-
const measureElementContentWidth = useCallback5((el, container) => {
|
|
966
|
-
if (typeof document === "undefined") return 0;
|
|
967
|
-
let maxW = el.scrollWidth || 0;
|
|
968
|
-
const firstChild = el.firstElementChild;
|
|
969
|
-
if (firstChild && firstChild.scrollWidth > maxW) {
|
|
970
|
-
maxW = firstChild.scrollWidth;
|
|
971
|
-
}
|
|
972
|
-
const truncated = el.querySelectorAll(".truncate, [title], span, div");
|
|
973
|
-
truncated.forEach((node) => {
|
|
974
|
-
if (node.scrollWidth > maxW) {
|
|
975
|
-
maxW = node.scrollWidth;
|
|
976
|
-
}
|
|
977
|
-
});
|
|
978
|
-
try {
|
|
979
|
-
const clone = firstChild ? firstChild.cloneNode(true) : el.cloneNode(true);
|
|
980
|
-
clone.style.cssText = `
|
|
981
|
-
position: absolute !important;
|
|
982
|
-
visibility: hidden !important;
|
|
983
|
-
width: max-content !important;
|
|
984
|
-
min-width: max-content !important;
|
|
985
|
-
max-width: none !important;
|
|
986
|
-
overflow: visible !important;
|
|
987
|
-
white-space: nowrap !important;
|
|
988
|
-
pointer-events: none !important;
|
|
989
|
-
top: -9999px !important;
|
|
990
|
-
left: -9999px !important;
|
|
991
|
-
`;
|
|
992
|
-
const allNodes = clone.querySelectorAll("*");
|
|
993
|
-
allNodes.forEach((node) => {
|
|
994
|
-
node.style.maxWidth = "none";
|
|
995
|
-
node.style.overflow = "visible";
|
|
996
|
-
node.style.textOverflow = "clip";
|
|
997
|
-
node.style.whiteSpace = "nowrap";
|
|
998
|
-
if (node.classList.contains("truncate") || node.classList.contains("min-w-0") || node.classList.contains("w-full") || node.classList.contains("max-w-0") || node.classList.contains("flex-1")) {
|
|
999
|
-
node.style.width = "max-content";
|
|
1000
|
-
node.style.minWidth = "max-content";
|
|
1001
|
-
}
|
|
1002
|
-
});
|
|
1003
|
-
container.appendChild(clone);
|
|
1004
|
-
const rect = clone.getBoundingClientRect();
|
|
1005
|
-
container.removeChild(clone);
|
|
1006
|
-
if (rect.width > maxW) {
|
|
1007
|
-
maxW = rect.width;
|
|
1008
|
-
}
|
|
1009
|
-
} catch {
|
|
1010
|
-
}
|
|
1011
|
-
return maxW;
|
|
1012
|
-
}, []);
|
|
1013
|
-
const autoFitColumn = useCallback5((colId, colIndex) => {
|
|
1014
|
-
const col = state.document.columns.find((c) => c.id === colId);
|
|
1015
|
-
if (!col) return;
|
|
1016
|
-
let calculatedWidth = 0;
|
|
1017
|
-
if (gridRef.current && typeof document !== "undefined") {
|
|
1018
|
-
const table = gridRef.current.querySelector("table");
|
|
1019
|
-
if (table) {
|
|
1020
|
-
const thElements = table.querySelectorAll("thead th");
|
|
1021
|
-
const th = thElements[colIndex + 1];
|
|
1022
|
-
if (th) {
|
|
1023
|
-
const headerInner = th.firstElementChild || th;
|
|
1024
|
-
const headerW = measureElementContentWidth(headerInner, gridRef.current);
|
|
1025
|
-
calculatedWidth = Math.max(calculatedWidth, headerW + 28);
|
|
1026
|
-
}
|
|
1027
|
-
const rows = table.querySelectorAll("tbody tr");
|
|
1028
|
-
const sampleLimit = Math.min(rows.length, 150);
|
|
1029
|
-
for (let r = 0; r < sampleLimit; r++) {
|
|
1030
|
-
const tr = rows[r];
|
|
1031
|
-
const td = tr.children[colIndex + 1];
|
|
1032
|
-
if (td) {
|
|
1033
|
-
const cellW = measureElementContentWidth(td, gridRef.current);
|
|
1034
|
-
calculatedWidth = Math.max(calculatedWidth, cellW + 20);
|
|
1035
|
-
}
|
|
974
|
+
const { threads, activeThreadId, store } = useComments(storeProp ?? editor);
|
|
975
|
+
const [showResolved, setShowResolved] = useState5(showResolvedInitial);
|
|
976
|
+
const author = authorProp ?? getCommentAuthor(editor) ?? { id: "anonymous", name: "Anonymous" };
|
|
977
|
+
const visible = threads.filter((t) => showResolved || !t.resolved);
|
|
978
|
+
const resolvedCount = threads.filter((t) => t.resolved).length;
|
|
979
|
+
return /* @__PURE__ */ jsxs5("aside", { className, "aria-label": "Comments", children: [
|
|
980
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between gap-2", children: [
|
|
981
|
+
/* @__PURE__ */ jsxs5("span", { className: "text-xs font-medium text-muted-foreground", children: [
|
|
982
|
+
threads.length - resolvedCount,
|
|
983
|
+
" open",
|
|
984
|
+
resolvedCount > 0 ? ` \xB7 ${resolvedCount} resolved` : ""
|
|
985
|
+
] }),
|
|
986
|
+
resolvedCount > 0 && /* @__PURE__ */ jsx6(
|
|
987
|
+
"button",
|
|
988
|
+
{
|
|
989
|
+
type: "button",
|
|
990
|
+
className: buttonClass,
|
|
991
|
+
"aria-pressed": showResolved,
|
|
992
|
+
onClick: () => setShowResolved((v) => !v),
|
|
993
|
+
children: showResolved ? "Hide resolved" : "Show resolved"
|
|
1036
994
|
}
|
|
1037
|
-
|
|
1038
|
-
}
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
995
|
+
)
|
|
996
|
+
] }),
|
|
997
|
+
visible.length === 0 ? /* @__PURE__ */ jsx6("p", { className: "text-xs text-muted-foreground", children: emptyMessage }) : /* @__PURE__ */ jsx6("ul", { className: "flex flex-col gap-2", role: "list", children: visible.map((thread) => /* @__PURE__ */ jsx6(
|
|
998
|
+
CommentThreadCard,
|
|
999
|
+
{
|
|
1000
|
+
thread,
|
|
1001
|
+
active: thread.id === activeThreadId,
|
|
1002
|
+
editor,
|
|
1003
|
+
store,
|
|
1004
|
+
author,
|
|
1005
|
+
formatTime
|
|
1006
|
+
},
|
|
1007
|
+
thread.id
|
|
1008
|
+
)) })
|
|
1009
|
+
] });
|
|
1010
|
+
};
|
|
1011
|
+
var CommentThreadCard = ({
|
|
1012
|
+
thread,
|
|
1013
|
+
active,
|
|
1014
|
+
editor,
|
|
1015
|
+
store,
|
|
1016
|
+
author,
|
|
1017
|
+
formatTime
|
|
1018
|
+
}) => {
|
|
1019
|
+
const [draft, setDraft] = useState5("");
|
|
1020
|
+
const isDraft = thread.body === "";
|
|
1021
|
+
const quote = thread.anchor?.quote ?? thread.lastQuote ?? "";
|
|
1022
|
+
const live = editor && !editor.isDestroyed ? editor : null;
|
|
1023
|
+
const focus = () => {
|
|
1024
|
+
if (!active) {
|
|
1025
|
+
if (live && !thread.orphaned) live.commands.focusComment(thread.id);
|
|
1026
|
+
else store?.setActiveThread(thread.id);
|
|
1064
1027
|
}
|
|
1065
|
-
}, [autoFitColumn]);
|
|
1066
|
-
const isCellSelected = (rIdx, cIdx) => {
|
|
1067
|
-
if (!state.selectedRange) return false;
|
|
1068
|
-
const minR = Math.min(state.selectedRange.startRow, state.selectedRange.endRow);
|
|
1069
|
-
const maxR = Math.max(state.selectedRange.startRow, state.selectedRange.endRow);
|
|
1070
|
-
const minC = Math.min(state.selectedRange.startCol, state.selectedRange.endCol);
|
|
1071
|
-
const maxC = Math.max(state.selectedRange.startCol, state.selectedRange.endCol);
|
|
1072
|
-
return rIdx >= minR && rIdx <= maxR && cIdx >= minC && cIdx <= maxC;
|
|
1073
1028
|
};
|
|
1074
|
-
const
|
|
1075
|
-
|
|
1029
|
+
const remove = () => {
|
|
1030
|
+
if (live) live.commands.deleteComment(thread.id);
|
|
1031
|
+
else store?.deleteThread(thread.id);
|
|
1032
|
+
};
|
|
1033
|
+
const setResolved = (resolved) => {
|
|
1034
|
+
if (live) live.commands.resolveComment(thread.id, resolved);
|
|
1035
|
+
else store?.resolveThread(thread.id, resolved, author);
|
|
1036
|
+
};
|
|
1037
|
+
const submit = () => {
|
|
1038
|
+
const body = draft.trim();
|
|
1039
|
+
if (!body || !store) return;
|
|
1040
|
+
if (isDraft) store.editComment(thread.id, body);
|
|
1041
|
+
else store.addReply(thread.id, { body, author });
|
|
1042
|
+
setDraft("");
|
|
1076
1043
|
};
|
|
1077
|
-
|
|
1078
|
-
|
|
1044
|
+
const stop = (e) => e.stopPropagation();
|
|
1045
|
+
return /* @__PURE__ */ jsxs5(
|
|
1046
|
+
"li",
|
|
1079
1047
|
{
|
|
1080
|
-
|
|
1081
|
-
|
|
1048
|
+
className: `flex flex-col gap-2 rounded-md border bg-background p-3 cursor-pointer ${active ? "border-primary ring-1 ring-primary" : "border-border"} ${thread.resolved ? "opacity-70" : ""}`,
|
|
1049
|
+
"data-thread-id": thread.id,
|
|
1050
|
+
"data-active": active || void 0,
|
|
1051
|
+
"aria-current": active || void 0,
|
|
1082
1052
|
tabIndex: 0,
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1053
|
+
onClick: focus,
|
|
1054
|
+
onKeyDown: (e) => {
|
|
1055
|
+
if (e.target === e.currentTarget && (e.key === "Enter" || e.key === " ")) {
|
|
1056
|
+
e.preventDefault();
|
|
1057
|
+
focus();
|
|
1058
|
+
}
|
|
1059
|
+
},
|
|
1086
1060
|
children: [
|
|
1087
|
-
/* @__PURE__ */
|
|
1088
|
-
/* @__PURE__ */
|
|
1089
|
-
/* @__PURE__ */
|
|
1090
|
-
|
|
1091
|
-
|
|
1061
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex items-baseline justify-between gap-2", children: [
|
|
1062
|
+
/* @__PURE__ */ jsx6("span", { className: "font-medium", children: thread.author.name }),
|
|
1063
|
+
/* @__PURE__ */ jsx6("span", { className: "text-xs text-muted-foreground", children: formatTime(thread.createdAt) })
|
|
1064
|
+
] }),
|
|
1065
|
+
quote && /* @__PURE__ */ jsx6("blockquote", { className: "border-l-2 border-border pl-2 text-xs text-muted-foreground line-clamp-2", children: quote }),
|
|
1066
|
+
thread.orphaned && /* @__PURE__ */ jsx6("span", { className: "text-xs text-destructive", children: "The commented text was deleted." }),
|
|
1067
|
+
thread.resolved && /* @__PURE__ */ jsx6("span", { className: "text-xs text-muted-foreground", children: "Resolved" }),
|
|
1068
|
+
!isDraft && /* @__PURE__ */ jsx6("p", { className: "whitespace-pre-wrap break-words", children: thread.body }),
|
|
1069
|
+
thread.replies.length > 0 && /* @__PURE__ */ jsx6("ul", { className: "flex flex-col gap-2 border-l border-border pl-3", role: "list", children: thread.replies.map((reply) => /* @__PURE__ */ jsxs5("li", { className: "flex flex-col gap-0.5", "data-reply-id": reply.id, children: [
|
|
1070
|
+
/* @__PURE__ */ jsxs5("span", { className: "text-xs", children: [
|
|
1071
|
+
/* @__PURE__ */ jsx6("span", { className: "font-medium", children: reply.author.name }),
|
|
1072
|
+
" ",
|
|
1073
|
+
/* @__PURE__ */ jsx6("span", { className: "text-muted-foreground", children: formatTime(reply.createdAt) })
|
|
1074
|
+
] }),
|
|
1075
|
+
/* @__PURE__ */ jsx6("p", { className: "whitespace-pre-wrap break-words", children: reply.body })
|
|
1076
|
+
] }, reply.id)) }),
|
|
1077
|
+
(active || isDraft) && !thread.resolved && /* @__PURE__ */ jsxs5("div", { className: "flex flex-col gap-1", onClick: stop, children: [
|
|
1078
|
+
/* @__PURE__ */ jsx6(
|
|
1079
|
+
"textarea",
|
|
1092
1080
|
{
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
"aria-label": "
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
if (!state.editingCell) setFormulaDraft(activeRawValue);
|
|
1101
|
-
},
|
|
1102
|
-
onChange: (e) => {
|
|
1103
|
-
if (state.editingCell) {
|
|
1104
|
-
state.setDraftValue(e.target.value);
|
|
1105
|
-
} else if (state.activeCell) {
|
|
1106
|
-
setFormulaDraft(e.target.value);
|
|
1107
|
-
}
|
|
1108
|
-
},
|
|
1109
|
-
onBlur: () => commitFormulaBar(),
|
|
1081
|
+
className: textareaClass,
|
|
1082
|
+
rows: 2,
|
|
1083
|
+
value: draft,
|
|
1084
|
+
"aria-label": isDraft ? "Comment" : "Reply",
|
|
1085
|
+
placeholder: isDraft ? "Add a comment\u2026" : "Reply\u2026",
|
|
1086
|
+
autoFocus: isDraft,
|
|
1087
|
+
onChange: (e) => setDraft(e.target.value),
|
|
1110
1088
|
onKeyDown: (e) => {
|
|
1111
|
-
e.
|
|
1112
|
-
if (e.key === "Enter") {
|
|
1113
|
-
e.preventDefault();
|
|
1114
|
-
commitFormulaBar();
|
|
1115
|
-
} else if (e.key === "Escape") {
|
|
1089
|
+
if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
|
|
1116
1090
|
e.preventDefault();
|
|
1117
|
-
|
|
1118
|
-
if (state.editingCell) state.cancelEditing();
|
|
1091
|
+
submit();
|
|
1119
1092
|
}
|
|
1120
1093
|
}
|
|
1121
1094
|
}
|
|
1122
|
-
)
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
state.document.columns.map((col, cIdx) => /* @__PURE__ */ jsxs(
|
|
1128
|
-
"th",
|
|
1129
|
-
{
|
|
1130
|
-
className: `relative border-r border-border px-2 text-left font-medium text-muted-foreground hover:bg-muted/90 transition-colors group overflow-hidden max-w-0 ${onColumnHeaderClick ? "cursor-pointer" : "cursor-default"}`,
|
|
1131
|
-
style: { width: col.width || 130, minWidth: col.width || 130, maxWidth: col.width || 130, overflow: "hidden" },
|
|
1132
|
-
onClick: () => onColumnHeaderClick?.(col),
|
|
1133
|
-
onDoubleClick: (e) => handleHeaderDblClick(col.id, cIdx, e),
|
|
1134
|
-
children: [
|
|
1135
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-1 min-w-0 overflow-hidden truncate", children: [
|
|
1136
|
-
/* @__PURE__ */ jsx3("span", { className: "truncate font-semibold text-foreground text-xs min-w-0", children: col.title }),
|
|
1137
|
-
/* @__PURE__ */ jsxs("span", { className: "text-[10px] text-muted-foreground/70 font-mono font-normal shrink-0", children: [
|
|
1138
|
-
"(",
|
|
1139
|
-
col.key,
|
|
1140
|
-
")"
|
|
1141
|
-
] })
|
|
1142
|
-
] }),
|
|
1143
|
-
/* @__PURE__ */ jsx3(
|
|
1144
|
-
"div",
|
|
1145
|
-
{
|
|
1146
|
-
className: "col-resize-handle",
|
|
1147
|
-
style: { position: "absolute", top: 0, bottom: 0, width: 12, right: -6, cursor: "col-resize", zIndex: 20, display: "flex", justifyContent: "center", touchAction: "none" },
|
|
1148
|
-
onMouseEnter: () => setHoveredColId(col.id),
|
|
1149
|
-
onMouseLeave: () => setHoveredColId((cur) => cur === col.id ? null : cur),
|
|
1150
|
-
onMouseDown: (e) => {
|
|
1151
|
-
e.preventDefault();
|
|
1152
|
-
e.stopPropagation();
|
|
1153
|
-
setResizingColId(col.id);
|
|
1154
|
-
setResizeStartX(e.clientX);
|
|
1155
|
-
setResizeStartWidth(col.width || 130);
|
|
1156
|
-
},
|
|
1157
|
-
onDoubleClick: (e) => handleResizeDblClick(col.id, cIdx, e),
|
|
1158
|
-
role: "separator",
|
|
1159
|
-
"aria-orientation": "vertical",
|
|
1160
|
-
children: /* @__PURE__ */ jsx3(
|
|
1161
|
-
"div",
|
|
1162
|
-
{
|
|
1163
|
-
className: "col-resize-handle-line",
|
|
1164
|
-
style: {
|
|
1165
|
-
width: 2,
|
|
1166
|
-
height: "100%",
|
|
1167
|
-
pointerEvents: "none",
|
|
1168
|
-
transition: "background-color 150ms ease",
|
|
1169
|
-
backgroundColor: resizingColId === col.id ? "var(--primary, #6366f1)" : hoveredColId === col.id ? "color-mix(in srgb, var(--primary, #6366f1) 75%, transparent)" : "transparent"
|
|
1170
|
-
}
|
|
1171
|
-
}
|
|
1172
|
-
)
|
|
1173
|
-
}
|
|
1174
|
-
)
|
|
1175
|
-
]
|
|
1176
|
-
},
|
|
1177
|
-
col.id
|
|
1178
|
-
)),
|
|
1179
|
-
onAddColumnClick && /* @__PURE__ */ jsx3(
|
|
1180
|
-
"th",
|
|
1095
|
+
),
|
|
1096
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex justify-end gap-1", children: [
|
|
1097
|
+
isDraft && /* @__PURE__ */ jsx6("button", { type: "button", className: buttonClass, onClick: remove, children: "Cancel" }),
|
|
1098
|
+
/* @__PURE__ */ jsx6(
|
|
1099
|
+
"button",
|
|
1181
1100
|
{
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1101
|
+
type: "button",
|
|
1102
|
+
className: primaryButtonClass,
|
|
1103
|
+
disabled: !draft.trim(),
|
|
1104
|
+
onClick: submit,
|
|
1105
|
+
children: isDraft ? "Comment" : "Reply"
|
|
1186
1106
|
}
|
|
1187
1107
|
)
|
|
1188
|
-
] })
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
onDoubleClick: () => handleCellDblClick(rIdx, cIdx),
|
|
1203
|
-
children: isEditing ? /* @__PURE__ */ jsx3(
|
|
1204
|
-
"input",
|
|
1205
|
-
{
|
|
1206
|
-
type: "text",
|
|
1207
|
-
className: "absolute inset-0 w-full h-full px-2 py-1 bg-background text-foreground outline-none font-sans text-xs border-2 border-primary z-20",
|
|
1208
|
-
value: state.draftValue,
|
|
1209
|
-
onChange: (e) => state.setDraftValue(e.target.value),
|
|
1210
|
-
onBlur: () => state.commitEditing(),
|
|
1211
|
-
autoFocus: true
|
|
1212
|
-
}
|
|
1213
|
-
) : customCellRenderer ? customCellRenderer({ row, col, cell }) : /* @__PURE__ */ jsx3("span", { className: `truncate block max-w-full ${cell.error ? "text-destructive font-semibold" : ""}`, children: cell.error || (cell.value ?? "") })
|
|
1214
|
-
},
|
|
1215
|
-
col.id
|
|
1216
|
-
);
|
|
1217
|
-
}),
|
|
1218
|
-
onAddColumnClick && /* @__PURE__ */ jsx3("td", { className: "w-10 min-w-[2.5rem] bg-muted/10 border-r border-border" })
|
|
1219
|
-
] }, row.id)) })
|
|
1220
|
-
] }) }),
|
|
1221
|
-
/* @__PURE__ */ jsx3("style", { children: `
|
|
1222
|
-
.col-resize-handle:hover .col-resize-handle-line {
|
|
1223
|
-
background-color: var(--primary, #6366f1);
|
|
1224
|
-
opacity: 0.75;
|
|
1225
|
-
}
|
|
1226
|
-
.col-resize-handle.active .col-resize-handle-line {
|
|
1227
|
-
background-color: var(--primary, #6366f1);
|
|
1228
|
-
opacity: 1;
|
|
1229
|
-
}
|
|
1230
|
-
table.table-fixed th {
|
|
1231
|
-
overflow: hidden;
|
|
1232
|
-
}
|
|
1233
|
-
table.table-fixed td {
|
|
1234
|
-
max-width: 0;
|
|
1235
|
-
overflow: hidden;
|
|
1236
|
-
}
|
|
1237
|
-
` })
|
|
1108
|
+
] })
|
|
1109
|
+
] }),
|
|
1110
|
+
!isDraft && /* @__PURE__ */ jsxs5("div", { className: "flex justify-end gap-1", onClick: stop, children: [
|
|
1111
|
+
/* @__PURE__ */ jsx6("button", { type: "button", className: buttonClass, onClick: () => setResolved(!thread.resolved), children: thread.resolved ? "Reopen" : "Resolve" }),
|
|
1112
|
+
/* @__PURE__ */ jsx6(
|
|
1113
|
+
"button",
|
|
1114
|
+
{
|
|
1115
|
+
type: "button",
|
|
1116
|
+
className: `${buttonClass} hover:text-destructive`,
|
|
1117
|
+
onClick: remove,
|
|
1118
|
+
children: "Delete"
|
|
1119
|
+
}
|
|
1120
|
+
)
|
|
1121
|
+
] })
|
|
1238
1122
|
]
|
|
1239
1123
|
}
|
|
1240
1124
|
);
|
|
1241
1125
|
};
|
|
1242
1126
|
|
|
1243
|
-
// src/
|
|
1244
|
-
import {
|
|
1245
|
-
|
|
1246
|
-
var
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1127
|
+
// src/review/ReviewToolbar.tsx
|
|
1128
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1129
|
+
var buttonClass2 = "rounded px-2 py-1 text-xs text-foreground hover:bg-muted disabled:opacity-40 disabled:hover:bg-transparent";
|
|
1130
|
+
var ReviewToolbar = ({
|
|
1131
|
+
editor,
|
|
1132
|
+
className = "flex flex-wrap items-center gap-1 rounded-md border border-border bg-background p-1 text-sm"
|
|
1133
|
+
}) => {
|
|
1134
|
+
const review = useTrackChanges(editor);
|
|
1135
|
+
const count = review.changes.length;
|
|
1136
|
+
const current = review.currentChange;
|
|
1137
|
+
const index = current ? review.changes.findIndex((c) => c.id === current.id) + 1 : 0;
|
|
1138
|
+
return /* @__PURE__ */ jsxs6("div", { className, role: "toolbar", "aria-label": "Review", children: [
|
|
1139
|
+
/* @__PURE__ */ jsx7(
|
|
1140
|
+
"button",
|
|
1141
|
+
{
|
|
1142
|
+
type: "button",
|
|
1143
|
+
className: `${buttonClass2} ${review.enabled ? "bg-primary/10 text-primary" : ""}`,
|
|
1144
|
+
"aria-pressed": review.enabled,
|
|
1145
|
+
disabled: !editor,
|
|
1146
|
+
onClick: review.toggle,
|
|
1147
|
+
children: review.enabled ? "Tracking on" : "Track changes"
|
|
1148
|
+
}
|
|
1149
|
+
),
|
|
1150
|
+
/* @__PURE__ */ jsx7("span", { className: "mx-1 h-4 w-px bg-border", "aria-hidden": "true" }),
|
|
1151
|
+
/* @__PURE__ */ jsx7(
|
|
1152
|
+
"button",
|
|
1153
|
+
{
|
|
1154
|
+
type: "button",
|
|
1155
|
+
className: buttonClass2,
|
|
1156
|
+
"aria-label": "Previous change",
|
|
1157
|
+
disabled: count === 0,
|
|
1158
|
+
onClick: review.previous,
|
|
1159
|
+
children: "\u2039"
|
|
1160
|
+
}
|
|
1161
|
+
),
|
|
1162
|
+
/* @__PURE__ */ jsx7("span", { className: "min-w-[4rem] text-center text-xs text-muted-foreground", "aria-live": "polite", children: count === 0 ? "No changes" : current ? `${index} of ${count}` : `${count} changes` }),
|
|
1163
|
+
/* @__PURE__ */ jsx7(
|
|
1164
|
+
"button",
|
|
1165
|
+
{
|
|
1166
|
+
type: "button",
|
|
1167
|
+
className: buttonClass2,
|
|
1168
|
+
"aria-label": "Next change",
|
|
1169
|
+
disabled: count === 0,
|
|
1170
|
+
onClick: review.next,
|
|
1171
|
+
children: "\u203A"
|
|
1172
|
+
}
|
|
1173
|
+
),
|
|
1174
|
+
/* @__PURE__ */ jsx7("span", { className: "mx-1 h-4 w-px bg-border", "aria-hidden": "true" }),
|
|
1175
|
+
/* @__PURE__ */ jsx7(
|
|
1176
|
+
"button",
|
|
1177
|
+
{
|
|
1178
|
+
type: "button",
|
|
1179
|
+
className: buttonClass2,
|
|
1180
|
+
disabled: !current,
|
|
1181
|
+
onClick: () => current && review.accept(current.id),
|
|
1182
|
+
children: "Accept"
|
|
1183
|
+
}
|
|
1184
|
+
),
|
|
1185
|
+
/* @__PURE__ */ jsx7(
|
|
1186
|
+
"button",
|
|
1187
|
+
{
|
|
1188
|
+
type: "button",
|
|
1189
|
+
className: buttonClass2,
|
|
1190
|
+
disabled: !current,
|
|
1191
|
+
onClick: () => current && review.reject(current.id),
|
|
1192
|
+
children: "Reject"
|
|
1193
|
+
}
|
|
1194
|
+
),
|
|
1195
|
+
/* @__PURE__ */ jsx7("button", { type: "button", className: buttonClass2, disabled: count === 0, onClick: review.acceptAll, children: "Accept all" }),
|
|
1196
|
+
/* @__PURE__ */ jsx7("button", { type: "button", className: buttonClass2, disabled: count === 0, onClick: review.rejectAll, children: "Reject all" })
|
|
1197
|
+
] });
|
|
1265
1198
|
};
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
}
|
|
1199
|
+
|
|
1200
|
+
// src/review/CommentButton.tsx
|
|
1201
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
1202
|
+
var CommentButton = ({
|
|
1203
|
+
editor,
|
|
1204
|
+
className = "rounded px-2 py-1 text-xs text-popover-foreground hover:bg-muted",
|
|
1205
|
+
children = "Comment"
|
|
1206
|
+
}) => /* @__PURE__ */ jsx8(
|
|
1207
|
+
"button",
|
|
1208
|
+
{
|
|
1209
|
+
type: "button",
|
|
1210
|
+
className,
|
|
1211
|
+
disabled: !editor,
|
|
1212
|
+
onClick: () => editor?.chain().focus().addComment().run(),
|
|
1213
|
+
children
|
|
1214
|
+
}
|
|
1215
|
+
);
|
|
1274
1216
|
export {
|
|
1275
1217
|
BubbleMenu,
|
|
1218
|
+
CommentButton,
|
|
1219
|
+
CommentsPanel,
|
|
1276
1220
|
DirtyTracker,
|
|
1277
1221
|
EditorContent,
|
|
1278
1222
|
EditorSlotsProvider,
|
|
1223
|
+
FormulaHints,
|
|
1279
1224
|
HistoryManager2 as HistoryManager,
|
|
1280
1225
|
ImageEditor,
|
|
1226
|
+
OutlinePanel,
|
|
1227
|
+
ReviewToolbar,
|
|
1228
|
+
SpreadsheetContextMenu,
|
|
1281
1229
|
SpreadsheetEditor,
|
|
1230
|
+
SpreadsheetGroupRow,
|
|
1282
1231
|
TemplateRenderer,
|
|
1232
|
+
VariableForm,
|
|
1283
1233
|
createDirtyTracker,
|
|
1284
1234
|
createHistoryManager2 as createHistoryManager,
|
|
1285
1235
|
defaultIsEqual,
|
|
1236
|
+
useAgentToolProvider,
|
|
1237
|
+
useComments,
|
|
1286
1238
|
useDismissGuard,
|
|
1287
1239
|
useEditor2 as useEditor,
|
|
1288
1240
|
useEditorSlots,
|
|
1241
|
+
useFileImport,
|
|
1242
|
+
useFillHandle,
|
|
1289
1243
|
useHistory,
|
|
1290
1244
|
useHistoryShortcuts,
|
|
1291
1245
|
useImageEditor,
|
|
1292
1246
|
useNavigationGuard,
|
|
1247
|
+
useOutline,
|
|
1293
1248
|
usePromptEditor,
|
|
1294
|
-
|
|
1249
|
+
useSpreadsheetClipboard,
|
|
1250
|
+
useSpreadsheetEditor,
|
|
1251
|
+
useTrackChanges
|
|
1295
1252
|
};
|
|
1296
1253
|
//# sourceMappingURL=index.js.map
|