ct-rich-text-editor 1.3.12 → 1.3.13
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/{html2pdf.bundle-83da4814.js → html2pdf.bundle-f58b88f5.js} +2 -2
- package/dist/{html2pdf.bundle-83da4814.js.map → html2pdf.bundle-f58b88f5.js.map} +1 -1
- package/dist/{html2pdf.bundle.min-9fbba084.js → html2pdf.bundle.min-277f1c42.js} +2 -2
- package/dist/{html2pdf.bundle.min-9fbba084.js.map → html2pdf.bundle.min-277f1c42.js.map} +1 -1
- package/dist/{index-7be32483.js → index-26434d4e.js} +2 -2
- package/dist/{index-7be32483.js.map → index-26434d4e.js.map} +1 -1
- package/dist/{index-78acd11a.js → index-38cb7602.js} +699 -428
- package/dist/index-38cb7602.js.map +1 -0
- package/dist/{index-c2f3d30e.js → index-fa2d3309.js} +2 -2
- package/dist/{index-c2f3d30e.js.map → index-fa2d3309.js.map} +1 -1
- package/dist/index.js +1 -1
- package/dist/utils/editorStyleConverter.d.ts +8 -0
- package/package.json +1 -1
- package/dist/index-78acd11a.js.map +0 -1
|
@@ -202,7 +202,7 @@ const EditorTheme = "";
|
|
|
202
202
|
const PlaygroundEditorTheme = "";
|
|
203
203
|
const AIChatPlugin$1 = "";
|
|
204
204
|
const backendInstance = axios.create({
|
|
205
|
-
baseURL: "
|
|
205
|
+
baseURL: "http://localhost:3000/",
|
|
206
206
|
headers: {
|
|
207
207
|
"Content-Type": "application/json"
|
|
208
208
|
}
|
|
@@ -1479,7 +1479,7 @@ const AiTextTransform = async ({ content, apiKey }) => {
|
|
|
1479
1479
|
const AI_ACTION_COMMAND = createCommand(
|
|
1480
1480
|
"AI_ACTION_COMMAND"
|
|
1481
1481
|
);
|
|
1482
|
-
const ImageView = React__default.lazy(() => import("./index-
|
|
1482
|
+
const ImageView = React__default.lazy(() => import("./index-26434d4e.js"));
|
|
1483
1483
|
function isGoogleDocCheckboxImg(img) {
|
|
1484
1484
|
return img.parentElement != null && img.parentElement.tagName === "LI" && img.previousSibling === null && img.getAttribute("aria-roledescription") === "checkbox";
|
|
1485
1485
|
}
|
|
@@ -15272,7 +15272,7 @@ const EmbedComponent = ({ url, displayType, alignment, nodeKey }) => {
|
|
|
15272
15272
|
}
|
|
15273
15273
|
);
|
|
15274
15274
|
};
|
|
15275
|
-
const FileComponent = React$1.lazy(() => import("./index-
|
|
15275
|
+
const FileComponent = React$1.lazy(() => import("./index-fa2d3309.js"));
|
|
15276
15276
|
function convertFileElement(domNode) {
|
|
15277
15277
|
if (domNode instanceof HTMLDivElement) {
|
|
15278
15278
|
const dataUrl = domNode.getAttribute("data-lexical-file-src");
|
|
@@ -17827,7 +17827,7 @@ function ChartComponent({
|
|
|
17827
17827
|
setIsLoading(true);
|
|
17828
17828
|
const toastId = toast.loading("Updating chart...");
|
|
17829
17829
|
try {
|
|
17830
|
-
const backendUrl = "
|
|
17830
|
+
const backendUrl = "http://localhost:3000/".replace(/\/$/, "");
|
|
17831
17831
|
const apiKey = localStorage.getItem("apiKey") || "";
|
|
17832
17832
|
const response = await fetch(`${backendUrl}/api/chat/regenerate`, {
|
|
17833
17833
|
method: "POST",
|
|
@@ -18567,188 +18567,6 @@ const formatMenuItems = [
|
|
|
18567
18567
|
}
|
|
18568
18568
|
];
|
|
18569
18569
|
const LOWEST_PRIORITY = 1;
|
|
18570
|
-
class FeatureSuggestionAPI {
|
|
18571
|
-
static async createSuggestion(data, apiKey) {
|
|
18572
|
-
const response = await backendAPI.post(
|
|
18573
|
-
"/api/feature-suggestions",
|
|
18574
|
-
data,
|
|
18575
|
-
apiKey ? { headers: { "X-API-Key": apiKey } } : void 0
|
|
18576
|
-
);
|
|
18577
|
-
return response.data;
|
|
18578
|
-
}
|
|
18579
|
-
}
|
|
18580
|
-
function FeatureSuggestionDialog({
|
|
18581
|
-
open,
|
|
18582
|
-
onOpenChange
|
|
18583
|
-
}) {
|
|
18584
|
-
const { apiKey } = useEditor();
|
|
18585
|
-
const [title, setTitle] = useState$1("");
|
|
18586
|
-
const [description, setDescription] = useState$1("");
|
|
18587
|
-
const [link, setLink] = useState$1("");
|
|
18588
|
-
const [isSubmitting, setIsSubmitting] = useState$1(false);
|
|
18589
|
-
const [errors, setErrors] = useState$1({});
|
|
18590
|
-
const validateForm = () => {
|
|
18591
|
-
const newErrors = {};
|
|
18592
|
-
if (!title.trim()) {
|
|
18593
|
-
newErrors.title = "Title is required";
|
|
18594
|
-
}
|
|
18595
|
-
if (!description.trim()) {
|
|
18596
|
-
newErrors.description = "Description is required";
|
|
18597
|
-
} else if (description.trim().length < 10) {
|
|
18598
|
-
newErrors.description = "Description must be at least 10 characters";
|
|
18599
|
-
}
|
|
18600
|
-
if (link.trim()) {
|
|
18601
|
-
try {
|
|
18602
|
-
new URL(link.trim());
|
|
18603
|
-
} catch {
|
|
18604
|
-
newErrors.link = "Please enter a valid URL";
|
|
18605
|
-
}
|
|
18606
|
-
}
|
|
18607
|
-
setErrors(newErrors);
|
|
18608
|
-
return Object.keys(newErrors).length === 0;
|
|
18609
|
-
};
|
|
18610
|
-
const handleSubmit = async (e) => {
|
|
18611
|
-
e.preventDefault();
|
|
18612
|
-
if (!validateForm()) {
|
|
18613
|
-
return;
|
|
18614
|
-
}
|
|
18615
|
-
setIsSubmitting(true);
|
|
18616
|
-
try {
|
|
18617
|
-
await FeatureSuggestionAPI.createSuggestion(
|
|
18618
|
-
{
|
|
18619
|
-
title: title.trim(),
|
|
18620
|
-
description: description.trim(),
|
|
18621
|
-
link: link.trim() || null
|
|
18622
|
-
},
|
|
18623
|
-
apiKey || void 0
|
|
18624
|
-
);
|
|
18625
|
-
toast.success("Success!", {
|
|
18626
|
-
description: "Your feature suggestion has been submitted successfully!"
|
|
18627
|
-
});
|
|
18628
|
-
setTitle("");
|
|
18629
|
-
setDescription("");
|
|
18630
|
-
setLink("");
|
|
18631
|
-
setErrors({});
|
|
18632
|
-
onOpenChange(false);
|
|
18633
|
-
} catch (error) {
|
|
18634
|
-
console.error("Error submitting suggestion:", error);
|
|
18635
|
-
toast.error("Error", {
|
|
18636
|
-
description: "Failed to submit feature suggestion. Please try again."
|
|
18637
|
-
});
|
|
18638
|
-
} finally {
|
|
18639
|
-
setIsSubmitting(false);
|
|
18640
|
-
}
|
|
18641
|
-
};
|
|
18642
|
-
const handleCancel = () => {
|
|
18643
|
-
setTitle("");
|
|
18644
|
-
setDescription("");
|
|
18645
|
-
setLink("");
|
|
18646
|
-
setErrors({});
|
|
18647
|
-
onOpenChange(false);
|
|
18648
|
-
};
|
|
18649
|
-
return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(DialogContent, { className: "sm:max-w-[500px]", children: [
|
|
18650
|
-
/* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
18651
|
-
/* @__PURE__ */ jsxs(DialogTitle, { className: "cteditor-flex cteditor-items-center cteditor-gap-2", children: [
|
|
18652
|
-
/* @__PURE__ */ jsx(Lightbulb, { className: "cteditor-h-5 cteditor-w-5 cteditor-text-primary" }),
|
|
18653
|
-
"Suggest a Feature"
|
|
18654
|
-
] }),
|
|
18655
|
-
/* @__PURE__ */ jsx(DialogDescription, { children: "Help us improve by suggesting new features you'd like to see" })
|
|
18656
|
-
] }),
|
|
18657
|
-
/* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, children: [
|
|
18658
|
-
/* @__PURE__ */ jsxs("div", { className: "cteditor-grid cteditor-gap-4 cteditor-py-4", children: [
|
|
18659
|
-
/* @__PURE__ */ jsxs("div", { className: "cteditor-grid cteditor-gap-2", children: [
|
|
18660
|
-
/* @__PURE__ */ jsx(Label$2, { htmlFor: "title", children: "Feature Name *" }),
|
|
18661
|
-
/* @__PURE__ */ jsx(
|
|
18662
|
-
Input$1,
|
|
18663
|
-
{
|
|
18664
|
-
id: "title",
|
|
18665
|
-
placeholder: "Enter a title for your feature suggestion",
|
|
18666
|
-
value: title,
|
|
18667
|
-
onChange: (e) => {
|
|
18668
|
-
setTitle(e.target.value);
|
|
18669
|
-
if (errors.title) {
|
|
18670
|
-
setErrors({ ...errors, title: void 0 });
|
|
18671
|
-
}
|
|
18672
|
-
},
|
|
18673
|
-
className: errors.title ? "cteditor-border-red-500 focus-visible:cteditor-ring-red-500" : ""
|
|
18674
|
-
}
|
|
18675
|
-
),
|
|
18676
|
-
errors.title && /* @__PURE__ */ jsx("p", { className: "cteditor-text-sm cteditor-text-red-500", children: errors.title })
|
|
18677
|
-
] }),
|
|
18678
|
-
/* @__PURE__ */ jsxs("div", { className: "cteditor-grid cteditor-gap-2", children: [
|
|
18679
|
-
/* @__PURE__ */ jsx(Label$2, { htmlFor: "description", children: "Description *" }),
|
|
18680
|
-
/* @__PURE__ */ jsx(
|
|
18681
|
-
"textarea",
|
|
18682
|
-
{
|
|
18683
|
-
id: "description",
|
|
18684
|
-
placeholder: "Describe your feature suggestion in detail. What problem would it solve? How would it work?",
|
|
18685
|
-
value: description,
|
|
18686
|
-
onChange: (e) => {
|
|
18687
|
-
setDescription(e.target.value);
|
|
18688
|
-
if (errors.description) {
|
|
18689
|
-
setErrors({ ...errors, description: void 0 });
|
|
18690
|
-
}
|
|
18691
|
-
},
|
|
18692
|
-
className: `cteditor-flex cteditor-min-h-[120px] cteditor-w-full cteditor-rounded-md cteditor-border cteditor-border-input cteditor-bg-transparent cteditor-px-3 cteditor-py-2 cteditor-text-base cteditor-shadow-sm placeholder:cteditor-text-muted-foreground focus-visible:cteditor-outline-none focus-visible:cteditor-ring-1 focus-visible:cteditor-ring-ring disabled:cteditor-cursor-not-allowed disabled:cteditor-opacity-50 ${errors.description ? "cteditor-border-red-500 focus-visible:cteditor-ring-red-500" : ""}`
|
|
18693
|
-
}
|
|
18694
|
-
),
|
|
18695
|
-
errors.description && /* @__PURE__ */ jsx("p", { className: "cteditor-text-sm cteditor-text-red-500", children: errors.description })
|
|
18696
|
-
] }),
|
|
18697
|
-
/* @__PURE__ */ jsxs("div", { className: "cteditor-grid cteditor-gap-2", children: [
|
|
18698
|
-
/* @__PURE__ */ jsx(Label$2, { htmlFor: "link", children: "Related Link (Optional)" }),
|
|
18699
|
-
/* @__PURE__ */ jsx(
|
|
18700
|
-
Input$1,
|
|
18701
|
-
{
|
|
18702
|
-
id: "link",
|
|
18703
|
-
type: "text",
|
|
18704
|
-
placeholder: "https://example.com",
|
|
18705
|
-
value: link,
|
|
18706
|
-
onChange: (e) => {
|
|
18707
|
-
setLink(e.target.value);
|
|
18708
|
-
if (errors.link) {
|
|
18709
|
-
setErrors({ ...errors, link: void 0 });
|
|
18710
|
-
}
|
|
18711
|
-
},
|
|
18712
|
-
onPaste: (e) => {
|
|
18713
|
-
e.stopPropagation();
|
|
18714
|
-
},
|
|
18715
|
-
className: errors.link ? "cteditor-border-red-500 focus-visible:cteditor-ring-red-500" : ""
|
|
18716
|
-
}
|
|
18717
|
-
),
|
|
18718
|
-
errors.link && /* @__PURE__ */ jsx("p", { className: "cteditor-text-sm cteditor-text-red-500", children: errors.link })
|
|
18719
|
-
] }),
|
|
18720
|
-
/* @__PURE__ */ jsxs("div", { className: "cteditor-p-3 cteditor-bg-muted/50 cteditor-rounded-lg", children: [
|
|
18721
|
-
/* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-center cteditor-gap-1 cteditor-mb-2", children: [
|
|
18722
|
-
/* @__PURE__ */ jsx(Lightbulb, { className: "cteditor-h-4 cteditor-w-4" }),
|
|
18723
|
-
/* @__PURE__ */ jsx("h3", { className: "cteditor-text-sm cteditor-font-medium", children: "Tips for a great suggestion:" })
|
|
18724
|
-
] }),
|
|
18725
|
-
/* @__PURE__ */ jsxs("ul", { className: "cteditor-text-xs cteditor-text-muted-foreground cteditor-space-y-1", children: [
|
|
18726
|
-
/* @__PURE__ */ jsx("li", { children: "• Be specific about what you want and why it would be useful" }),
|
|
18727
|
-
/* @__PURE__ */ jsx("li", { children: "• Explain the problem your suggestion would solve" }),
|
|
18728
|
-
/* @__PURE__ */ jsx("li", { children: "• Consider how other users might benefit from this feature" }),
|
|
18729
|
-
/* @__PURE__ */ jsx("li", { children: "• Include any relevant examples or use cases" })
|
|
18730
|
-
] })
|
|
18731
|
-
] })
|
|
18732
|
-
] }),
|
|
18733
|
-
/* @__PURE__ */ jsxs(DialogFooter, { children: [
|
|
18734
|
-
/* @__PURE__ */ jsx(
|
|
18735
|
-
Button,
|
|
18736
|
-
{
|
|
18737
|
-
type: "button",
|
|
18738
|
-
variant: "outline",
|
|
18739
|
-
onClick: handleCancel,
|
|
18740
|
-
disabled: isSubmitting,
|
|
18741
|
-
children: "Cancel"
|
|
18742
|
-
}
|
|
18743
|
-
),
|
|
18744
|
-
/* @__PURE__ */ jsx(Button, { type: "submit", disabled: isSubmitting, children: isSubmitting ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
18745
|
-
/* @__PURE__ */ jsx(Loader2, { className: "cteditor-h-4 cteditor-w-4 cteditor-animate-spin cteditor-mr-2" }),
|
|
18746
|
-
"Submitting..."
|
|
18747
|
-
] }) : "Submit Suggestion" })
|
|
18748
|
-
] })
|
|
18749
|
-
] })
|
|
18750
|
-
] }) });
|
|
18751
|
-
}
|
|
18752
18570
|
const DEFAULT_FONT_SIZE = 15;
|
|
18753
18571
|
const INITIAL_TOOLBAR_STATE = {
|
|
18754
18572
|
bgColor: "#fff",
|
|
@@ -19612,6 +19430,8 @@ function TableOptionPlugin() {
|
|
|
19612
19430
|
} else {
|
|
19613
19431
|
$insertNodeToNearestRoot(tableNode);
|
|
19614
19432
|
}
|
|
19433
|
+
const exitParagraph = $createParagraphNode();
|
|
19434
|
+
tableNode.insertAfter(exitParagraph);
|
|
19615
19435
|
if ($isTableRowNode(headerRow)) {
|
|
19616
19436
|
const cells = headerRow.getChildren();
|
|
19617
19437
|
if (cells.length > 0 && $isTableCellNode(cells[0])) {
|
|
@@ -20157,10 +19977,10 @@ const PDF_CONFIG = {
|
|
|
20157
19977
|
};
|
|
20158
19978
|
const loadHtml2Pdf = async () => {
|
|
20159
19979
|
try {
|
|
20160
|
-
const mod = await import("./html2pdf.bundle.min-
|
|
19980
|
+
const mod = await import("./html2pdf.bundle.min-277f1c42.js").then((n) => n.h);
|
|
20161
19981
|
return (mod == null ? void 0 : mod.default) || mod;
|
|
20162
19982
|
} catch {
|
|
20163
|
-
const mod2 = await import("./html2pdf.bundle-
|
|
19983
|
+
const mod2 = await import("./html2pdf.bundle-f58b88f5.js").then((n) => n.h);
|
|
20164
19984
|
return (mod2 == null ? void 0 : mod2.default) || mod2;
|
|
20165
19985
|
}
|
|
20166
19986
|
};
|
|
@@ -22348,6 +22168,86 @@ const BlockFormatMenu = ({ blockType }) => {
|
|
|
22348
22168
|
}
|
|
22349
22169
|
) });
|
|
22350
22170
|
};
|
|
22171
|
+
const CHART_TYPES = [
|
|
22172
|
+
{ value: "bar", label: "Bar Chart", icon: "📊", description: "Vertical bars for comparing values" },
|
|
22173
|
+
{ value: "horizontal-bar", label: "Horizontal Bar", icon: "📈", description: "Horizontal bars for categories" },
|
|
22174
|
+
{ value: "line", label: "Line Chart", icon: "📉", description: "Connected points showing trends" },
|
|
22175
|
+
{ value: "pie", label: "Pie Chart", icon: "🥧", description: "Circular chart for proportions" },
|
|
22176
|
+
{ value: "donut", label: "Donut Chart", icon: "🍩", description: "Hollow circle showing proportions" }
|
|
22177
|
+
];
|
|
22178
|
+
const DEFAULT_COLORS = [
|
|
22179
|
+
"#4285f4",
|
|
22180
|
+
// Blue
|
|
22181
|
+
"#ea4335",
|
|
22182
|
+
// Red
|
|
22183
|
+
"#fbbc04",
|
|
22184
|
+
// Yellow
|
|
22185
|
+
"#34a853",
|
|
22186
|
+
// Green
|
|
22187
|
+
"#ff6d01"
|
|
22188
|
+
// Orange
|
|
22189
|
+
];
|
|
22190
|
+
function ChartInsertDialog({
|
|
22191
|
+
open,
|
|
22192
|
+
onOpenChange,
|
|
22193
|
+
onInsert
|
|
22194
|
+
}) {
|
|
22195
|
+
const [selectedType, setSelectedType] = useState$1("bar");
|
|
22196
|
+
const handleInsert = () => {
|
|
22197
|
+
const dummyMetadata = {
|
|
22198
|
+
type: selectedType,
|
|
22199
|
+
values: [10, 20, 15, 25, 30],
|
|
22200
|
+
labels: ["Item 1", "Item 2", "Item 3", "Item 4", "Item 5"],
|
|
22201
|
+
title: "Sample Chart",
|
|
22202
|
+
colors: DEFAULT_COLORS
|
|
22203
|
+
};
|
|
22204
|
+
onInsert(dummyMetadata);
|
|
22205
|
+
onOpenChange(false);
|
|
22206
|
+
};
|
|
22207
|
+
return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(DialogContent, { className: "sm:max-w-[500px]", children: [
|
|
22208
|
+
/* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
22209
|
+
/* @__PURE__ */ jsxs(DialogTitle, { className: "cteditor-flex cteditor-items-center cteditor-gap-2", children: [
|
|
22210
|
+
/* @__PURE__ */ jsx("span", { className: "cteditor-text-2xl", children: "📊" }),
|
|
22211
|
+
"Insert Chart"
|
|
22212
|
+
] }),
|
|
22213
|
+
/* @__PURE__ */ jsx(DialogDescription, { children: "Select a chart type to insert into your document. You can customize it after insertion." })
|
|
22214
|
+
] }),
|
|
22215
|
+
/* @__PURE__ */ jsxs("div", { className: "cteditor-space-y-4 ", children: [
|
|
22216
|
+
/* @__PURE__ */ jsx(Label$2, { className: "cteditor-text-sm cteditor-font-medium", children: "Chart Type" }),
|
|
22217
|
+
/* @__PURE__ */ jsx("div", { className: "cteditor-grid cteditor-gap-3", children: CHART_TYPES.map((type) => /* @__PURE__ */ jsxs(
|
|
22218
|
+
"button",
|
|
22219
|
+
{
|
|
22220
|
+
onClick: () => setSelectedType(type.value),
|
|
22221
|
+
className: `cteditor-flex cteditor-items-start cteditor-gap-3 cteditor-p-4 cteditor-rounded-lg cteditor-border-2 cteditor-transition-all cteditor-text-left ${selectedType === type.value ? "cteditor-border-primary cteditor-bg-primary/5" : "cteditor-border-gray-200 dark:cteditor-border-gray-700 hover:cteditor-border-gray-300 dark:hover:cteditor-border-gray-600"}`,
|
|
22222
|
+
children: [
|
|
22223
|
+
/* @__PURE__ */ jsx("span", { className: "cteditor-text-2xl", children: type.icon }),
|
|
22224
|
+
/* @__PURE__ */ jsxs("div", { className: "cteditor-flex-1", children: [
|
|
22225
|
+
/* @__PURE__ */ jsx("div", { className: "cteditor-font-medium cteditor-text-sm", children: type.label }),
|
|
22226
|
+
/* @__PURE__ */ jsx("div", { className: "cteditor-text-xs cteditor-text-gray-600 dark:cteditor-text-gray-400 cteditor-mt-1", children: type.description })
|
|
22227
|
+
] }),
|
|
22228
|
+
selectedType === type.value && /* @__PURE__ */ jsx("div", { className: "cteditor-flex cteditor-items-center cteditor-justify-center cteditor-w-5 cteditor-h-5 cteditor-rounded-full cteditor-bg-primary cteditor-text-primary-foreground", children: /* @__PURE__ */ jsx("svg", { className: "cteditor-w-3 cteditor-h-3", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z", clipRule: "evenodd" }) }) })
|
|
22229
|
+
]
|
|
22230
|
+
},
|
|
22231
|
+
type.value
|
|
22232
|
+
)) }),
|
|
22233
|
+
/* @__PURE__ */ jsx("div", { className: "cteditor-p-3 cteditor-rounded-md cteditor-bg-blue-50 dark:cteditor-bg-blue-950/20 cteditor-border cteditor-border-blue-200 dark:cteditor-border-blue-800", children: /* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-start cteditor-gap-2", children: [
|
|
22234
|
+
/* @__PURE__ */ jsx("span", { className: "cteditor-text-blue-600 dark:cteditor-text-blue-400", children: "ℹ️" }),
|
|
22235
|
+
/* @__PURE__ */ jsx("p", { className: "cteditor-text-xs cteditor-text-blue-700 dark:cteditor-text-blue-300", children: 'A sample chart with dummy data will be inserted. You can edit the chart by hovering over it and clicking the "Edit Chart" button.' })
|
|
22236
|
+
] }) })
|
|
22237
|
+
] }),
|
|
22238
|
+
/* @__PURE__ */ jsxs(DialogFooter, { className: "cteditor-gap-2", children: [
|
|
22239
|
+
/* @__PURE__ */ jsx(
|
|
22240
|
+
Button,
|
|
22241
|
+
{
|
|
22242
|
+
variant: "outline",
|
|
22243
|
+
onClick: () => onOpenChange(false),
|
|
22244
|
+
children: "Cancel"
|
|
22245
|
+
}
|
|
22246
|
+
),
|
|
22247
|
+
/* @__PURE__ */ jsx(Button, { onClick: handleInsert, children: "Insert Chart" })
|
|
22248
|
+
] })
|
|
22249
|
+
] }) });
|
|
22250
|
+
}
|
|
22351
22251
|
const ColorPicker$3 = "";
|
|
22352
22252
|
function u() {
|
|
22353
22253
|
return (u = Object.assign || function(e) {
|
|
@@ -23125,6 +23025,188 @@ const EmojiPickerWidget = forwardRef(
|
|
|
23125
23025
|
}
|
|
23126
23026
|
);
|
|
23127
23027
|
EmojiPickerWidget.displayName = "EmojiPickerWidget";
|
|
23028
|
+
class FeatureSuggestionAPI {
|
|
23029
|
+
static async createSuggestion(data, apiKey) {
|
|
23030
|
+
const response = await backendAPI.post(
|
|
23031
|
+
"/api/feature-suggestions",
|
|
23032
|
+
data,
|
|
23033
|
+
apiKey ? { headers: { "X-API-Key": apiKey } } : void 0
|
|
23034
|
+
);
|
|
23035
|
+
return response.data;
|
|
23036
|
+
}
|
|
23037
|
+
}
|
|
23038
|
+
function FeatureSuggestionDialog({
|
|
23039
|
+
open,
|
|
23040
|
+
onOpenChange
|
|
23041
|
+
}) {
|
|
23042
|
+
const { apiKey } = useEditor();
|
|
23043
|
+
const [title, setTitle] = useState$1("");
|
|
23044
|
+
const [description, setDescription] = useState$1("");
|
|
23045
|
+
const [link, setLink] = useState$1("");
|
|
23046
|
+
const [isSubmitting, setIsSubmitting] = useState$1(false);
|
|
23047
|
+
const [errors, setErrors] = useState$1({});
|
|
23048
|
+
const validateForm = () => {
|
|
23049
|
+
const newErrors = {};
|
|
23050
|
+
if (!title.trim()) {
|
|
23051
|
+
newErrors.title = "Title is required";
|
|
23052
|
+
}
|
|
23053
|
+
if (!description.trim()) {
|
|
23054
|
+
newErrors.description = "Description is required";
|
|
23055
|
+
} else if (description.trim().length < 10) {
|
|
23056
|
+
newErrors.description = "Description must be at least 10 characters";
|
|
23057
|
+
}
|
|
23058
|
+
if (link.trim()) {
|
|
23059
|
+
try {
|
|
23060
|
+
new URL(link.trim());
|
|
23061
|
+
} catch {
|
|
23062
|
+
newErrors.link = "Please enter a valid URL";
|
|
23063
|
+
}
|
|
23064
|
+
}
|
|
23065
|
+
setErrors(newErrors);
|
|
23066
|
+
return Object.keys(newErrors).length === 0;
|
|
23067
|
+
};
|
|
23068
|
+
const handleSubmit = async (e) => {
|
|
23069
|
+
e.preventDefault();
|
|
23070
|
+
if (!validateForm()) {
|
|
23071
|
+
return;
|
|
23072
|
+
}
|
|
23073
|
+
setIsSubmitting(true);
|
|
23074
|
+
try {
|
|
23075
|
+
await FeatureSuggestionAPI.createSuggestion(
|
|
23076
|
+
{
|
|
23077
|
+
title: title.trim(),
|
|
23078
|
+
description: description.trim(),
|
|
23079
|
+
link: link.trim() || null
|
|
23080
|
+
},
|
|
23081
|
+
apiKey || void 0
|
|
23082
|
+
);
|
|
23083
|
+
toast.success("Success!", {
|
|
23084
|
+
description: "Your feature suggestion has been submitted successfully!"
|
|
23085
|
+
});
|
|
23086
|
+
setTitle("");
|
|
23087
|
+
setDescription("");
|
|
23088
|
+
setLink("");
|
|
23089
|
+
setErrors({});
|
|
23090
|
+
onOpenChange(false);
|
|
23091
|
+
} catch (error) {
|
|
23092
|
+
console.error("Error submitting suggestion:", error);
|
|
23093
|
+
toast.error("Error", {
|
|
23094
|
+
description: "Failed to submit feature suggestion. Please try again."
|
|
23095
|
+
});
|
|
23096
|
+
} finally {
|
|
23097
|
+
setIsSubmitting(false);
|
|
23098
|
+
}
|
|
23099
|
+
};
|
|
23100
|
+
const handleCancel = () => {
|
|
23101
|
+
setTitle("");
|
|
23102
|
+
setDescription("");
|
|
23103
|
+
setLink("");
|
|
23104
|
+
setErrors({});
|
|
23105
|
+
onOpenChange(false);
|
|
23106
|
+
};
|
|
23107
|
+
return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(DialogContent, { className: "sm:max-w-[500px]", children: [
|
|
23108
|
+
/* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
23109
|
+
/* @__PURE__ */ jsxs(DialogTitle, { className: "cteditor-flex cteditor-items-center cteditor-gap-2", children: [
|
|
23110
|
+
/* @__PURE__ */ jsx(Lightbulb, { className: "cteditor-h-5 cteditor-w-5 cteditor-text-primary" }),
|
|
23111
|
+
"Suggest a Feature"
|
|
23112
|
+
] }),
|
|
23113
|
+
/* @__PURE__ */ jsx(DialogDescription, { children: "Help us improve by suggesting new features you'd like to see" })
|
|
23114
|
+
] }),
|
|
23115
|
+
/* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, children: [
|
|
23116
|
+
/* @__PURE__ */ jsxs("div", { className: "cteditor-grid cteditor-gap-4 cteditor-py-4", children: [
|
|
23117
|
+
/* @__PURE__ */ jsxs("div", { className: "cteditor-grid cteditor-gap-2", children: [
|
|
23118
|
+
/* @__PURE__ */ jsx(Label$2, { htmlFor: "title", children: "Feature Name *" }),
|
|
23119
|
+
/* @__PURE__ */ jsx(
|
|
23120
|
+
Input$1,
|
|
23121
|
+
{
|
|
23122
|
+
id: "title",
|
|
23123
|
+
placeholder: "Enter a title for your feature suggestion",
|
|
23124
|
+
value: title,
|
|
23125
|
+
onChange: (e) => {
|
|
23126
|
+
setTitle(e.target.value);
|
|
23127
|
+
if (errors.title) {
|
|
23128
|
+
setErrors({ ...errors, title: void 0 });
|
|
23129
|
+
}
|
|
23130
|
+
},
|
|
23131
|
+
className: errors.title ? "cteditor-border-red-500 focus-visible:cteditor-ring-red-500" : ""
|
|
23132
|
+
}
|
|
23133
|
+
),
|
|
23134
|
+
errors.title && /* @__PURE__ */ jsx("p", { className: "cteditor-text-sm cteditor-text-red-500", children: errors.title })
|
|
23135
|
+
] }),
|
|
23136
|
+
/* @__PURE__ */ jsxs("div", { className: "cteditor-grid cteditor-gap-2", children: [
|
|
23137
|
+
/* @__PURE__ */ jsx(Label$2, { htmlFor: "description", children: "Description *" }),
|
|
23138
|
+
/* @__PURE__ */ jsx(
|
|
23139
|
+
"textarea",
|
|
23140
|
+
{
|
|
23141
|
+
id: "description",
|
|
23142
|
+
placeholder: "Describe your feature suggestion in detail. What problem would it solve? How would it work?",
|
|
23143
|
+
value: description,
|
|
23144
|
+
onChange: (e) => {
|
|
23145
|
+
setDescription(e.target.value);
|
|
23146
|
+
if (errors.description) {
|
|
23147
|
+
setErrors({ ...errors, description: void 0 });
|
|
23148
|
+
}
|
|
23149
|
+
},
|
|
23150
|
+
className: `cteditor-flex cteditor-min-h-[120px] cteditor-w-full cteditor-rounded-md cteditor-border cteditor-border-input cteditor-bg-transparent cteditor-px-3 cteditor-py-2 cteditor-text-base cteditor-shadow-sm placeholder:cteditor-text-muted-foreground focus-visible:cteditor-outline-none focus-visible:cteditor-ring-1 focus-visible:cteditor-ring-ring disabled:cteditor-cursor-not-allowed disabled:cteditor-opacity-50 ${errors.description ? "cteditor-border-red-500 focus-visible:cteditor-ring-red-500" : ""}`
|
|
23151
|
+
}
|
|
23152
|
+
),
|
|
23153
|
+
errors.description && /* @__PURE__ */ jsx("p", { className: "cteditor-text-sm cteditor-text-red-500", children: errors.description })
|
|
23154
|
+
] }),
|
|
23155
|
+
/* @__PURE__ */ jsxs("div", { className: "cteditor-grid cteditor-gap-2", children: [
|
|
23156
|
+
/* @__PURE__ */ jsx(Label$2, { htmlFor: "link", children: "Related Link (Optional)" }),
|
|
23157
|
+
/* @__PURE__ */ jsx(
|
|
23158
|
+
Input$1,
|
|
23159
|
+
{
|
|
23160
|
+
id: "link",
|
|
23161
|
+
type: "text",
|
|
23162
|
+
placeholder: "https://example.com",
|
|
23163
|
+
value: link,
|
|
23164
|
+
onChange: (e) => {
|
|
23165
|
+
setLink(e.target.value);
|
|
23166
|
+
if (errors.link) {
|
|
23167
|
+
setErrors({ ...errors, link: void 0 });
|
|
23168
|
+
}
|
|
23169
|
+
},
|
|
23170
|
+
onPaste: (e) => {
|
|
23171
|
+
e.stopPropagation();
|
|
23172
|
+
},
|
|
23173
|
+
className: errors.link ? "cteditor-border-red-500 focus-visible:cteditor-ring-red-500" : ""
|
|
23174
|
+
}
|
|
23175
|
+
),
|
|
23176
|
+
errors.link && /* @__PURE__ */ jsx("p", { className: "cteditor-text-sm cteditor-text-red-500", children: errors.link })
|
|
23177
|
+
] }),
|
|
23178
|
+
/* @__PURE__ */ jsxs("div", { className: "cteditor-p-3 cteditor-bg-muted/50 cteditor-rounded-lg", children: [
|
|
23179
|
+
/* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-center cteditor-gap-1 cteditor-mb-2", children: [
|
|
23180
|
+
/* @__PURE__ */ jsx(Lightbulb, { className: "cteditor-h-4 cteditor-w-4" }),
|
|
23181
|
+
/* @__PURE__ */ jsx("h3", { className: "cteditor-text-sm cteditor-font-medium", children: "Tips for a great suggestion:" })
|
|
23182
|
+
] }),
|
|
23183
|
+
/* @__PURE__ */ jsxs("ul", { className: "cteditor-text-xs cteditor-text-muted-foreground cteditor-space-y-1", children: [
|
|
23184
|
+
/* @__PURE__ */ jsx("li", { children: "• Be specific about what you want and why it would be useful" }),
|
|
23185
|
+
/* @__PURE__ */ jsx("li", { children: "• Explain the problem your suggestion would solve" }),
|
|
23186
|
+
/* @__PURE__ */ jsx("li", { children: "• Consider how other users might benefit from this feature" }),
|
|
23187
|
+
/* @__PURE__ */ jsx("li", { children: "• Include any relevant examples or use cases" })
|
|
23188
|
+
] })
|
|
23189
|
+
] })
|
|
23190
|
+
] }),
|
|
23191
|
+
/* @__PURE__ */ jsxs(DialogFooter, { children: [
|
|
23192
|
+
/* @__PURE__ */ jsx(
|
|
23193
|
+
Button,
|
|
23194
|
+
{
|
|
23195
|
+
type: "button",
|
|
23196
|
+
variant: "outline",
|
|
23197
|
+
onClick: handleCancel,
|
|
23198
|
+
disabled: isSubmitting,
|
|
23199
|
+
children: "Cancel"
|
|
23200
|
+
}
|
|
23201
|
+
),
|
|
23202
|
+
/* @__PURE__ */ jsx(Button, { type: "submit", disabled: isSubmitting, children: isSubmitting ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
23203
|
+
/* @__PURE__ */ jsx(Loader2, { className: "cteditor-h-4 cteditor-w-4 cteditor-animate-spin cteditor-mr-2" }),
|
|
23204
|
+
"Submitting..."
|
|
23205
|
+
] }) : "Submit Suggestion" })
|
|
23206
|
+
] })
|
|
23207
|
+
] })
|
|
23208
|
+
] }) });
|
|
23209
|
+
}
|
|
23128
23210
|
const DEFAULT_FONTS = [
|
|
23129
23211
|
"Arial",
|
|
23130
23212
|
"Courier New",
|
|
@@ -25315,86 +25397,6 @@ const NotePanelMenu = ({ className }) => {
|
|
|
25315
25397
|
}) })
|
|
25316
25398
|
] });
|
|
25317
25399
|
};
|
|
25318
|
-
const CHART_TYPES = [
|
|
25319
|
-
{ value: "bar", label: "Bar Chart", icon: "📊", description: "Vertical bars for comparing values" },
|
|
25320
|
-
{ value: "horizontal-bar", label: "Horizontal Bar", icon: "📈", description: "Horizontal bars for categories" },
|
|
25321
|
-
{ value: "line", label: "Line Chart", icon: "📉", description: "Connected points showing trends" },
|
|
25322
|
-
{ value: "pie", label: "Pie Chart", icon: "🥧", description: "Circular chart for proportions" },
|
|
25323
|
-
{ value: "donut", label: "Donut Chart", icon: "🍩", description: "Hollow circle showing proportions" }
|
|
25324
|
-
];
|
|
25325
|
-
const DEFAULT_COLORS = [
|
|
25326
|
-
"#4285f4",
|
|
25327
|
-
// Blue
|
|
25328
|
-
"#ea4335",
|
|
25329
|
-
// Red
|
|
25330
|
-
"#fbbc04",
|
|
25331
|
-
// Yellow
|
|
25332
|
-
"#34a853",
|
|
25333
|
-
// Green
|
|
25334
|
-
"#ff6d01"
|
|
25335
|
-
// Orange
|
|
25336
|
-
];
|
|
25337
|
-
function ChartInsertDialog({
|
|
25338
|
-
open,
|
|
25339
|
-
onOpenChange,
|
|
25340
|
-
onInsert
|
|
25341
|
-
}) {
|
|
25342
|
-
const [selectedType, setSelectedType] = useState$1("bar");
|
|
25343
|
-
const handleInsert = () => {
|
|
25344
|
-
const dummyMetadata = {
|
|
25345
|
-
type: selectedType,
|
|
25346
|
-
values: [10, 20, 15, 25, 30],
|
|
25347
|
-
labels: ["Item 1", "Item 2", "Item 3", "Item 4", "Item 5"],
|
|
25348
|
-
title: "Sample Chart",
|
|
25349
|
-
colors: DEFAULT_COLORS
|
|
25350
|
-
};
|
|
25351
|
-
onInsert(dummyMetadata);
|
|
25352
|
-
onOpenChange(false);
|
|
25353
|
-
};
|
|
25354
|
-
return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(DialogContent, { className: "sm:max-w-[500px]", children: [
|
|
25355
|
-
/* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
25356
|
-
/* @__PURE__ */ jsxs(DialogTitle, { className: "cteditor-flex cteditor-items-center cteditor-gap-2", children: [
|
|
25357
|
-
/* @__PURE__ */ jsx("span", { className: "cteditor-text-2xl", children: "📊" }),
|
|
25358
|
-
"Insert Chart"
|
|
25359
|
-
] }),
|
|
25360
|
-
/* @__PURE__ */ jsx(DialogDescription, { children: "Select a chart type to insert into your document. You can customize it after insertion." })
|
|
25361
|
-
] }),
|
|
25362
|
-
/* @__PURE__ */ jsxs("div", { className: "cteditor-space-y-4 ", children: [
|
|
25363
|
-
/* @__PURE__ */ jsx(Label$2, { className: "cteditor-text-sm cteditor-font-medium", children: "Chart Type" }),
|
|
25364
|
-
/* @__PURE__ */ jsx("div", { className: "cteditor-grid cteditor-gap-3", children: CHART_TYPES.map((type) => /* @__PURE__ */ jsxs(
|
|
25365
|
-
"button",
|
|
25366
|
-
{
|
|
25367
|
-
onClick: () => setSelectedType(type.value),
|
|
25368
|
-
className: `cteditor-flex cteditor-items-start cteditor-gap-3 cteditor-p-4 cteditor-rounded-lg cteditor-border-2 cteditor-transition-all cteditor-text-left ${selectedType === type.value ? "cteditor-border-primary cteditor-bg-primary/5" : "cteditor-border-gray-200 dark:cteditor-border-gray-700 hover:cteditor-border-gray-300 dark:hover:cteditor-border-gray-600"}`,
|
|
25369
|
-
children: [
|
|
25370
|
-
/* @__PURE__ */ jsx("span", { className: "cteditor-text-2xl", children: type.icon }),
|
|
25371
|
-
/* @__PURE__ */ jsxs("div", { className: "cteditor-flex-1", children: [
|
|
25372
|
-
/* @__PURE__ */ jsx("div", { className: "cteditor-font-medium cteditor-text-sm", children: type.label }),
|
|
25373
|
-
/* @__PURE__ */ jsx("div", { className: "cteditor-text-xs cteditor-text-gray-600 dark:cteditor-text-gray-400 cteditor-mt-1", children: type.description })
|
|
25374
|
-
] }),
|
|
25375
|
-
selectedType === type.value && /* @__PURE__ */ jsx("div", { className: "cteditor-flex cteditor-items-center cteditor-justify-center cteditor-w-5 cteditor-h-5 cteditor-rounded-full cteditor-bg-primary cteditor-text-primary-foreground", children: /* @__PURE__ */ jsx("svg", { className: "cteditor-w-3 cteditor-h-3", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z", clipRule: "evenodd" }) }) })
|
|
25376
|
-
]
|
|
25377
|
-
},
|
|
25378
|
-
type.value
|
|
25379
|
-
)) }),
|
|
25380
|
-
/* @__PURE__ */ jsx("div", { className: "cteditor-p-3 cteditor-rounded-md cteditor-bg-blue-50 dark:cteditor-bg-blue-950/20 cteditor-border cteditor-border-blue-200 dark:cteditor-border-blue-800", children: /* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-start cteditor-gap-2", children: [
|
|
25381
|
-
/* @__PURE__ */ jsx("span", { className: "cteditor-text-blue-600 dark:cteditor-text-blue-400", children: "ℹ️" }),
|
|
25382
|
-
/* @__PURE__ */ jsx("p", { className: "cteditor-text-xs cteditor-text-blue-700 dark:cteditor-text-blue-300", children: 'A sample chart with dummy data will be inserted. You can edit the chart by hovering over it and clicking the "Edit Chart" button.' })
|
|
25383
|
-
] }) })
|
|
25384
|
-
] }),
|
|
25385
|
-
/* @__PURE__ */ jsxs(DialogFooter, { className: "cteditor-gap-2", children: [
|
|
25386
|
-
/* @__PURE__ */ jsx(
|
|
25387
|
-
Button,
|
|
25388
|
-
{
|
|
25389
|
-
variant: "outline",
|
|
25390
|
-
onClick: () => onOpenChange(false),
|
|
25391
|
-
children: "Cancel"
|
|
25392
|
-
}
|
|
25393
|
-
),
|
|
25394
|
-
/* @__PURE__ */ jsx(Button, { onClick: handleInsert, children: "Insert Chart" })
|
|
25395
|
-
] })
|
|
25396
|
-
] }) });
|
|
25397
|
-
}
|
|
25398
25400
|
const useStyles$1 = () => ({
|
|
25399
25401
|
root: "cteditor-p-2 cteditor-border-b cteditor-border-[#e0e0e0] cteditor-max-w-full cteditor-overflow-x-auto",
|
|
25400
25402
|
toolbar: "cteditor-p-2 cteditor-max-w-full cteditor-overflow-x-auto cteditor-flex cteditor-flex-nowrap cteditor-gap-1",
|
|
@@ -25771,42 +25773,49 @@ const Toolbar = ({
|
|
|
25771
25773
|
useCallback(() => {
|
|
25772
25774
|
setIsChartDialogOpen(false);
|
|
25773
25775
|
}, []);
|
|
25774
|
-
const handleChartInsert = useCallback(
|
|
25775
|
-
|
|
25776
|
-
|
|
25777
|
-
|
|
25778
|
-
|
|
25779
|
-
|
|
25780
|
-
|
|
25781
|
-
|
|
25782
|
-
|
|
25783
|
-
|
|
25784
|
-
|
|
25785
|
-
|
|
25786
|
-
|
|
25787
|
-
|
|
25788
|
-
|
|
25789
|
-
|
|
25790
|
-
|
|
25791
|
-
|
|
25792
|
-
throw new Error(data.message || "Failed to generate chart");
|
|
25793
|
-
}
|
|
25794
|
-
editor.update(() => {
|
|
25795
|
-
const chartNode = $createChartNode(data.html, metadata);
|
|
25796
|
-
const selection = $getSelection();
|
|
25797
|
-
if (!selection) {
|
|
25798
|
-
const root2 = $getRoot();
|
|
25799
|
-
root2.append(chartNode);
|
|
25800
|
-
} else {
|
|
25801
|
-
$insertNodes([chartNode]);
|
|
25776
|
+
const handleChartInsert = useCallback(
|
|
25777
|
+
async (metadata) => {
|
|
25778
|
+
const toastId = toast.loading("Generating chart...");
|
|
25779
|
+
try {
|
|
25780
|
+
const backendUrl = "http://localhost:3000/".replace(/\/$/, "");
|
|
25781
|
+
const response = await fetch(`${backendUrl}/api/chat/regenerate`, {
|
|
25782
|
+
method: "POST",
|
|
25783
|
+
headers: {
|
|
25784
|
+
"Content-Type": "application/json",
|
|
25785
|
+
"x-api-key": apiKey || ""
|
|
25786
|
+
},
|
|
25787
|
+
body: JSON.stringify(metadata)
|
|
25788
|
+
});
|
|
25789
|
+
if (!response.ok) {
|
|
25790
|
+
const errorData = await response.json().catch(() => ({}));
|
|
25791
|
+
throw new Error(
|
|
25792
|
+
errorData.message || `Server error: ${response.status}`
|
|
25793
|
+
);
|
|
25802
25794
|
}
|
|
25803
|
-
|
|
25804
|
-
|
|
25805
|
-
|
|
25806
|
-
|
|
25807
|
-
|
|
25808
|
-
|
|
25809
|
-
|
|
25795
|
+
const data = await response.json();
|
|
25796
|
+
if (!data.success || !data.html) {
|
|
25797
|
+
throw new Error(data.message || "Failed to generate chart");
|
|
25798
|
+
}
|
|
25799
|
+
editor.update(() => {
|
|
25800
|
+
const chartNode = $createChartNode(data.html, metadata);
|
|
25801
|
+
const selection = $getSelection();
|
|
25802
|
+
if (!selection) {
|
|
25803
|
+
const root2 = $getRoot();
|
|
25804
|
+
root2.append(chartNode);
|
|
25805
|
+
} else {
|
|
25806
|
+
$insertNodes([chartNode]);
|
|
25807
|
+
}
|
|
25808
|
+
const paragraphNode = $createParagraphNode();
|
|
25809
|
+
chartNode.insertAfter(paragraphNode);
|
|
25810
|
+
});
|
|
25811
|
+
toast.success("Chart inserted successfully!", { id: toastId });
|
|
25812
|
+
} catch (error) {
|
|
25813
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
25814
|
+
toast.error(`Failed to insert chart: ${errorMessage}`, { id: toastId });
|
|
25815
|
+
}
|
|
25816
|
+
},
|
|
25817
|
+
[editor, apiKey]
|
|
25818
|
+
);
|
|
25810
25819
|
const handleExportPDF = useCallback(async () => {
|
|
25811
25820
|
try {
|
|
25812
25821
|
setIsExportingPDF(true);
|
|
@@ -25836,7 +25845,11 @@ const Toolbar = ({
|
|
|
25836
25845
|
});
|
|
25837
25846
|
}, 200);
|
|
25838
25847
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().slice(0, 19).replace(/[:T]/g, "-");
|
|
25839
|
-
await exportEditorToPDF(
|
|
25848
|
+
await exportEditorToPDF(
|
|
25849
|
+
activeEditor,
|
|
25850
|
+
`export-${timestamp}.pdf`,
|
|
25851
|
+
apiKey || void 0
|
|
25852
|
+
);
|
|
25840
25853
|
clearInterval(progressInterval);
|
|
25841
25854
|
setExportProgress(100);
|
|
25842
25855
|
toast.success("PDF exported successfully!", {
|
|
@@ -26450,7 +26463,12 @@ const Toolbar = ({
|
|
|
26450
26463
|
DropdownMenuItem,
|
|
26451
26464
|
{
|
|
26452
26465
|
asChild: true,
|
|
26453
|
-
onSelect: (
|
|
26466
|
+
onSelect: () => {
|
|
26467
|
+
editor.dispatchCommand(
|
|
26468
|
+
CREATE_TABLE_COMMAND,
|
|
26469
|
+
void 0
|
|
26470
|
+
);
|
|
26471
|
+
},
|
|
26454
26472
|
children: /* @__PURE__ */ jsxs(
|
|
26455
26473
|
"div",
|
|
26456
26474
|
{
|
|
@@ -26657,7 +26675,10 @@ const Toolbar = ({
|
|
|
26657
26675
|
/* @__PURE__ */ jsxs(
|
|
26658
26676
|
"button",
|
|
26659
26677
|
{
|
|
26660
|
-
onClick: () => editor.dispatchCommand(
|
|
26678
|
+
onClick: () => editor.dispatchCommand(
|
|
26679
|
+
AI_TRANSLATE_COMMAND,
|
|
26680
|
+
void 0
|
|
26681
|
+
),
|
|
26661
26682
|
className: "cteditor-w-full cteditor-justify-start cteditor-gap-2",
|
|
26662
26683
|
children: [
|
|
26663
26684
|
/* @__PURE__ */ jsx("div", { className: "[&>svg]:cteditor-size-5 cteditor-size-6 cteditor-flex cteditor-justify-center cteditor-items-center", children: /* @__PURE__ */ jsx(TranslateIcon, {}) }),
|
|
@@ -26694,7 +26715,10 @@ const Toolbar = ({
|
|
|
26694
26715
|
/* @__PURE__ */ jsxs(
|
|
26695
26716
|
"button",
|
|
26696
26717
|
{
|
|
26697
|
-
onClick: () => editor.dispatchCommand(
|
|
26718
|
+
onClick: () => editor.dispatchCommand(
|
|
26719
|
+
AI_ADJUST_TONE_COMMAND,
|
|
26720
|
+
void 0
|
|
26721
|
+
),
|
|
26698
26722
|
className: "cteditor-w-full cteditor-justify-start cteditor-gap-2",
|
|
26699
26723
|
children: [
|
|
26700
26724
|
/* @__PURE__ */ jsx("div", { className: "[&>svg]:cteditor-size-5 cteditor-size-6 cteditor-flex cteditor-justify-center cteditor-items-center", children: /* @__PURE__ */ jsx(Volume2, {}) }),
|
|
@@ -27046,7 +27070,7 @@ class GrammarAIService {
|
|
|
27046
27070
|
__publicField(this, "apiEndpoint");
|
|
27047
27071
|
__publicField(this, "requestTimeout", REQUEST_TIMEOUT);
|
|
27048
27072
|
__publicField(this, "sentenceCache", /* @__PURE__ */ new Map());
|
|
27049
|
-
this.apiEndpoint = "
|
|
27073
|
+
this.apiEndpoint = "http://localhost:3000/" + apiEndpoint;
|
|
27050
27074
|
}
|
|
27051
27075
|
isSentenceCached(text) {
|
|
27052
27076
|
const hash = generateSentenceHash(text);
|
|
@@ -27179,7 +27203,7 @@ function CombinedAutocompleteGrammarPlugin({
|
|
|
27179
27203
|
onSelectOption,
|
|
27180
27204
|
minMatchLength = 2,
|
|
27181
27205
|
maxSuggestions = 10,
|
|
27182
|
-
apiEndpoint = "api/
|
|
27206
|
+
apiEndpoint = "api/grammar/process",
|
|
27183
27207
|
enableAI = true,
|
|
27184
27208
|
debounceDelay = 800
|
|
27185
27209
|
}) {
|
|
@@ -27206,7 +27230,9 @@ function CombinedAutocompleteGrammarPlugin({
|
|
|
27206
27230
|
);
|
|
27207
27231
|
const [errors, setErrors] = useState$1([]);
|
|
27208
27232
|
const [errorMap, setErrorMap] = useState$1(/* @__PURE__ */ new Map());
|
|
27209
|
-
const [checkingSentences, setCheckingSentences] = useState$1(
|
|
27233
|
+
const [checkingSentences, setCheckingSentences] = useState$1(
|
|
27234
|
+
/* @__PURE__ */ new Set()
|
|
27235
|
+
);
|
|
27210
27236
|
const [ignoredErrors, setIgnoredErrors] = useState$1(/* @__PURE__ */ new Set());
|
|
27211
27237
|
const [correctedSentences, setCorrectedSentences] = useState$1(
|
|
27212
27238
|
/* @__PURE__ */ new Set()
|
|
@@ -27828,24 +27854,37 @@ function CombinedAutocompleteGrammarPlugin({
|
|
|
27828
27854
|
)
|
|
27829
27855
|
] }),
|
|
27830
27856
|
/* @__PURE__ */ jsx("div", { className: "cteditor-p-3 cteditor-bg-red-50 dark:cteditor-bg-red-900/10 cteditor-rounded-lg cteditor-border-2 cteditor-border-red-200 dark:cteditor-border-red-800", children: /* @__PURE__ */ jsx("p", { className: "cteditor-text-sm cteditor-line-through cteditor-text-red-700 dark:cteditor-text-red-400 cteditor-font-semibold", children: error.original }) }),
|
|
27831
|
-
error.suggestions.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "cteditor-space-y-2", children: [
|
|
27857
|
+
error.suggestions.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "cteditor-space-y-2 overflow-y-auto cteditor-max-h-48", children: [
|
|
27832
27858
|
/* @__PURE__ */ jsx("p", { className: "cteditor-text-xs cteditor-font-bold cteditor-text-gray-700 dark:cteditor-text-gray-300 cteditor-uppercase cteditor-tracking-wider", children: "Suggestions:" }),
|
|
27833
|
-
|
|
27834
|
-
"
|
|
27859
|
+
/* @__PURE__ */ jsx(
|
|
27860
|
+
"div",
|
|
27835
27861
|
{
|
|
27836
|
-
|
|
27837
|
-
|
|
27838
|
-
|
|
27839
|
-
|
|
27862
|
+
style: {
|
|
27863
|
+
//add overflow y logic
|
|
27864
|
+
overflowY: "auto",
|
|
27865
|
+
maxHeight: "130px",
|
|
27866
|
+
display: "grid",
|
|
27867
|
+
gridTemplateColumns: "1fr",
|
|
27868
|
+
gap: "8px"
|
|
27840
27869
|
},
|
|
27841
|
-
|
|
27842
|
-
|
|
27843
|
-
|
|
27844
|
-
|
|
27845
|
-
|
|
27846
|
-
|
|
27847
|
-
|
|
27848
|
-
|
|
27870
|
+
children: error.suggestions.map((suggestion, idx) => /* @__PURE__ */ jsxs(
|
|
27871
|
+
"button",
|
|
27872
|
+
{
|
|
27873
|
+
onClick: (e) => {
|
|
27874
|
+
e.preventDefault();
|
|
27875
|
+
e.stopPropagation();
|
|
27876
|
+
applyCorrection(suggestion, error);
|
|
27877
|
+
},
|
|
27878
|
+
className: "cteditor-w-full cteditor-flex cteditor-items-center cteditor-gap-3 cteditor-px-4 cteditor-py-3 cteditor-bg-green-50 dark:cteditor-bg-green-900/10 hover:cteditor-bg-green-100 cteditor-border-2 cteditor-border-green-200 cteditor-rounded-lg cteditor-transition-all",
|
|
27879
|
+
children: [
|
|
27880
|
+
/* @__PURE__ */ jsx(CheckCircle, { className: "cteditor-w-5 cteditor-h-5 cteditor-text-green-600" }),
|
|
27881
|
+
/* @__PURE__ */ jsx("span", { className: "cteditor-text-sm cteditor-font-semibold cteditor-text-green-700", children: suggestion })
|
|
27882
|
+
]
|
|
27883
|
+
},
|
|
27884
|
+
idx
|
|
27885
|
+
))
|
|
27886
|
+
}
|
|
27887
|
+
),
|
|
27849
27888
|
error.type === "grammar" && error.correctedSentence && /* @__PURE__ */ jsx(
|
|
27850
27889
|
"button",
|
|
27851
27890
|
{
|
|
@@ -30439,7 +30478,7 @@ function LinkPreviewPlugin() {
|
|
|
30439
30478
|
return;
|
|
30440
30479
|
}
|
|
30441
30480
|
const linkElement = target.closest("a");
|
|
30442
|
-
if (linkElement) {
|
|
30481
|
+
if (linkElement && editorElement.contains(linkElement)) {
|
|
30443
30482
|
const href = linkElement.getAttribute("href");
|
|
30444
30483
|
if (href && href !== "https://" && href !== "http://" && href !== "#") {
|
|
30445
30484
|
if (showTimeout) {
|
|
@@ -30476,7 +30515,7 @@ function LinkPreviewPlugin() {
|
|
|
30476
30515
|
return;
|
|
30477
30516
|
}
|
|
30478
30517
|
const linkElement = target.closest("a");
|
|
30479
|
-
if (linkElement) {
|
|
30518
|
+
if (linkElement && editorElement.contains(linkElement)) {
|
|
30480
30519
|
if (showTimeout) {
|
|
30481
30520
|
clearTimeout(showTimeout);
|
|
30482
30521
|
showTimeout = null;
|
|
@@ -30491,10 +30530,35 @@ function LinkPreviewPlugin() {
|
|
|
30491
30530
|
}
|
|
30492
30531
|
}
|
|
30493
30532
|
};
|
|
30533
|
+
const handlePreviewMouseOver = (event) => {
|
|
30534
|
+
const target = event.target;
|
|
30535
|
+
if (target.closest(".link-preview-card")) {
|
|
30536
|
+
isOverPreview = true;
|
|
30537
|
+
if (hideTimeout) {
|
|
30538
|
+
clearTimeout(hideTimeout);
|
|
30539
|
+
hideTimeout = null;
|
|
30540
|
+
}
|
|
30541
|
+
}
|
|
30542
|
+
};
|
|
30543
|
+
const handlePreviewMouseOut = (event) => {
|
|
30544
|
+
const target = event.target;
|
|
30545
|
+
const relatedTarget = event.relatedTarget;
|
|
30546
|
+
if (target.closest(".link-preview-card")) {
|
|
30547
|
+
isOverPreview = false;
|
|
30548
|
+
const movingToLink = relatedTarget == null ? void 0 : relatedTarget.closest("a");
|
|
30549
|
+
if (!movingToLink || !editorElement.contains(movingToLink)) {
|
|
30550
|
+
hideTimeout = window.setTimeout(() => {
|
|
30551
|
+
if (!isOverPreview) {
|
|
30552
|
+
setHoveredLink(null);
|
|
30553
|
+
}
|
|
30554
|
+
}, 300);
|
|
30555
|
+
}
|
|
30556
|
+
}
|
|
30557
|
+
};
|
|
30494
30558
|
editorElement.addEventListener("mouseover", handleMouseOver);
|
|
30495
30559
|
editorElement.addEventListener("mouseout", handleMouseOut);
|
|
30496
|
-
document.body.addEventListener("mouseover",
|
|
30497
|
-
document.body.addEventListener("mouseout",
|
|
30560
|
+
document.body.addEventListener("mouseover", handlePreviewMouseOver);
|
|
30561
|
+
document.body.addEventListener("mouseout", handlePreviewMouseOut);
|
|
30498
30562
|
return () => {
|
|
30499
30563
|
if (showTimeout) {
|
|
30500
30564
|
clearTimeout(showTimeout);
|
|
@@ -30504,8 +30568,8 @@ function LinkPreviewPlugin() {
|
|
|
30504
30568
|
}
|
|
30505
30569
|
editorElement.removeEventListener("mouseover", handleMouseOver);
|
|
30506
30570
|
editorElement.removeEventListener("mouseout", handleMouseOut);
|
|
30507
|
-
document.body.removeEventListener("mouseover",
|
|
30508
|
-
document.body.removeEventListener("mouseout",
|
|
30571
|
+
document.body.removeEventListener("mouseover", handlePreviewMouseOver);
|
|
30572
|
+
document.body.removeEventListener("mouseout", handlePreviewMouseOut);
|
|
30509
30573
|
};
|
|
30510
30574
|
}, [editor]);
|
|
30511
30575
|
if (!hoveredLink) {
|
|
@@ -31684,8 +31748,6 @@ const basicColors = [
|
|
|
31684
31748
|
"#9b9b9b",
|
|
31685
31749
|
"#ffffff"
|
|
31686
31750
|
];
|
|
31687
|
-
const WIDTH = 214;
|
|
31688
|
-
const HEIGHT = 150;
|
|
31689
31751
|
function ColorPicker({
|
|
31690
31752
|
color,
|
|
31691
31753
|
onChange,
|
|
@@ -31694,19 +31756,6 @@ function ColorPicker({
|
|
|
31694
31756
|
const [selfColor, setSelfColor] = useState$1(transformColor("hex", color));
|
|
31695
31757
|
const [inputColor, setInputColor] = useState$1(color);
|
|
31696
31758
|
const innerDivRef = useRef(null);
|
|
31697
|
-
const saturationPosition = useMemo(
|
|
31698
|
-
() => ({
|
|
31699
|
-
x: selfColor.hsv.s / 100 * WIDTH,
|
|
31700
|
-
y: (100 - selfColor.hsv.v) / 100 * HEIGHT
|
|
31701
|
-
}),
|
|
31702
|
-
[selfColor.hsv.s, selfColor.hsv.v]
|
|
31703
|
-
);
|
|
31704
|
-
const huePosition = useMemo(
|
|
31705
|
-
() => ({
|
|
31706
|
-
x: selfColor.hsv.h / 360 * WIDTH
|
|
31707
|
-
}),
|
|
31708
|
-
[selfColor.hsv]
|
|
31709
|
-
);
|
|
31710
31759
|
const onSetHex = (hex) => {
|
|
31711
31760
|
setInputColor(hex);
|
|
31712
31761
|
if (/^#[0-9A-Fa-f]{6}$/i.test(hex)) {
|
|
@@ -31717,15 +31766,17 @@ function ColorPicker({
|
|
|
31717
31766
|
const onMoveSaturation = ({ x: x2, y: y2 }) => {
|
|
31718
31767
|
const newHsv = {
|
|
31719
31768
|
...selfColor.hsv,
|
|
31720
|
-
s: x2
|
|
31721
|
-
|
|
31769
|
+
s: x2,
|
|
31770
|
+
// x is already 0-100
|
|
31771
|
+
v: 100 - y2
|
|
31772
|
+
// y is 0-100, so 100-y is correct for Value
|
|
31722
31773
|
};
|
|
31723
31774
|
const newColor = transformColor("hsv", newHsv);
|
|
31724
31775
|
setSelfColor(newColor);
|
|
31725
31776
|
setInputColor(newColor.hex);
|
|
31726
31777
|
};
|
|
31727
31778
|
const onMoveHue = ({ x: x2 }) => {
|
|
31728
|
-
const newHsv = { ...selfColor.hsv, h: x2 /
|
|
31779
|
+
const newHsv = { ...selfColor.hsv, h: x2 / 100 * 360 };
|
|
31729
31780
|
const newColor = transformColor("hsv", newHsv);
|
|
31730
31781
|
setSelfColor(newColor);
|
|
31731
31782
|
setInputColor(newColor.hex);
|
|
@@ -31744,67 +31795,69 @@ function ColorPicker({
|
|
|
31744
31795
|
setSelfColor(newColor);
|
|
31745
31796
|
setInputColor(newColor.hex);
|
|
31746
31797
|
}, [color]);
|
|
31747
|
-
return /* @__PURE__ */ jsxs(
|
|
31748
|
-
"div",
|
|
31749
|
-
|
|
31750
|
-
|
|
31751
|
-
|
|
31752
|
-
|
|
31753
|
-
|
|
31754
|
-
|
|
31755
|
-
|
|
31756
|
-
|
|
31757
|
-
|
|
31758
|
-
|
|
31759
|
-
|
|
31760
|
-
|
|
31761
|
-
|
|
31762
|
-
|
|
31763
|
-
|
|
31764
|
-
|
|
31765
|
-
|
|
31766
|
-
|
|
31767
|
-
|
|
31768
|
-
|
|
31769
|
-
|
|
31770
|
-
|
|
31771
|
-
|
|
31772
|
-
|
|
31773
|
-
|
|
31774
|
-
)
|
|
31775
|
-
|
|
31776
|
-
|
|
31777
|
-
{
|
|
31778
|
-
className: "color-picker-saturation",
|
|
31779
|
-
style: { backgroundColor: `hsl(${selfColor.hsv.h}, 100%, 50%)` },
|
|
31780
|
-
onChange: onMoveSaturation,
|
|
31781
|
-
children: /* @__PURE__ */ jsx(
|
|
31782
|
-
"div",
|
|
31783
|
-
{
|
|
31784
|
-
className: "color-picker-saturation_cursor",
|
|
31785
|
-
style: {
|
|
31786
|
-
backgroundColor: selfColor.hex,
|
|
31787
|
-
left: saturationPosition.x,
|
|
31788
|
-
top: saturationPosition.y
|
|
31789
|
-
}
|
|
31790
|
-
}
|
|
31791
|
-
)
|
|
31792
|
-
}
|
|
31793
|
-
),
|
|
31794
|
-
/* @__PURE__ */ jsx(MoveWrapper, { className: "color-picker-hue", onChange: onMoveHue, children: /* @__PURE__ */ jsx(
|
|
31798
|
+
return /* @__PURE__ */ jsxs("div", { className: "color-picker-wrapper", ref: innerDivRef, children: [
|
|
31799
|
+
/* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-gap-2 cteditor-justify-between cteditor-mb-2", children: [
|
|
31800
|
+
/* @__PURE__ */ jsx(TextInput, { label: "Hex", onChange: onSetHex, value: inputColor }),
|
|
31801
|
+
/* @__PURE__ */ jsx(
|
|
31802
|
+
"div",
|
|
31803
|
+
{
|
|
31804
|
+
className: "color-picker-color",
|
|
31805
|
+
style: { backgroundColor: selfColor.hex }
|
|
31806
|
+
}
|
|
31807
|
+
)
|
|
31808
|
+
] }),
|
|
31809
|
+
/* @__PURE__ */ jsx("div", { className: "color-picker-basic-color", children: basicColors.map((basicColor) => /* @__PURE__ */ jsx(
|
|
31810
|
+
"button",
|
|
31811
|
+
{
|
|
31812
|
+
className: basicColor === selfColor.hex ? " active" : "",
|
|
31813
|
+
style: { backgroundColor: basicColor },
|
|
31814
|
+
onClick: () => {
|
|
31815
|
+
setInputColor(basicColor);
|
|
31816
|
+
setSelfColor(transformColor("hex", basicColor));
|
|
31817
|
+
}
|
|
31818
|
+
},
|
|
31819
|
+
basicColor
|
|
31820
|
+
)) }),
|
|
31821
|
+
/* @__PURE__ */ jsx(
|
|
31822
|
+
MoveWrapper,
|
|
31823
|
+
{
|
|
31824
|
+
className: "color-picker-saturation",
|
|
31825
|
+
style: { backgroundColor: `hsl(${selfColor.hsv.h}, 100%, 50%)` },
|
|
31826
|
+
onChange: onMoveSaturation,
|
|
31827
|
+
children: /* @__PURE__ */ jsx(
|
|
31795
31828
|
"div",
|
|
31796
31829
|
{
|
|
31797
|
-
className: "color-picker-
|
|
31830
|
+
className: "color-picker-saturation_cursor",
|
|
31798
31831
|
style: {
|
|
31799
|
-
backgroundColor:
|
|
31800
|
-
|
|
31832
|
+
backgroundColor: selfColor.hex,
|
|
31833
|
+
// Use percentages for positioning
|
|
31834
|
+
left: `${selfColor.hsv.s}%`,
|
|
31835
|
+
top: `${100 - selfColor.hsv.v}%`
|
|
31801
31836
|
}
|
|
31802
31837
|
}
|
|
31803
|
-
)
|
|
31804
|
-
|
|
31805
|
-
|
|
31806
|
-
|
|
31807
|
-
|
|
31838
|
+
)
|
|
31839
|
+
}
|
|
31840
|
+
),
|
|
31841
|
+
/* @__PURE__ */ jsx(MoveWrapper, { className: "color-picker-hue", onChange: onMoveHue, children: /* @__PURE__ */ jsx(
|
|
31842
|
+
"div",
|
|
31843
|
+
{
|
|
31844
|
+
className: "color-picker-hue_cursor",
|
|
31845
|
+
style: {
|
|
31846
|
+
backgroundColor: `hsl(${selfColor.hsv.h}, 100%, 50%)`,
|
|
31847
|
+
// Use percentages for positioning
|
|
31848
|
+
left: `${selfColor.hsv.h / 360 * 100}%`
|
|
31849
|
+
}
|
|
31850
|
+
}
|
|
31851
|
+
) }),
|
|
31852
|
+
onApply && /* @__PURE__ */ jsx(
|
|
31853
|
+
Button,
|
|
31854
|
+
{
|
|
31855
|
+
className: "cteditor-w-full cteditor-mt-3",
|
|
31856
|
+
onClick: () => onApply(selfColor.hex),
|
|
31857
|
+
children: "Apply Color"
|
|
31858
|
+
}
|
|
31859
|
+
)
|
|
31860
|
+
] });
|
|
31808
31861
|
}
|
|
31809
31862
|
function MoveWrapper({
|
|
31810
31863
|
className,
|
|
@@ -31814,6 +31867,10 @@ function MoveWrapper({
|
|
|
31814
31867
|
}) {
|
|
31815
31868
|
const divRef = useRef(null);
|
|
31816
31869
|
const draggedRef = useRef(false);
|
|
31870
|
+
const onChangeRef = useRef(onChange);
|
|
31871
|
+
useEffect$1(() => {
|
|
31872
|
+
onChangeRef.current = onChange;
|
|
31873
|
+
}, [onChange]);
|
|
31817
31874
|
const move = (e) => {
|
|
31818
31875
|
if (divRef.current) {
|
|
31819
31876
|
const { current: div } = divRef;
|
|
@@ -31821,7 +31878,11 @@ function MoveWrapper({
|
|
|
31821
31878
|
const zoom = calculateZoomLevel(div);
|
|
31822
31879
|
const x2 = clamp(e.clientX / zoom - left, width, 0);
|
|
31823
31880
|
const y2 = clamp(e.clientY / zoom - top, height, 0);
|
|
31824
|
-
|
|
31881
|
+
const xPercent = x2 / width * 100;
|
|
31882
|
+
const yPercent = y2 / height * 100;
|
|
31883
|
+
if (onChangeRef.current) {
|
|
31884
|
+
onChangeRef.current({ x: xPercent, y: yPercent });
|
|
31885
|
+
}
|
|
31825
31886
|
}
|
|
31826
31887
|
};
|
|
31827
31888
|
const onMouseDown = (e) => {
|
|
@@ -32653,7 +32714,7 @@ function TableActionMenu({
|
|
|
32653
32714
|
);
|
|
32654
32715
|
const handleCellBackgroundColor = useCallback(
|
|
32655
32716
|
(value) => {
|
|
32656
|
-
const
|
|
32717
|
+
const getContrastColor2 = (hexColor) => {
|
|
32657
32718
|
const hex = hexColor.replace("#", "");
|
|
32658
32719
|
const r2 = parseInt(hex.substr(0, 2), 16);
|
|
32659
32720
|
const g2 = parseInt(hex.substr(2, 2), 16);
|
|
@@ -32661,7 +32722,7 @@ function TableActionMenu({
|
|
|
32661
32722
|
const luminance = (0.299 * r2 + 0.587 * g2 + 0.114 * b2) / 255;
|
|
32662
32723
|
return luminance > 0.5 ? "#000000" : "#FFFFFF";
|
|
32663
32724
|
};
|
|
32664
|
-
const textColor =
|
|
32725
|
+
const textColor = getContrastColor2(value);
|
|
32665
32726
|
const cellKeysToStyle = [];
|
|
32666
32727
|
editor.update(() => {
|
|
32667
32728
|
if (tableCellNode.isAttached()) {
|
|
@@ -33210,7 +33271,7 @@ function TableCellActionMenuContainer({
|
|
|
33210
33271
|
return () => clearTimeout(timer);
|
|
33211
33272
|
}
|
|
33212
33273
|
}, [colorPickerModal]);
|
|
33213
|
-
return /* @__PURE__ */ jsxs("div", { className: "table-cell-action-button-container", ref: menuButtonRef, children: [
|
|
33274
|
+
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("div", { className: "table-cell-action-button-container", ref: menuButtonRef, children: [
|
|
33214
33275
|
tableCellNode != null && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
33215
33276
|
!isMenuOpen && /* @__PURE__ */ jsx(
|
|
33216
33277
|
"button",
|
|
@@ -33255,7 +33316,7 @@ function TableCellActionMenuContainer({
|
|
|
33255
33316
|
)
|
|
33256
33317
|
] }),
|
|
33257
33318
|
colorPickerModal
|
|
33258
|
-
] });
|
|
33319
|
+
] }) });
|
|
33259
33320
|
}
|
|
33260
33321
|
function TableActionMenuPlugin({
|
|
33261
33322
|
anchorElem,
|
|
@@ -35080,6 +35141,190 @@ const WordCountPlugin = () => {
|
|
|
35080
35141
|
}
|
|
35081
35142
|
);
|
|
35082
35143
|
};
|
|
35144
|
+
function exportEditorWithStriping(editor) {
|
|
35145
|
+
const rootElement = editor.getRootElement();
|
|
35146
|
+
if (!rootElement)
|
|
35147
|
+
return "";
|
|
35148
|
+
const tableStyleMap = /* @__PURE__ */ new Map();
|
|
35149
|
+
const liveTables = rootElement.querySelectorAll("table");
|
|
35150
|
+
liveTables.forEach((table, index2) => {
|
|
35151
|
+
const colors = detectTableColorsFromVariables(table);
|
|
35152
|
+
if (colors) {
|
|
35153
|
+
tableStyleMap.set(index2, colors);
|
|
35154
|
+
}
|
|
35155
|
+
});
|
|
35156
|
+
let htmlString = "";
|
|
35157
|
+
editor.getEditorState().read(() => {
|
|
35158
|
+
htmlString = $generateHtmlFromNodes(editor, null);
|
|
35159
|
+
});
|
|
35160
|
+
return processHtmlForExport(htmlString, tableStyleMap);
|
|
35161
|
+
}
|
|
35162
|
+
function detectTableColorsFromVariables(table) {
|
|
35163
|
+
const computed = window.getComputedStyle(table);
|
|
35164
|
+
const oddVar = computed.getPropertyValue("--table-odd-striping-color").trim();
|
|
35165
|
+
const evenVar = computed.getPropertyValue("--table-even-striping-color").trim();
|
|
35166
|
+
const isValidColor = (c2) => c2 && c2 !== "initial" && c2 !== "inherit" && c2 !== "";
|
|
35167
|
+
if (isValidColor(oddVar) || isValidColor(evenVar)) {
|
|
35168
|
+
return {
|
|
35169
|
+
odd: isValidColor(oddVar) ? oddVar : "",
|
|
35170
|
+
even: isValidColor(evenVar) ? evenVar : ""
|
|
35171
|
+
};
|
|
35172
|
+
}
|
|
35173
|
+
const rows = Array.from(table.querySelectorAll("tr")).filter(
|
|
35174
|
+
(row) => row.querySelector("td")
|
|
35175
|
+
);
|
|
35176
|
+
if (rows.length >= 2) {
|
|
35177
|
+
const r1 = window.getComputedStyle(
|
|
35178
|
+
rows[0].querySelector("td")
|
|
35179
|
+
).backgroundColor;
|
|
35180
|
+
const r2 = window.getComputedStyle(
|
|
35181
|
+
rows[1].querySelector("td")
|
|
35182
|
+
).backgroundColor;
|
|
35183
|
+
if (r1 !== r2 && r1 !== "rgba(0, 0, 0, 0)") {
|
|
35184
|
+
return { odd: r1, even: r2 };
|
|
35185
|
+
}
|
|
35186
|
+
}
|
|
35187
|
+
return null;
|
|
35188
|
+
}
|
|
35189
|
+
function processHtmlForExport(html, tableStyleMap) {
|
|
35190
|
+
const parser = new DOMParser();
|
|
35191
|
+
const doc = parser.parseFromString(html, "text/html");
|
|
35192
|
+
const tables = doc.querySelectorAll("table");
|
|
35193
|
+
tables.forEach((table, index2) => {
|
|
35194
|
+
const colors = tableStyleMap.get(index2);
|
|
35195
|
+
if (!colors)
|
|
35196
|
+
return;
|
|
35197
|
+
const tbody = table.querySelector("tbody") || table;
|
|
35198
|
+
const dataRows = Array.from(tbody.querySelectorAll("tr")).filter(
|
|
35199
|
+
(row) => row.querySelector("td")
|
|
35200
|
+
);
|
|
35201
|
+
dataRows.forEach((row, rowIndex) => {
|
|
35202
|
+
const isOdd = !(rowIndex % 2 === 0);
|
|
35203
|
+
const bgColor = isOdd ? colors.odd : colors.even;
|
|
35204
|
+
if (bgColor) {
|
|
35205
|
+
const textColor = getContrastColor(bgColor);
|
|
35206
|
+
row.querySelectorAll("td").forEach((cell) => {
|
|
35207
|
+
const el = cell;
|
|
35208
|
+
el.style.setProperty("background-color", bgColor, "important");
|
|
35209
|
+
el.style.color = textColor;
|
|
35210
|
+
el.querySelectorAll("*").forEach((nested) => {
|
|
35211
|
+
nested.style.color = textColor;
|
|
35212
|
+
});
|
|
35213
|
+
});
|
|
35214
|
+
}
|
|
35215
|
+
});
|
|
35216
|
+
});
|
|
35217
|
+
cleanupHeaderCellStructure(doc.body);
|
|
35218
|
+
applyGenericSafeStyles(doc.body);
|
|
35219
|
+
cleanupClasses(doc.body);
|
|
35220
|
+
return doc.body.innerHTML;
|
|
35221
|
+
}
|
|
35222
|
+
function cleanupHeaderCellStructure(container) {
|
|
35223
|
+
const allHeaderCells = container.querySelectorAll("th");
|
|
35224
|
+
allHeaderCells.forEach((th) => {
|
|
35225
|
+
const paragraphs = th.querySelectorAll("p");
|
|
35226
|
+
paragraphs.forEach((p2) => {
|
|
35227
|
+
const childNodes = Array.from(p2.childNodes);
|
|
35228
|
+
const hasOnlyBr = childNodes.filter(
|
|
35229
|
+
(node) => {
|
|
35230
|
+
var _a;
|
|
35231
|
+
return node.nodeType === Node.ELEMENT_NODE || ((_a = node.textContent) == null ? void 0 : _a.trim());
|
|
35232
|
+
}
|
|
35233
|
+
).length === 1 && p2.querySelector("br");
|
|
35234
|
+
if (hasOnlyBr) {
|
|
35235
|
+
const br = p2.querySelector("br");
|
|
35236
|
+
if (br)
|
|
35237
|
+
br.remove();
|
|
35238
|
+
}
|
|
35239
|
+
});
|
|
35240
|
+
});
|
|
35241
|
+
}
|
|
35242
|
+
function applyGenericSafeStyles(container) {
|
|
35243
|
+
const addStyle = (selector, styles) => {
|
|
35244
|
+
container.querySelectorAll(selector).forEach((el) => {
|
|
35245
|
+
el.style.cssText += "; " + styles;
|
|
35246
|
+
});
|
|
35247
|
+
};
|
|
35248
|
+
const fontReset = 'font-family: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif; font-size: 14px; line-height: 1.5;';
|
|
35249
|
+
addStyle("table, p, span, li, td, th, div, h1, h2, h3, h4, h5, h6", fontReset);
|
|
35250
|
+
addStyle("th p, td p", "margin: 0; padding: 0;");
|
|
35251
|
+
addStyle(
|
|
35252
|
+
"table",
|
|
35253
|
+
"border-collapse: collapse; width: 100%; max-width: 100%; margin: 20px 0;"
|
|
35254
|
+
);
|
|
35255
|
+
addStyle(
|
|
35256
|
+
"th, td",
|
|
35257
|
+
"border: 1px solid #dfe1e5; padding: 10px; vertical-align: middle; text-align: left;"
|
|
35258
|
+
);
|
|
35259
|
+
addStyle("th", "background-color: #f8f9fa; font-weight: 600;");
|
|
35260
|
+
addStyle("img", "max-width: 100%; height: auto; display: block;");
|
|
35261
|
+
addStyle("h1", "font-size: 2em; font-weight: bold; margin: 0.67em 0;");
|
|
35262
|
+
addStyle("h2", "font-size: 1.5em; font-weight: bold; margin: 0.75em 0;");
|
|
35263
|
+
addStyle("h3", "font-size: 1.17em; font-weight: bold; margin: 0.83em 0;");
|
|
35264
|
+
addStyle("h4", "font-size: 1em; font-weight: bold; margin: 1.12em 0;");
|
|
35265
|
+
addStyle("h5", "font-size: 0.83em; font-weight: bold; margin: 1.5em 0;");
|
|
35266
|
+
addStyle("h6", "font-size: 0.75em; font-weight: bold; margin: 1.67em 0;");
|
|
35267
|
+
addStyle("ul, ol", "margin: 1em 0; padding-left: 40px;");
|
|
35268
|
+
addStyle("li", "margin: 0.5em 0;");
|
|
35269
|
+
addStyle("a", "color: #0066cc; text-decoration: underline;");
|
|
35270
|
+
addStyle(
|
|
35271
|
+
"code",
|
|
35272
|
+
'font-family: "Courier New", Courier, monospace; background-color: #f5f5f5; padding: 2px 4px; border-radius: 3px;'
|
|
35273
|
+
);
|
|
35274
|
+
addStyle(
|
|
35275
|
+
"pre",
|
|
35276
|
+
'font-family: "Courier New", Courier, monospace; background-color: #f5f5f5; padding: 10px; border-radius: 5px; overflow-x: auto; margin: 1em 0;'
|
|
35277
|
+
);
|
|
35278
|
+
addStyle(
|
|
35279
|
+
"blockquote",
|
|
35280
|
+
"border-left: 4px solid #ddd; margin: 1em 0; padding-left: 1em; color: #666;"
|
|
35281
|
+
);
|
|
35282
|
+
addStyle("strong, b", "font-weight: bold;");
|
|
35283
|
+
addStyle("em, i", "font-style: italic;");
|
|
35284
|
+
addStyle("hr", "border: none; border-top: 1px solid #ddd; margin: 1em 0;");
|
|
35285
|
+
}
|
|
35286
|
+
function cleanupClasses(container) {
|
|
35287
|
+
const classesToRemove = [
|
|
35288
|
+
"PlaygroundEditorTheme__",
|
|
35289
|
+
"editor-",
|
|
35290
|
+
"cteditor-",
|
|
35291
|
+
"table-custom-odd-striping",
|
|
35292
|
+
"table-custom-even-striping",
|
|
35293
|
+
"has-header-row"
|
|
35294
|
+
];
|
|
35295
|
+
container.querySelectorAll("*").forEach((elem) => {
|
|
35296
|
+
const classList = Array.from(elem.classList);
|
|
35297
|
+
classList.forEach((className) => {
|
|
35298
|
+
if (classesToRemove.some((prefix) => className.startsWith(prefix))) {
|
|
35299
|
+
elem.classList.remove(className);
|
|
35300
|
+
}
|
|
35301
|
+
});
|
|
35302
|
+
if (elem.classList.length === 0)
|
|
35303
|
+
elem.removeAttribute("class");
|
|
35304
|
+
});
|
|
35305
|
+
}
|
|
35306
|
+
function getContrastColor(color) {
|
|
35307
|
+
if (color.includes("var("))
|
|
35308
|
+
return "#000000";
|
|
35309
|
+
let r2 = 0, g2 = 0, b2 = 0;
|
|
35310
|
+
if (color.startsWith("#")) {
|
|
35311
|
+
const hex = color.replace("#", "");
|
|
35312
|
+
r2 = parseInt(hex.length === 3 ? hex[0] + hex[0] : hex.substring(0, 2), 16);
|
|
35313
|
+
g2 = parseInt(hex.length === 3 ? hex[1] + hex[1] : hex.substring(2, 4), 16);
|
|
35314
|
+
b2 = parseInt(hex.length === 3 ? hex[2] + hex[2] : hex.substring(4, 6), 16);
|
|
35315
|
+
} else if (color.includes("rgb")) {
|
|
35316
|
+
const matches = color.match(/\d+/g);
|
|
35317
|
+
if (matches && matches.length >= 3) {
|
|
35318
|
+
r2 = parseInt(matches[0]);
|
|
35319
|
+
g2 = parseInt(matches[1]);
|
|
35320
|
+
b2 = parseInt(matches[2]);
|
|
35321
|
+
}
|
|
35322
|
+
} else {
|
|
35323
|
+
return "#000000";
|
|
35324
|
+
}
|
|
35325
|
+
const yiq = (r2 * 299 + g2 * 587 + b2 * 114) / 1e3;
|
|
35326
|
+
return yiq >= 128 ? "#000000" : "#FFFFFF";
|
|
35327
|
+
}
|
|
35083
35328
|
const useAutoExpandingHeight = ({
|
|
35084
35329
|
minHeight = 150,
|
|
35085
35330
|
maxHeight = 800,
|
|
@@ -35177,23 +35422,30 @@ const CombinedPluginWrapper = () => {
|
|
|
35177
35422
|
if (!toolbarState.isAutocompleteEnabled || !toolbarState.isGrammarCheckEnabled) {
|
|
35178
35423
|
return null;
|
|
35179
35424
|
}
|
|
35180
|
-
return /* @__PURE__ */ jsx(
|
|
35425
|
+
return /* @__PURE__ */ jsx(
|
|
35426
|
+
CombinedAutocompleteGrammarPlugin,
|
|
35427
|
+
{
|
|
35428
|
+
minMatchLength: 2,
|
|
35429
|
+
maxSuggestions: 10,
|
|
35430
|
+
enableAI: (toolbarState == null ? void 0 : toolbarState.isAutocompleteEnabled) ?? true
|
|
35431
|
+
}
|
|
35432
|
+
);
|
|
35181
35433
|
};
|
|
35182
|
-
const OnChangeWrapper = ({
|
|
35434
|
+
const OnChangeWrapper = ({
|
|
35435
|
+
onChange
|
|
35436
|
+
}) => {
|
|
35183
35437
|
const [editor] = useLexicalComposerContext();
|
|
35184
|
-
const handleChange = (
|
|
35185
|
-
|
|
35186
|
-
|
|
35187
|
-
|
|
35188
|
-
|
|
35189
|
-
const htmlContent = $generateHtmlFromNodes(editor, null);
|
|
35190
|
-
onChange(htmlContent);
|
|
35191
|
-
}
|
|
35192
|
-
});
|
|
35438
|
+
const handleChange = () => {
|
|
35439
|
+
const exportReady = exportEditorWithStriping(editor);
|
|
35440
|
+
if (onChange) {
|
|
35441
|
+
onChange(exportReady);
|
|
35442
|
+
}
|
|
35193
35443
|
};
|
|
35194
35444
|
return /* @__PURE__ */ jsx(OnChangePlugin, { onChange: handleChange });
|
|
35195
35445
|
};
|
|
35196
|
-
const InitialContentPlugin = ({
|
|
35446
|
+
const InitialContentPlugin = ({
|
|
35447
|
+
initialContent
|
|
35448
|
+
}) => {
|
|
35197
35449
|
const [editor] = useLexicalComposerContext();
|
|
35198
35450
|
useEffect$1(() => {
|
|
35199
35451
|
if (!initialContent)
|
|
@@ -35223,7 +35475,9 @@ const CellBackgroundPersistencePlugin = () => {
|
|
|
35223
35475
|
const cells = tableElement.querySelectorAll("td, th");
|
|
35224
35476
|
cells.forEach((cell) => {
|
|
35225
35477
|
const htmlCell = cell;
|
|
35226
|
-
const cellKey = Object.keys(htmlCell).find(
|
|
35478
|
+
const cellKey = Object.keys(htmlCell).find(
|
|
35479
|
+
(key) => key.startsWith("__reactProps")
|
|
35480
|
+
) ? htmlCell["__lexicalKey"] : void 0;
|
|
35227
35481
|
if (!cellKey)
|
|
35228
35482
|
return;
|
|
35229
35483
|
try {
|
|
@@ -35237,9 +35491,17 @@ const CellBackgroundPersistencePlugin = () => {
|
|
|
35237
35491
|
const b2 = parseInt(hex.substr(4, 2), 16);
|
|
35238
35492
|
const luminance = (0.299 * r2 + 0.587 * g2 + 0.114 * b2) / 255;
|
|
35239
35493
|
const textColor = luminance > 0.5 ? "#000000" : "#FFFFFF";
|
|
35240
|
-
htmlCell.style.setProperty(
|
|
35494
|
+
htmlCell.style.setProperty(
|
|
35495
|
+
"background-color",
|
|
35496
|
+
bgColor,
|
|
35497
|
+
"important"
|
|
35498
|
+
);
|
|
35241
35499
|
htmlCell.style.setProperty("color", textColor, "important");
|
|
35242
|
-
htmlCell.style.setProperty(
|
|
35500
|
+
htmlCell.style.setProperty(
|
|
35501
|
+
"border-color",
|
|
35502
|
+
"#bbb",
|
|
35503
|
+
"important"
|
|
35504
|
+
);
|
|
35243
35505
|
const nestedElements = htmlCell.querySelectorAll("*");
|
|
35244
35506
|
nestedElements.forEach((elem) => {
|
|
35245
35507
|
if (elem instanceof HTMLElement) {
|
|
@@ -35248,7 +35510,11 @@ const CellBackgroundPersistencePlugin = () => {
|
|
|
35248
35510
|
});
|
|
35249
35511
|
const hasHeaderStyles = cellNode.getHeaderStyles();
|
|
35250
35512
|
if (hasHeaderStyles) {
|
|
35251
|
-
htmlCell.style.setProperty(
|
|
35513
|
+
htmlCell.style.setProperty(
|
|
35514
|
+
"font-weight",
|
|
35515
|
+
"600",
|
|
35516
|
+
"important"
|
|
35517
|
+
);
|
|
35252
35518
|
}
|
|
35253
35519
|
}
|
|
35254
35520
|
}
|
|
@@ -35422,7 +35688,12 @@ const ConfigurableEditor = ({
|
|
|
35422
35688
|
features: config.floatingMenuOptions
|
|
35423
35689
|
}
|
|
35424
35690
|
),
|
|
35425
|
-
/* @__PURE__ */ jsx(
|
|
35691
|
+
/* @__PURE__ */ jsx(
|
|
35692
|
+
FloatingEnhanceButtonPlugin,
|
|
35693
|
+
{
|
|
35694
|
+
anchorElem: floatingAnchorElem
|
|
35695
|
+
}
|
|
35696
|
+
)
|
|
35426
35697
|
] })
|
|
35427
35698
|
] }) }),
|
|
35428
35699
|
/* @__PURE__ */ jsx(
|
|
@@ -35590,4 +35861,4 @@ export {
|
|
|
35590
35861
|
useHtmlView as u,
|
|
35591
35862
|
verifyApiKey as v
|
|
35592
35863
|
};
|
|
35593
|
-
//# sourceMappingURL=index-
|
|
35864
|
+
//# sourceMappingURL=index-38cb7602.js.map
|