@underverse-ui/underverse 0.2.76 → 0.2.78

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/index.js CHANGED
@@ -3066,7 +3066,7 @@ var Tooltip = ({
3066
3066
  children,
3067
3067
  content,
3068
3068
  placement = "top",
3069
- delay = { open: 700, close: 300 },
3069
+ delay = { open: 200, close: 300 },
3070
3070
  className,
3071
3071
  disabled = false,
3072
3072
  variant = "default"
@@ -15131,6 +15131,1577 @@ function useSmartLocale() {
15131
15131
  }
15132
15132
  }
15133
15133
 
15134
+ // ../../components/ui/UEditor/UEditor.tsx
15135
+ import { useEffect as useEffect27, useMemo as useMemo16 } from "react";
15136
+ import { useTranslations as useTranslations7 } from "next-intl";
15137
+ import { useEditor, EditorContent } from "@tiptap/react";
15138
+
15139
+ // ../../components/ui/UEditor/extensions.ts
15140
+ import Document from "@tiptap/extension-document";
15141
+ import Paragraph from "@tiptap/extension-paragraph";
15142
+ import Text from "@tiptap/extension-text";
15143
+ import Bold from "@tiptap/extension-bold";
15144
+ import Italic from "@tiptap/extension-italic";
15145
+ import Strike from "@tiptap/extension-strike";
15146
+ import Underline from "@tiptap/extension-underline";
15147
+ import Heading from "@tiptap/extension-heading";
15148
+ import BulletList from "@tiptap/extension-bullet-list";
15149
+ import OrderedList from "@tiptap/extension-ordered-list";
15150
+ import ListItem2 from "@tiptap/extension-list-item";
15151
+ import TaskList from "@tiptap/extension-task-list";
15152
+ import TaskItem from "@tiptap/extension-task-item";
15153
+ import Blockquote from "@tiptap/extension-blockquote";
15154
+ import Code from "@tiptap/extension-code";
15155
+ import CodeBlockLowlight from "@tiptap/extension-code-block-lowlight";
15156
+ import History2 from "@tiptap/extension-history";
15157
+ import Placeholder from "@tiptap/extension-placeholder";
15158
+ import Link3 from "@tiptap/extension-link";
15159
+ import Image3 from "@tiptap/extension-image";
15160
+ import { TextStyle } from "@tiptap/extension-text-style";
15161
+ import Color from "@tiptap/extension-color";
15162
+ import Highlight from "@tiptap/extension-highlight";
15163
+ import TextAlign from "@tiptap/extension-text-align";
15164
+ import { Table as Table3 } from "@tiptap/extension-table";
15165
+ import TableRow2 from "@tiptap/extension-table-row";
15166
+ import TableCell2 from "@tiptap/extension-table-cell";
15167
+ import TableHeader2 from "@tiptap/extension-table-header";
15168
+ import CharacterCount from "@tiptap/extension-character-count";
15169
+ import Typography from "@tiptap/extension-typography";
15170
+ import Subscript from "@tiptap/extension-subscript";
15171
+ import Superscript from "@tiptap/extension-superscript";
15172
+ import HorizontalRule from "@tiptap/extension-horizontal-rule";
15173
+ import { common, createLowlight } from "lowlight";
15174
+
15175
+ // ../../components/ui/UEditor/slash-command.tsx
15176
+ import { Extension } from "@tiptap/core";
15177
+ import Suggestion from "@tiptap/suggestion";
15178
+ import { ReactRenderer } from "@tiptap/react";
15179
+ import { forwardRef as forwardRef13, useEffect as useEffect24, useImperativeHandle, useRef as useRef21, useState as useState42 } from "react";
15180
+ import {
15181
+ FileCode,
15182
+ Heading1,
15183
+ Heading2,
15184
+ Heading3,
15185
+ List as List2,
15186
+ ListOrdered,
15187
+ ListTodo,
15188
+ Minus,
15189
+ Quote,
15190
+ Table as Table2,
15191
+ Type
15192
+ } from "lucide-react";
15193
+ import tippy from "tippy.js";
15194
+ import { jsx as jsx68, jsxs as jsxs60 } from "react/jsx-runtime";
15195
+ var CommandList = forwardRef13((props, ref) => {
15196
+ const [selectedIndex, setSelectedIndex] = useState42(0);
15197
+ const listRef = useRef21(null);
15198
+ useEffect24(() => {
15199
+ setSelectedIndex(0);
15200
+ }, [props.items]);
15201
+ useEffect24(() => {
15202
+ const selectedElement = listRef.current?.querySelector(`[data-index="${selectedIndex}"]`);
15203
+ selectedElement?.scrollIntoView({ block: "nearest" });
15204
+ }, [selectedIndex, props.items]);
15205
+ useImperativeHandle(ref, () => ({
15206
+ onKeyDown: ({ event }) => {
15207
+ if (event.key === "ArrowUp") {
15208
+ setSelectedIndex((prev) => (prev + props.items.length - 1) % props.items.length);
15209
+ return true;
15210
+ }
15211
+ if (event.key === "ArrowDown") {
15212
+ setSelectedIndex((prev) => (prev + 1) % props.items.length);
15213
+ return true;
15214
+ }
15215
+ if (event.key === "Enter") {
15216
+ const item = props.items[selectedIndex];
15217
+ if (item) {
15218
+ props.command(item);
15219
+ }
15220
+ return true;
15221
+ }
15222
+ return false;
15223
+ }
15224
+ }));
15225
+ if (props.items.length === 0) {
15226
+ return /* @__PURE__ */ jsx68("div", { className: "w-72 p-4 text-center text-sm text-muted-foreground", children: "No results" });
15227
+ }
15228
+ return /* @__PURE__ */ jsxs60("div", { ref: listRef, className: "w-72 max-h-80 overflow-y-auto bg-card border border-border rounded-2xl shadow-lg", children: [
15229
+ /* @__PURE__ */ jsx68("div", { className: "px-3 py-2 border-b", children: /* @__PURE__ */ jsx68("span", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: "Basic Blocks" }) }),
15230
+ /* @__PURE__ */ jsx68("div", { className: "p-1", children: props.items.map((item, index) => /* @__PURE__ */ jsxs60(
15231
+ "button",
15232
+ {
15233
+ type: "button",
15234
+ "data-index": index,
15235
+ onClick: () => props.command(item),
15236
+ className: cn(
15237
+ "flex items-center w-full px-3 py-2.5 rounded-lg transition-colors group",
15238
+ selectedIndex === index ? "bg-accent" : "hover:bg-accent/50"
15239
+ ),
15240
+ children: [
15241
+ /* @__PURE__ */ jsx68(
15242
+ "div",
15243
+ {
15244
+ className: cn(
15245
+ "flex items-center justify-center w-10 h-10 rounded-lg mr-3 transition-colors",
15246
+ selectedIndex === index ? "bg-primary/10" : "bg-muted/50 group-hover:bg-muted"
15247
+ ),
15248
+ children: /* @__PURE__ */ jsx68(item.icon, { className: cn("w-5 h-5", selectedIndex === index ? "text-primary" : "text-muted-foreground") })
15249
+ }
15250
+ ),
15251
+ /* @__PURE__ */ jsxs60("div", { className: "text-left", children: [
15252
+ /* @__PURE__ */ jsx68("div", { className: cn("text-sm font-medium", selectedIndex === index && "text-primary"), children: item.title }),
15253
+ /* @__PURE__ */ jsx68("div", { className: "text-xs text-muted-foreground", children: item.description })
15254
+ ] })
15255
+ ]
15256
+ },
15257
+ item.title
15258
+ )) })
15259
+ ] });
15260
+ });
15261
+ CommandList.displayName = "CommandList";
15262
+ var getSuggestionItems = ({ query }) => {
15263
+ return [
15264
+ {
15265
+ icon: Type,
15266
+ title: "Text",
15267
+ description: "Start writing with plain text",
15268
+ command: ({ editor, range }) => {
15269
+ editor.chain().focus().deleteRange(range).setParagraph().run();
15270
+ }
15271
+ },
15272
+ {
15273
+ icon: Heading1,
15274
+ title: "Heading 1",
15275
+ description: "Large section heading",
15276
+ command: ({ editor, range }) => {
15277
+ editor.chain().focus().deleteRange(range).setNode("heading", { level: 1 }).run();
15278
+ }
15279
+ },
15280
+ {
15281
+ icon: Heading2,
15282
+ title: "Heading 2",
15283
+ description: "Medium section heading",
15284
+ command: ({ editor, range }) => {
15285
+ editor.chain().focus().deleteRange(range).setNode("heading", { level: 2 }).run();
15286
+ }
15287
+ },
15288
+ {
15289
+ icon: Heading3,
15290
+ title: "Heading 3",
15291
+ description: "Small section heading",
15292
+ command: ({ editor, range }) => {
15293
+ editor.chain().focus().deleteRange(range).setNode("heading", { level: 3 }).run();
15294
+ }
15295
+ },
15296
+ {
15297
+ icon: List2,
15298
+ title: "Bullet List",
15299
+ description: "Create a simple bullet list",
15300
+ command: ({ editor, range }) => {
15301
+ editor.chain().focus().deleteRange(range).toggleBulletList().run();
15302
+ }
15303
+ },
15304
+ {
15305
+ icon: ListOrdered,
15306
+ title: "Numbered List",
15307
+ description: "Create a list with numbering",
15308
+ command: ({ editor, range }) => {
15309
+ editor.chain().focus().deleteRange(range).toggleOrderedList().run();
15310
+ }
15311
+ },
15312
+ {
15313
+ icon: ListTodo,
15314
+ title: "Todo List",
15315
+ description: "Track tasks with a todo list",
15316
+ command: ({ editor, range }) => {
15317
+ editor.chain().focus().deleteRange(range).toggleTaskList().run();
15318
+ }
15319
+ },
15320
+ {
15321
+ icon: Quote,
15322
+ title: "Quote",
15323
+ description: "Capture a quote",
15324
+ command: ({ editor, range }) => {
15325
+ editor.chain().focus().deleteRange(range).toggleBlockquote().run();
15326
+ }
15327
+ },
15328
+ {
15329
+ icon: FileCode,
15330
+ title: "Code Block",
15331
+ description: "Display code with syntax highlighting",
15332
+ command: ({ editor, range }) => {
15333
+ editor.chain().focus().deleteRange(range).toggleCodeBlock().run();
15334
+ }
15335
+ },
15336
+ {
15337
+ icon: Minus,
15338
+ title: "Divider",
15339
+ description: "Visually divide blocks",
15340
+ command: ({ editor, range }) => {
15341
+ editor.chain().focus().deleteRange(range).setHorizontalRule().run();
15342
+ }
15343
+ },
15344
+ {
15345
+ icon: Table2,
15346
+ title: "Table",
15347
+ description: "Insert a table",
15348
+ command: ({ editor, range }) => {
15349
+ editor.chain().focus().deleteRange(range).insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run();
15350
+ }
15351
+ }
15352
+ ].filter((item) => item.title.toLowerCase().includes(query.toLowerCase()));
15353
+ };
15354
+ var SlashCommand = Extension.create({
15355
+ name: "slashCommand",
15356
+ addProseMirrorPlugins() {
15357
+ return [
15358
+ Suggestion({
15359
+ editor: this.editor,
15360
+ char: "/",
15361
+ command: ({ editor, range, props }) => {
15362
+ props.command({ editor, range });
15363
+ },
15364
+ items: getSuggestionItems,
15365
+ render: () => {
15366
+ let component;
15367
+ let popup;
15368
+ return {
15369
+ onStart: (props) => {
15370
+ component = new ReactRenderer(CommandList, {
15371
+ props,
15372
+ editor: props.editor
15373
+ });
15374
+ if (!props.clientRect) {
15375
+ return;
15376
+ }
15377
+ popup = tippy("body", {
15378
+ getReferenceClientRect: props.clientRect,
15379
+ appendTo: () => document.body,
15380
+ content: component.element,
15381
+ showOnCreate: true,
15382
+ interactive: true,
15383
+ trigger: "manual",
15384
+ placement: "bottom-start"
15385
+ });
15386
+ },
15387
+ onUpdate(props) {
15388
+ component?.updateProps(props);
15389
+ if (!props.clientRect) {
15390
+ return;
15391
+ }
15392
+ popup?.[0]?.setProps({
15393
+ getReferenceClientRect: props.clientRect
15394
+ });
15395
+ },
15396
+ onKeyDown(props) {
15397
+ if (props.event.key === "Escape") {
15398
+ popup?.[0]?.hide();
15399
+ return true;
15400
+ }
15401
+ return component?.ref?.onKeyDown(props) ?? false;
15402
+ },
15403
+ onExit() {
15404
+ popup?.[0]?.destroy();
15405
+ component?.destroy();
15406
+ }
15407
+ };
15408
+ }
15409
+ })
15410
+ ];
15411
+ }
15412
+ });
15413
+
15414
+ // ../../components/ui/UEditor/extensions.ts
15415
+ var lowlight = createLowlight(common);
15416
+ function buildUEditorExtensions({ placeholder, maxCharacters }) {
15417
+ return [
15418
+ Document,
15419
+ Paragraph,
15420
+ Text,
15421
+ Bold,
15422
+ Italic,
15423
+ Strike,
15424
+ Underline,
15425
+ Subscript,
15426
+ Superscript,
15427
+ Heading.configure({
15428
+ levels: [1, 2, 3]
15429
+ }),
15430
+ BulletList.configure({
15431
+ HTMLAttributes: {
15432
+ class: "list-disc pl-6 my-2 space-y-1"
15433
+ }
15434
+ }),
15435
+ OrderedList.configure({
15436
+ HTMLAttributes: {
15437
+ class: "list-decimal pl-6 my-2 space-y-1"
15438
+ }
15439
+ }),
15440
+ ListItem2.configure({
15441
+ HTMLAttributes: {
15442
+ class: "pl-1"
15443
+ }
15444
+ }),
15445
+ TaskList,
15446
+ TaskItem.configure({
15447
+ nested: true
15448
+ }),
15449
+ Blockquote.configure({
15450
+ HTMLAttributes: {
15451
+ class: "border-l-4 border-primary pl-4 py-2 my-4 bg-muted/30 rounded-r-lg italic text-muted-foreground"
15452
+ }
15453
+ }),
15454
+ Code.configure({
15455
+ HTMLAttributes: {
15456
+ class: "px-1.5 py-0.5 rounded bg-muted font-mono text-sm"
15457
+ }
15458
+ }),
15459
+ CodeBlockLowlight.configure({
15460
+ lowlight,
15461
+ HTMLAttributes: {
15462
+ class: "rounded-lg bg-[#1e1e1e] p-4 font-mono text-sm overflow-x-auto"
15463
+ }
15464
+ }),
15465
+ HorizontalRule,
15466
+ Link3.configure({
15467
+ openOnClick: false,
15468
+ HTMLAttributes: {
15469
+ class: "text-primary underline underline-offset-2 hover:text-primary/80 cursor-pointer"
15470
+ }
15471
+ }),
15472
+ Image3.configure({
15473
+ HTMLAttributes: {
15474
+ class: "rounded-lg max-w-full h-auto my-4"
15475
+ }
15476
+ }),
15477
+ TextStyle,
15478
+ Color,
15479
+ Highlight.configure({
15480
+ multicolor: true
15481
+ }),
15482
+ TextAlign.configure({
15483
+ types: ["heading", "paragraph"]
15484
+ }),
15485
+ Table3.configure({
15486
+ resizable: true,
15487
+ HTMLAttributes: {
15488
+ class: "border-collapse w-full my-4"
15489
+ }
15490
+ }),
15491
+ TableRow2,
15492
+ TableCell2.configure({
15493
+ HTMLAttributes: {
15494
+ class: "border border-border p-2 min-w-[100px]"
15495
+ }
15496
+ }),
15497
+ TableHeader2.configure({
15498
+ HTMLAttributes: {
15499
+ class: "border border-border p-2 bg-muted font-semibold min-w-[100px]"
15500
+ }
15501
+ }),
15502
+ CharacterCount.configure({
15503
+ limit: maxCharacters
15504
+ }),
15505
+ Typography,
15506
+ History2,
15507
+ Placeholder.configure({
15508
+ placeholder,
15509
+ emptyEditorClass: "is-editor-empty",
15510
+ emptyNodeClass: "is-empty"
15511
+ }),
15512
+ SlashCommand
15513
+ ];
15514
+ }
15515
+
15516
+ // ../../components/ui/UEditor/toolbar.tsx
15517
+ import React59, { useState as useState44 } from "react";
15518
+ import { useTranslations as useTranslations4 } from "next-intl";
15519
+ import {
15520
+ AlignCenter,
15521
+ AlignJustify,
15522
+ AlignLeft,
15523
+ AlignRight,
15524
+ ArrowDown,
15525
+ ArrowRight,
15526
+ Bold as BoldIcon,
15527
+ ChevronDown as ChevronDown5,
15528
+ Code as CodeIcon,
15529
+ FileCode as FileCode2,
15530
+ Heading1 as Heading1Icon,
15531
+ Heading2 as Heading2Icon,
15532
+ Heading3 as Heading3Icon,
15533
+ Highlighter,
15534
+ Image as ImageIcon2,
15535
+ Italic as ItalicIcon,
15536
+ Link as LinkIcon,
15537
+ List as ListIcon,
15538
+ ListOrdered as ListOrderedIcon,
15539
+ ListTodo as ListTodo2,
15540
+ Palette as Palette2,
15541
+ Quote as QuoteIcon,
15542
+ Redo as RedoIcon,
15543
+ Strikethrough as StrikethroughIcon,
15544
+ Subscript as SubscriptIcon,
15545
+ Superscript as SuperscriptIcon,
15546
+ Table as TableIcon,
15547
+ Trash2,
15548
+ Type as Type2,
15549
+ Underline as UnderlineIcon,
15550
+ Undo as UndoIcon
15551
+ } from "lucide-react";
15552
+
15553
+ // ../../components/ui/UEditor/colors.tsx
15554
+ import { useMemo as useMemo14 } from "react";
15555
+ import { useTranslations as useTranslations2 } from "next-intl";
15556
+ import { X as X14 } from "lucide-react";
15557
+ import { jsx as jsx69, jsxs as jsxs61 } from "react/jsx-runtime";
15558
+ var useEditorColors = () => {
15559
+ const t = useTranslations2("UEditor");
15560
+ const textColors = useMemo14(
15561
+ () => [
15562
+ { name: t("colors.default"), color: "inherit", cssClass: "text-foreground" },
15563
+ { name: t("colors.muted"), color: "var(--muted-foreground)", cssClass: "text-muted-foreground" },
15564
+ { name: t("colors.primary"), color: "var(--primary)", cssClass: "text-primary" },
15565
+ { name: t("colors.secondary"), color: "var(--secondary)", cssClass: "text-secondary" },
15566
+ { name: t("colors.success"), color: "var(--success)", cssClass: "text-success" },
15567
+ { name: t("colors.warning"), color: "var(--warning)", cssClass: "text-warning" },
15568
+ { name: t("colors.destructive"), color: "var(--destructive)", cssClass: "text-destructive" },
15569
+ { name: t("colors.info"), color: "var(--info)", cssClass: "text-info" }
15570
+ ],
15571
+ [t]
15572
+ );
15573
+ const highlightColors = useMemo14(
15574
+ () => [
15575
+ { name: t("colors.default"), color: "", cssClass: "" },
15576
+ { name: t("colors.muted"), color: "var(--muted)", cssClass: "bg-muted" },
15577
+ { name: t("colors.primary"), color: "color-mix(in oklch, var(--primary) 20%, transparent)", cssClass: "bg-primary/20" },
15578
+ { name: t("colors.secondary"), color: "color-mix(in oklch, var(--secondary) 20%, transparent)", cssClass: "bg-secondary/20" },
15579
+ { name: t("colors.success"), color: "color-mix(in oklch, var(--success) 20%, transparent)", cssClass: "bg-success/20" },
15580
+ { name: t("colors.warning"), color: "color-mix(in oklch, var(--warning) 20%, transparent)", cssClass: "bg-warning/20" },
15581
+ { name: t("colors.destructive"), color: "color-mix(in oklch, var(--destructive) 20%, transparent)", cssClass: "bg-destructive/20" },
15582
+ { name: t("colors.info"), color: "color-mix(in oklch, var(--info) 20%, transparent)", cssClass: "bg-info/20" },
15583
+ { name: t("colors.accent"), color: "var(--accent)", cssClass: "bg-accent" }
15584
+ ],
15585
+ [t]
15586
+ );
15587
+ return { textColors, highlightColors };
15588
+ };
15589
+ var EditorColorPalette = ({
15590
+ colors,
15591
+ currentColor,
15592
+ onSelect,
15593
+ label
15594
+ }) => /* @__PURE__ */ jsxs61("div", { className: "p-2", children: [
15595
+ /* @__PURE__ */ jsx69("span", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wider px-2", children: label }),
15596
+ /* @__PURE__ */ jsx69("div", { className: "grid grid-cols-4 gap-1.5 mt-2", children: colors.map((c) => /* @__PURE__ */ jsxs61(
15597
+ "button",
15598
+ {
15599
+ type: "button",
15600
+ onMouseDown: (e) => e.preventDefault(),
15601
+ onClick: () => onSelect(c.color),
15602
+ className: cn(
15603
+ "flex items-center justify-center w-9 h-9 rounded-lg border-2 transition-all hover:scale-105",
15604
+ currentColor === c.color ? "border-primary ring-2 ring-primary/20" : "border-border/50 hover:border-primary/50"
15605
+ ),
15606
+ style: { backgroundColor: c.color || "transparent" },
15607
+ title: c.name,
15608
+ children: [
15609
+ c.color === "" && /* @__PURE__ */ jsx69(X14, { className: "w-4 h-4 text-muted-foreground" }),
15610
+ c.color === "inherit" && /* @__PURE__ */ jsx69("span", { className: "text-xs font-medium", children: "A" })
15611
+ ]
15612
+ },
15613
+ c.name
15614
+ )) })
15615
+ ] });
15616
+
15617
+ // ../../components/ui/UEditor/inputs.tsx
15618
+ import { useEffect as useEffect25, useRef as useRef22, useState as useState43 } from "react";
15619
+ import { useTranslations as useTranslations3 } from "next-intl";
15620
+ import { Check as Check9, X as X15 } from "lucide-react";
15621
+ import { jsx as jsx70, jsxs as jsxs62 } from "react/jsx-runtime";
15622
+ var LinkInput = ({
15623
+ onSubmit,
15624
+ onCancel,
15625
+ initialUrl = ""
15626
+ }) => {
15627
+ const t = useTranslations3("UEditor");
15628
+ const [url, setUrl] = useState43(initialUrl);
15629
+ const inputRef = useRef22(null);
15630
+ useEffect25(() => {
15631
+ inputRef.current?.focus();
15632
+ inputRef.current?.select();
15633
+ }, []);
15634
+ const handleSubmit = (e) => {
15635
+ e.preventDefault();
15636
+ if (url) {
15637
+ onSubmit(url.startsWith("http") ? url : `https://${url}`);
15638
+ }
15639
+ };
15640
+ return /* @__PURE__ */ jsxs62("form", { onSubmit: handleSubmit, className: "flex items-center gap-2 p-2", children: [
15641
+ /* @__PURE__ */ jsx70(
15642
+ "input",
15643
+ {
15644
+ ref: inputRef,
15645
+ type: "text",
15646
+ value: url,
15647
+ onChange: (e) => setUrl(e.target.value),
15648
+ placeholder: t("linkInput.placeholder"),
15649
+ className: "flex-1 px-3 py-2 text-sm bg-muted/50 border-0 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary/20"
15650
+ }
15651
+ ),
15652
+ /* @__PURE__ */ jsx70("button", { type: "submit", className: "p-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 transition-colors", children: /* @__PURE__ */ jsx70(Check9, { className: "w-4 h-4" }) }),
15653
+ /* @__PURE__ */ jsx70("button", { type: "button", onClick: onCancel, className: "p-2 rounded-lg hover:bg-muted transition-colors text-muted-foreground", children: /* @__PURE__ */ jsx70(X15, { className: "w-4 h-4" }) })
15654
+ ] });
15655
+ };
15656
+ var ImageInput = ({ onSubmit, onCancel }) => {
15657
+ const t = useTranslations3("UEditor");
15658
+ const [url, setUrl] = useState43("");
15659
+ const [alt, setAlt] = useState43("");
15660
+ const inputRef = useRef22(null);
15661
+ useEffect25(() => {
15662
+ inputRef.current?.focus();
15663
+ }, []);
15664
+ const handleSubmit = (e) => {
15665
+ e.preventDefault();
15666
+ if (url) {
15667
+ onSubmit(url, alt);
15668
+ }
15669
+ };
15670
+ return /* @__PURE__ */ jsxs62("form", { onSubmit: handleSubmit, className: "p-3 space-y-3", children: [
15671
+ /* @__PURE__ */ jsxs62("div", { children: [
15672
+ /* @__PURE__ */ jsx70("label", { className: "text-xs font-medium text-muted-foreground", children: t("imageInput.urlLabel") }),
15673
+ /* @__PURE__ */ jsx70(
15674
+ "input",
15675
+ {
15676
+ ref: inputRef,
15677
+ type: "text",
15678
+ value: url,
15679
+ onChange: (e) => setUrl(e.target.value),
15680
+ placeholder: t("imageInput.urlPlaceholder"),
15681
+ className: "w-full mt-1 px-3 py-2 text-sm bg-muted/50 border-0 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary/20"
15682
+ }
15683
+ )
15684
+ ] }),
15685
+ /* @__PURE__ */ jsxs62("div", { children: [
15686
+ /* @__PURE__ */ jsx70("label", { className: "text-xs font-medium text-muted-foreground", children: t("imageInput.altLabel") }),
15687
+ /* @__PURE__ */ jsx70(
15688
+ "input",
15689
+ {
15690
+ type: "text",
15691
+ value: alt,
15692
+ onChange: (e) => setAlt(e.target.value),
15693
+ placeholder: t("imageInput.altPlaceholder"),
15694
+ className: "w-full mt-1 px-3 py-2 text-sm bg-muted/50 border-0 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary/20"
15695
+ }
15696
+ )
15697
+ ] }),
15698
+ /* @__PURE__ */ jsxs62("div", { className: "flex gap-2", children: [
15699
+ /* @__PURE__ */ jsx70(
15700
+ "button",
15701
+ {
15702
+ type: "submit",
15703
+ disabled: !url,
15704
+ className: "flex-1 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 transition-colors disabled:opacity-50",
15705
+ children: t("imageInput.addBtn")
15706
+ }
15707
+ ),
15708
+ /* @__PURE__ */ jsx70("button", { type: "button", onClick: onCancel, className: "px-4 py-2 rounded-lg hover:bg-muted transition-colors text-muted-foreground", children: t("imageInput.cancelBtn") })
15709
+ ] })
15710
+ ] });
15711
+ };
15712
+
15713
+ // ../../components/ui/UEditor/toolbar.tsx
15714
+ import { jsx as jsx71, jsxs as jsxs63 } from "react/jsx-runtime";
15715
+ var ToolbarButton = React59.forwardRef(({ onClick, active, disabled, children, title, className }, ref) => {
15716
+ const button = /* @__PURE__ */ jsx71(
15717
+ "button",
15718
+ {
15719
+ ref,
15720
+ type: "button",
15721
+ onMouseDown: (e) => e.preventDefault(),
15722
+ onClick,
15723
+ disabled,
15724
+ className: cn(
15725
+ "flex items-center justify-center w-8 h-8 rounded-lg transition-all duration-200",
15726
+ "hover:bg-accent hover:scale-105",
15727
+ "focus:outline-none focus:ring-2 focus:ring-primary/20",
15728
+ "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:scale-100",
15729
+ active ? "bg-primary/10 text-primary shadow-sm" : "text-muted-foreground hover:text-foreground",
15730
+ className
15731
+ ),
15732
+ children
15733
+ }
15734
+ );
15735
+ if (title) {
15736
+ return /* @__PURE__ */ jsx71(Tooltip, { content: title, placement: "top", delay: { open: 500, close: 0 }, children: button });
15737
+ }
15738
+ return button;
15739
+ });
15740
+ ToolbarButton.displayName = "ToolbarButton";
15741
+ var ToolbarDivider = () => /* @__PURE__ */ jsx71("div", { className: "w-px h-6 bg-border/50 mx-1" });
15742
+ var EditorToolbar = ({ editor, variant }) => {
15743
+ const t = useTranslations4("UEditor");
15744
+ const { textColors, highlightColors } = useEditorColors();
15745
+ const [showImageInput, setShowImageInput] = useState44(false);
15746
+ if (variant === "minimal") {
15747
+ return /* @__PURE__ */ jsxs63("div", { className: "flex items-center gap-1 p-2 border-b bg-muted/30", children: [
15748
+ /* @__PURE__ */ jsx71(ToolbarButton, { onClick: () => editor.chain().focus().toggleBold().run(), active: editor.isActive("bold"), title: t("toolbar.bold"), children: /* @__PURE__ */ jsx71(BoldIcon, { className: "w-4 h-4" }) }),
15749
+ /* @__PURE__ */ jsx71(
15750
+ ToolbarButton,
15751
+ {
15752
+ onClick: () => editor.chain().focus().toggleItalic().run(),
15753
+ active: editor.isActive("italic"),
15754
+ title: t("toolbar.italic"),
15755
+ children: /* @__PURE__ */ jsx71(ItalicIcon, { className: "w-4 h-4" })
15756
+ }
15757
+ ),
15758
+ /* @__PURE__ */ jsx71(
15759
+ ToolbarButton,
15760
+ {
15761
+ onClick: () => editor.chain().focus().toggleBulletList().run(),
15762
+ active: editor.isActive("bulletList"),
15763
+ title: t("toolbar.bulletList"),
15764
+ children: /* @__PURE__ */ jsx71(ListIcon, { className: "w-4 h-4" })
15765
+ }
15766
+ )
15767
+ ] });
15768
+ }
15769
+ return /* @__PURE__ */ jsxs63("div", { className: "flex flex-wrap items-center gap-1 p-2 border-b bg-linear-to-r from-muted/30 to-transparent", children: [
15770
+ /* @__PURE__ */ jsxs63(
15771
+ DropdownMenu,
15772
+ {
15773
+ trigger: /* @__PURE__ */ jsxs63(ToolbarButton, { onClick: () => {
15774
+ }, title: t("toolbar.textStyle"), className: "px-2 w-auto gap-1", children: [
15775
+ /* @__PURE__ */ jsx71(Type2, { className: "w-4 h-4" }),
15776
+ /* @__PURE__ */ jsx71(ChevronDown5, { className: "w-3 h-3" })
15777
+ ] }),
15778
+ children: [
15779
+ /* @__PURE__ */ jsx71(DropdownMenuItem, { icon: Type2, label: t("toolbar.normal"), onClick: () => editor.chain().focus().setParagraph().run(), active: editor.isActive("paragraph") }),
15780
+ /* @__PURE__ */ jsx71(
15781
+ DropdownMenuItem,
15782
+ {
15783
+ icon: Heading1Icon,
15784
+ label: t("toolbar.heading1"),
15785
+ onClick: () => editor.chain().focus().toggleHeading({ level: 1 }).run(),
15786
+ active: editor.isActive("heading", { level: 1 }),
15787
+ shortcut: "Ctrl+Alt+1"
15788
+ }
15789
+ ),
15790
+ /* @__PURE__ */ jsx71(
15791
+ DropdownMenuItem,
15792
+ {
15793
+ icon: Heading2Icon,
15794
+ label: t("toolbar.heading2"),
15795
+ onClick: () => editor.chain().focus().toggleHeading({ level: 2 }).run(),
15796
+ active: editor.isActive("heading", { level: 2 }),
15797
+ shortcut: "Ctrl+Alt+2"
15798
+ }
15799
+ ),
15800
+ /* @__PURE__ */ jsx71(
15801
+ DropdownMenuItem,
15802
+ {
15803
+ icon: Heading3Icon,
15804
+ label: t("toolbar.heading3"),
15805
+ onClick: () => editor.chain().focus().toggleHeading({ level: 3 }).run(),
15806
+ active: editor.isActive("heading", { level: 3 }),
15807
+ shortcut: "Ctrl+Alt+3"
15808
+ }
15809
+ )
15810
+ ]
15811
+ }
15812
+ ),
15813
+ /* @__PURE__ */ jsx71(ToolbarDivider, {}),
15814
+ /* @__PURE__ */ jsx71(ToolbarButton, { onClick: () => editor.chain().focus().toggleBold().run(), active: editor.isActive("bold"), title: t("toolbar.bold"), children: /* @__PURE__ */ jsx71(BoldIcon, { className: "w-4 h-4" }) }),
15815
+ /* @__PURE__ */ jsx71(
15816
+ ToolbarButton,
15817
+ {
15818
+ onClick: () => editor.chain().focus().toggleItalic().run(),
15819
+ active: editor.isActive("italic"),
15820
+ title: t("toolbar.italic"),
15821
+ children: /* @__PURE__ */ jsx71(ItalicIcon, { className: "w-4 h-4" })
15822
+ }
15823
+ ),
15824
+ /* @__PURE__ */ jsx71(
15825
+ ToolbarButton,
15826
+ {
15827
+ onClick: () => editor.chain().focus().toggleUnderline().run(),
15828
+ active: editor.isActive("underline"),
15829
+ title: t("toolbar.underline"),
15830
+ children: /* @__PURE__ */ jsx71(UnderlineIcon, { className: "w-4 h-4" })
15831
+ }
15832
+ ),
15833
+ /* @__PURE__ */ jsx71(
15834
+ ToolbarButton,
15835
+ {
15836
+ onClick: () => editor.chain().focus().toggleStrike().run(),
15837
+ active: editor.isActive("strike"),
15838
+ title: t("toolbar.strike"),
15839
+ children: /* @__PURE__ */ jsx71(StrikethroughIcon, { className: "w-4 h-4" })
15840
+ }
15841
+ ),
15842
+ /* @__PURE__ */ jsx71(ToolbarButton, { onClick: () => editor.chain().focus().toggleCode().run(), active: editor.isActive("code"), title: t("toolbar.code"), children: /* @__PURE__ */ jsx71(CodeIcon, { className: "w-4 h-4" }) }),
15843
+ /* @__PURE__ */ jsx71(ToolbarDivider, {}),
15844
+ /* @__PURE__ */ jsx71(
15845
+ DropdownMenu,
15846
+ {
15847
+ trigger: /* @__PURE__ */ jsxs63(ToolbarButton, { onClick: () => {
15848
+ }, title: t("colors.textColor"), children: [
15849
+ /* @__PURE__ */ jsx71(Palette2, { className: "w-4 h-4" }),
15850
+ /* @__PURE__ */ jsx71(ChevronDown5, { className: "w-3 h-3" })
15851
+ ] }),
15852
+ children: /* @__PURE__ */ jsx71(
15853
+ EditorColorPalette,
15854
+ {
15855
+ colors: textColors,
15856
+ currentColor: editor.getAttributes("textStyle").color || "inherit",
15857
+ onSelect: (color) => {
15858
+ if (color === "inherit") {
15859
+ editor.chain().focus().unsetColor().run();
15860
+ } else {
15861
+ editor.chain().focus().setColor(color).run();
15862
+ }
15863
+ },
15864
+ label: t("colors.textColor")
15865
+ }
15866
+ )
15867
+ }
15868
+ ),
15869
+ /* @__PURE__ */ jsx71(
15870
+ DropdownMenu,
15871
+ {
15872
+ trigger: /* @__PURE__ */ jsxs63(ToolbarButton, { onClick: () => {
15873
+ }, active: editor.isActive("highlight"), title: t("colors.highlight"), children: [
15874
+ /* @__PURE__ */ jsx71(Highlighter, { className: "w-4 h-4" }),
15875
+ /* @__PURE__ */ jsx71(ChevronDown5, { className: "w-3 h-3" })
15876
+ ] }),
15877
+ children: /* @__PURE__ */ jsx71(
15878
+ EditorColorPalette,
15879
+ {
15880
+ colors: highlightColors,
15881
+ currentColor: editor.getAttributes("highlight").color || "",
15882
+ onSelect: (color) => {
15883
+ if (color === "") {
15884
+ editor.chain().focus().unsetHighlight().run();
15885
+ } else {
15886
+ editor.chain().focus().toggleHighlight({ color }).run();
15887
+ }
15888
+ },
15889
+ label: t("colors.highlight")
15890
+ }
15891
+ )
15892
+ }
15893
+ ),
15894
+ /* @__PURE__ */ jsx71(ToolbarDivider, {}),
15895
+ /* @__PURE__ */ jsxs63(
15896
+ DropdownMenu,
15897
+ {
15898
+ trigger: /* @__PURE__ */ jsxs63(ToolbarButton, { onClick: () => {
15899
+ }, title: t("toolbar.alignment"), children: [
15900
+ /* @__PURE__ */ jsx71(AlignLeft, { className: "w-4 h-4" }),
15901
+ /* @__PURE__ */ jsx71(ChevronDown5, { className: "w-3 h-3" })
15902
+ ] }),
15903
+ children: [
15904
+ /* @__PURE__ */ jsx71(
15905
+ DropdownMenuItem,
15906
+ {
15907
+ icon: AlignLeft,
15908
+ label: t("toolbar.alignLeft"),
15909
+ onClick: () => editor.chain().focus().setTextAlign("left").run(),
15910
+ active: editor.isActive({ textAlign: "left" })
15911
+ }
15912
+ ),
15913
+ /* @__PURE__ */ jsx71(
15914
+ DropdownMenuItem,
15915
+ {
15916
+ icon: AlignCenter,
15917
+ label: t("toolbar.alignCenter"),
15918
+ onClick: () => editor.chain().focus().setTextAlign("center").run(),
15919
+ active: editor.isActive({ textAlign: "center" })
15920
+ }
15921
+ ),
15922
+ /* @__PURE__ */ jsx71(
15923
+ DropdownMenuItem,
15924
+ {
15925
+ icon: AlignRight,
15926
+ label: t("toolbar.alignRight"),
15927
+ onClick: () => editor.chain().focus().setTextAlign("right").run(),
15928
+ active: editor.isActive({ textAlign: "right" })
15929
+ }
15930
+ ),
15931
+ /* @__PURE__ */ jsx71(
15932
+ DropdownMenuItem,
15933
+ {
15934
+ icon: AlignJustify,
15935
+ label: t("toolbar.justify"),
15936
+ onClick: () => editor.chain().focus().setTextAlign("justify").run(),
15937
+ active: editor.isActive({ textAlign: "justify" })
15938
+ }
15939
+ )
15940
+ ]
15941
+ }
15942
+ ),
15943
+ /* @__PURE__ */ jsx71(ToolbarDivider, {}),
15944
+ /* @__PURE__ */ jsxs63(
15945
+ DropdownMenu,
15946
+ {
15947
+ trigger: /* @__PURE__ */ jsxs63(ToolbarButton, { onClick: () => {
15948
+ }, title: t("toolbar.bulletList"), children: [
15949
+ /* @__PURE__ */ jsx71(ListIcon, { className: "w-4 h-4" }),
15950
+ /* @__PURE__ */ jsx71(ChevronDown5, { className: "w-3 h-3" })
15951
+ ] }),
15952
+ children: [
15953
+ /* @__PURE__ */ jsx71(
15954
+ DropdownMenuItem,
15955
+ {
15956
+ icon: ListIcon,
15957
+ label: t("toolbar.bulletList"),
15958
+ onClick: () => editor.chain().focus().toggleBulletList().run(),
15959
+ active: editor.isActive("bulletList"),
15960
+ shortcut: "Ctrl+Shift+8"
15961
+ }
15962
+ ),
15963
+ /* @__PURE__ */ jsx71(
15964
+ DropdownMenuItem,
15965
+ {
15966
+ icon: ListOrderedIcon,
15967
+ label: t("toolbar.orderedList"),
15968
+ onClick: () => editor.chain().focus().toggleOrderedList().run(),
15969
+ active: editor.isActive("orderedList"),
15970
+ shortcut: "Ctrl+Shift+7"
15971
+ }
15972
+ ),
15973
+ /* @__PURE__ */ jsx71(
15974
+ DropdownMenuItem,
15975
+ {
15976
+ icon: ListTodo2,
15977
+ label: t("toolbar.taskList"),
15978
+ onClick: () => editor.chain().focus().toggleTaskList().run(),
15979
+ active: editor.isActive("taskList"),
15980
+ shortcut: "Ctrl+Shift+9"
15981
+ }
15982
+ )
15983
+ ]
15984
+ }
15985
+ ),
15986
+ /* @__PURE__ */ jsxs63(
15987
+ DropdownMenu,
15988
+ {
15989
+ trigger: /* @__PURE__ */ jsxs63(ToolbarButton, { onClick: () => {
15990
+ }, title: t("toolbar.quote"), children: [
15991
+ /* @__PURE__ */ jsx71(QuoteIcon, { className: "w-4 h-4" }),
15992
+ /* @__PURE__ */ jsx71(ChevronDown5, { className: "w-3 h-3" })
15993
+ ] }),
15994
+ children: [
15995
+ /* @__PURE__ */ jsx71(
15996
+ DropdownMenuItem,
15997
+ {
15998
+ icon: QuoteIcon,
15999
+ label: t("toolbar.quote"),
16000
+ onClick: () => editor.chain().focus().toggleBlockquote().run(),
16001
+ active: editor.isActive("blockquote"),
16002
+ shortcut: "Ctrl+Shift+B"
16003
+ }
16004
+ ),
16005
+ /* @__PURE__ */ jsx71(
16006
+ DropdownMenuItem,
16007
+ {
16008
+ icon: FileCode2,
16009
+ label: t("toolbar.codeBlock"),
16010
+ onClick: () => editor.chain().focus().toggleCodeBlock().run(),
16011
+ active: editor.isActive("codeBlock"),
16012
+ shortcut: "Ctrl+Alt+C"
16013
+ }
16014
+ )
16015
+ ]
16016
+ }
16017
+ ),
16018
+ /* @__PURE__ */ jsx71(
16019
+ DropdownMenu,
16020
+ {
16021
+ trigger: /* @__PURE__ */ jsxs63(ToolbarButton, { onClick: () => {
16022
+ }, title: t("toolbar.image"), children: [
16023
+ /* @__PURE__ */ jsx71(ImageIcon2, { className: "w-4 h-4" }),
16024
+ /* @__PURE__ */ jsx71(ChevronDown5, { className: "w-3 h-3" })
16025
+ ] }),
16026
+ children: showImageInput ? /* @__PURE__ */ jsx71(
16027
+ ImageInput,
16028
+ {
16029
+ onSubmit: (url, alt) => {
16030
+ editor.chain().focus().setImage({ src: url, alt }).run();
16031
+ setShowImageInput(false);
16032
+ },
16033
+ onCancel: () => setShowImageInput(false)
16034
+ }
16035
+ ) : /* @__PURE__ */ jsx71(DropdownMenuItem, { icon: LinkIcon, label: t("imageInput.addFromUrl"), onClick: () => setShowImageInput(true) })
16036
+ }
16037
+ ),
16038
+ /* @__PURE__ */ jsxs63(
16039
+ DropdownMenu,
16040
+ {
16041
+ trigger: /* @__PURE__ */ jsxs63(ToolbarButton, { onClick: () => {
16042
+ }, title: t("toolbar.table"), children: [
16043
+ /* @__PURE__ */ jsx71(TableIcon, { className: "w-4 h-4" }),
16044
+ /* @__PURE__ */ jsx71(ChevronDown5, { className: "w-3 h-3" })
16045
+ ] }),
16046
+ children: [
16047
+ /* @__PURE__ */ jsx71(DropdownMenuItem, { icon: TableIcon, label: t("tableMenu.insert3x3"), onClick: () => editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run() }),
16048
+ /* @__PURE__ */ jsx71("div", { className: "my-1 border-t" }),
16049
+ /* @__PURE__ */ jsx71(
16050
+ DropdownMenuItem,
16051
+ {
16052
+ icon: ArrowDown,
16053
+ label: t("tableMenu.addColumnBefore"),
16054
+ onClick: () => editor.chain().focus().addColumnBefore().run(),
16055
+ disabled: !editor.can().addColumnBefore()
16056
+ }
16057
+ ),
16058
+ /* @__PURE__ */ jsx71(
16059
+ DropdownMenuItem,
16060
+ {
16061
+ icon: ArrowDown,
16062
+ label: t("tableMenu.addColumnAfter"),
16063
+ onClick: () => editor.chain().focus().addColumnAfter().run(),
16064
+ disabled: !editor.can().addColumnAfter()
16065
+ }
16066
+ ),
16067
+ /* @__PURE__ */ jsx71(
16068
+ DropdownMenuItem,
16069
+ {
16070
+ icon: ArrowRight,
16071
+ label: t("tableMenu.addRowBefore"),
16072
+ onClick: () => editor.chain().focus().addRowBefore().run(),
16073
+ disabled: !editor.can().addRowBefore()
16074
+ }
16075
+ ),
16076
+ /* @__PURE__ */ jsx71(
16077
+ DropdownMenuItem,
16078
+ {
16079
+ icon: ArrowRight,
16080
+ label: t("tableMenu.addRowAfter"),
16081
+ onClick: () => editor.chain().focus().addRowAfter().run(),
16082
+ disabled: !editor.can().addRowAfter()
16083
+ }
16084
+ ),
16085
+ /* @__PURE__ */ jsx71("div", { className: "my-1 border-t" }),
16086
+ /* @__PURE__ */ jsx71(
16087
+ DropdownMenuItem,
16088
+ {
16089
+ icon: Trash2,
16090
+ label: t("tableMenu.deleteColumn"),
16091
+ onClick: () => editor.chain().focus().deleteColumn().run(),
16092
+ disabled: !editor.can().deleteColumn()
16093
+ }
16094
+ ),
16095
+ /* @__PURE__ */ jsx71(DropdownMenuItem, { icon: Trash2, label: t("tableMenu.deleteRow"), onClick: () => editor.chain().focus().deleteRow().run(), disabled: !editor.can().deleteRow() }),
16096
+ /* @__PURE__ */ jsx71(
16097
+ DropdownMenuItem,
16098
+ {
16099
+ icon: Trash2,
16100
+ label: t("tableMenu.deleteTable"),
16101
+ onClick: () => editor.chain().focus().deleteTable().run(),
16102
+ disabled: !editor.can().deleteTable()
16103
+ }
16104
+ )
16105
+ ]
16106
+ }
16107
+ ),
16108
+ /* @__PURE__ */ jsx71(ToolbarDivider, {}),
16109
+ /* @__PURE__ */ jsx71(ToolbarButton, { onClick: () => editor.chain().focus().toggleSubscript().run(), active: editor.isActive("subscript"), title: t("toolbar.subscript"), children: /* @__PURE__ */ jsx71(SubscriptIcon, { className: "w-4 h-4" }) }),
16110
+ /* @__PURE__ */ jsx71(ToolbarButton, { onClick: () => editor.chain().focus().toggleSuperscript().run(), active: editor.isActive("superscript"), title: t("toolbar.superscript"), children: /* @__PURE__ */ jsx71(SuperscriptIcon, { className: "w-4 h-4" }) }),
16111
+ /* @__PURE__ */ jsx71(ToolbarDivider, {}),
16112
+ /* @__PURE__ */ jsx71(ToolbarButton, { onClick: () => editor.chain().focus().undo().run(), disabled: !editor.can().undo(), title: t("toolbar.undo"), children: /* @__PURE__ */ jsx71(UndoIcon, { className: "w-4 h-4" }) }),
16113
+ /* @__PURE__ */ jsx71(ToolbarButton, { onClick: () => editor.chain().focus().redo().run(), disabled: !editor.can().redo(), title: t("toolbar.redo"), children: /* @__PURE__ */ jsx71(RedoIcon, { className: "w-4 h-4" }) })
16114
+ ] });
16115
+ };
16116
+
16117
+ // ../../components/ui/UEditor/menus.tsx
16118
+ import { useCallback as useCallback12, useEffect as useEffect26, useMemo as useMemo15, useRef as useRef23, useState as useState45 } from "react";
16119
+ import { createPortal as createPortal9 } from "react-dom";
16120
+ import { useTranslations as useTranslations5 } from "next-intl";
16121
+ import {
16122
+ Bold as BoldIcon2,
16123
+ Code as CodeIcon2,
16124
+ FileCode as FileCode3,
16125
+ Heading1 as Heading1Icon2,
16126
+ Heading2 as Heading2Icon2,
16127
+ Heading3 as Heading3Icon2,
16128
+ Italic as ItalicIcon2,
16129
+ Link as LinkIcon2,
16130
+ List as ListIcon2,
16131
+ ListOrdered as ListOrderedIcon2,
16132
+ ListTodo as ListTodo3,
16133
+ Minus as Minus2,
16134
+ Palette as Palette3,
16135
+ Plus,
16136
+ Quote as QuoteIcon2,
16137
+ Subscript as SubscriptIcon2,
16138
+ Superscript as SuperscriptIcon2,
16139
+ Table as TableIcon2,
16140
+ Type as Type3,
16141
+ Underline as UnderlineIcon2,
16142
+ Strikethrough as StrikethroughIcon2
16143
+ } from "lucide-react";
16144
+ import { jsx as jsx72, jsxs as jsxs64 } from "react/jsx-runtime";
16145
+ var SlashCommandMenu = ({ editor, onClose, filterText = "" }) => {
16146
+ const t = useTranslations5("UEditor");
16147
+ const [selectedIndex, setSelectedIndex] = useState45(0);
16148
+ const menuRef = useRef23(null);
16149
+ const allCommands = useMemo15(
16150
+ () => [
16151
+ {
16152
+ icon: Type3,
16153
+ label: t("slashCommand.text"),
16154
+ description: t("slashCommand.textDesc"),
16155
+ action: () => editor.chain().focus().setParagraph().run()
16156
+ },
16157
+ {
16158
+ icon: Heading1Icon2,
16159
+ label: t("slashCommand.heading1"),
16160
+ description: t("slashCommand.heading1Desc"),
16161
+ action: () => editor.chain().focus().toggleHeading({ level: 1 }).run()
16162
+ },
16163
+ {
16164
+ icon: Heading2Icon2,
16165
+ label: t("slashCommand.heading2"),
16166
+ description: t("slashCommand.heading2Desc"),
16167
+ action: () => editor.chain().focus().toggleHeading({ level: 2 }).run()
16168
+ },
16169
+ {
16170
+ icon: Heading3Icon2,
16171
+ label: t("slashCommand.heading3"),
16172
+ description: t("slashCommand.heading3Desc"),
16173
+ action: () => editor.chain().focus().toggleHeading({ level: 3 }).run()
16174
+ },
16175
+ {
16176
+ icon: ListIcon2,
16177
+ label: t("slashCommand.bulletList"),
16178
+ description: t("slashCommand.bulletListDesc"),
16179
+ action: () => editor.chain().focus().toggleBulletList().run()
16180
+ },
16181
+ {
16182
+ icon: ListOrderedIcon2,
16183
+ label: t("slashCommand.orderedList"),
16184
+ description: t("slashCommand.orderedListDesc"),
16185
+ action: () => editor.chain().focus().toggleOrderedList().run()
16186
+ },
16187
+ {
16188
+ icon: ListTodo3,
16189
+ label: t("slashCommand.todoList"),
16190
+ description: t("slashCommand.todoListDesc"),
16191
+ action: () => editor.chain().focus().toggleTaskList().run()
16192
+ },
16193
+ {
16194
+ icon: QuoteIcon2,
16195
+ label: t("slashCommand.quote"),
16196
+ description: t("slashCommand.quoteDesc"),
16197
+ action: () => editor.chain().focus().toggleBlockquote().run()
16198
+ },
16199
+ {
16200
+ icon: FileCode3,
16201
+ label: t("slashCommand.codeBlock"),
16202
+ description: t("slashCommand.codeBlockDesc"),
16203
+ action: () => editor.chain().focus().toggleCodeBlock().run()
16204
+ },
16205
+ {
16206
+ icon: Minus2,
16207
+ label: t("slashCommand.divider"),
16208
+ description: t("slashCommand.dividerDesc"),
16209
+ action: () => editor.chain().focus().setHorizontalRule().run()
16210
+ },
16211
+ {
16212
+ icon: TableIcon2,
16213
+ label: t("slashCommand.table"),
16214
+ description: t("slashCommand.tableDesc"),
16215
+ action: () => editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run()
16216
+ }
16217
+ ],
16218
+ [editor, t]
16219
+ );
16220
+ const commands = useMemo15(() => {
16221
+ if (!filterText) return allCommands;
16222
+ const lowerFilter = filterText.toLowerCase();
16223
+ return allCommands.filter((cmd) => cmd.label.toLowerCase().includes(lowerFilter) || cmd.description.toLowerCase().includes(lowerFilter));
16224
+ }, [allCommands, filterText]);
16225
+ useEffect26(() => {
16226
+ setSelectedIndex(0);
16227
+ }, [filterText]);
16228
+ useEffect26(() => {
16229
+ const selectedElement = menuRef.current?.querySelector(`[data-index="${selectedIndex}"]`);
16230
+ selectedElement?.scrollIntoView({ block: "nearest" });
16231
+ }, [selectedIndex]);
16232
+ const selectCommand = useCallback12(
16233
+ (index) => {
16234
+ const command = commands[index];
16235
+ if (command) {
16236
+ command.action();
16237
+ onClose();
16238
+ }
16239
+ },
16240
+ [commands, onClose]
16241
+ );
16242
+ useEffect26(() => {
16243
+ const handleKeyDown = (e) => {
16244
+ if (commands.length === 0) return;
16245
+ if (e.key === "ArrowDown") {
16246
+ e.preventDefault();
16247
+ setSelectedIndex((prev) => (prev + 1) % commands.length);
16248
+ } else if (e.key === "ArrowUp") {
16249
+ e.preventDefault();
16250
+ setSelectedIndex((prev) => (prev - 1 + commands.length) % commands.length);
16251
+ } else if (e.key === "Enter") {
16252
+ e.preventDefault();
16253
+ selectCommand(selectedIndex);
16254
+ } else if (e.key === "Escape") {
16255
+ e.preventDefault();
16256
+ onClose();
16257
+ }
16258
+ };
16259
+ document.addEventListener("keydown", handleKeyDown);
16260
+ return () => document.removeEventListener("keydown", handleKeyDown);
16261
+ }, [commands, selectedIndex, selectCommand, onClose]);
16262
+ if (commands.length === 0) {
16263
+ return /* @__PURE__ */ jsx72("div", { className: "w-72 p-4 text-center text-muted-foreground text-sm", children: t("slashCommand.noResults") });
16264
+ }
16265
+ return /* @__PURE__ */ jsxs64("div", { ref: menuRef, className: "w-72 max-h-80 overflow-y-auto", children: [
16266
+ /* @__PURE__ */ jsx72("div", { className: "px-3 py-2 border-b", children: /* @__PURE__ */ jsx72("span", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: t("slashCommand.basicBlocks") }) }),
16267
+ /* @__PURE__ */ jsx72("div", { className: "p-1", children: commands.map((cmd, index) => /* @__PURE__ */ jsxs64(
16268
+ "button",
16269
+ {
16270
+ type: "button",
16271
+ "data-index": index,
16272
+ onMouseDown: (e) => e.preventDefault(),
16273
+ onClick: () => selectCommand(index),
16274
+ onMouseEnter: () => setSelectedIndex(index),
16275
+ className: cn(
16276
+ "flex items-center w-full px-3 py-2.5 rounded-lg transition-colors group",
16277
+ selectedIndex === index ? "bg-accent" : "hover:bg-accent/50"
16278
+ ),
16279
+ children: [
16280
+ /* @__PURE__ */ jsx72(
16281
+ "div",
16282
+ {
16283
+ className: cn(
16284
+ "flex items-center justify-center w-10 h-10 rounded-lg mr-3 transition-colors",
16285
+ selectedIndex === index ? "bg-primary/10" : "bg-muted/50 group-hover:bg-muted"
16286
+ ),
16287
+ children: /* @__PURE__ */ jsx72(cmd.icon, { className: cn("w-5 h-5", selectedIndex === index ? "text-primary" : "text-muted-foreground") })
16288
+ }
16289
+ ),
16290
+ /* @__PURE__ */ jsxs64("div", { className: "text-left", children: [
16291
+ /* @__PURE__ */ jsx72("div", { className: cn("text-sm font-medium", selectedIndex === index && "text-primary"), children: cmd.label }),
16292
+ /* @__PURE__ */ jsx72("div", { className: "text-xs text-muted-foreground", children: cmd.description })
16293
+ ] })
16294
+ ]
16295
+ },
16296
+ cmd.label
16297
+ )) })
16298
+ ] });
16299
+ };
16300
+ var FloatingMenuContent = ({ editor }) => {
16301
+ const t = useTranslations5("UEditor");
16302
+ const [showCommands, setShowCommands] = useState45(false);
16303
+ if (showCommands) {
16304
+ return /* @__PURE__ */ jsx72(SlashCommandMenu, { editor, onClose: () => setShowCommands(false) });
16305
+ }
16306
+ return /* @__PURE__ */ jsxs64(
16307
+ "button",
16308
+ {
16309
+ type: "button",
16310
+ onClick: () => setShowCommands(true),
16311
+ className: "flex items-center gap-1 px-2 py-1.5 rounded-lg hover:bg-accent transition-all group",
16312
+ children: [
16313
+ /* @__PURE__ */ jsx72(Plus, { className: "w-4 h-4 text-muted-foreground group-hover:text-foreground" }),
16314
+ /* @__PURE__ */ jsx72("span", { className: "text-sm text-muted-foreground group-hover:text-foreground", children: t("floatingMenu.addBlock") })
16315
+ ]
16316
+ }
16317
+ );
16318
+ };
16319
+ var BubbleMenuContent = ({ editor }) => {
16320
+ const t = useTranslations5("UEditor");
16321
+ const { textColors, highlightColors } = useEditorColors();
16322
+ const [showLinkInput, setShowLinkInput] = useState45(false);
16323
+ const [showEditorColorPalette, setShowEditorColorPalette] = useState45(false);
16324
+ if (showLinkInput) {
16325
+ return /* @__PURE__ */ jsx72(
16326
+ LinkInput,
16327
+ {
16328
+ initialUrl: editor.getAttributes("link").href || "",
16329
+ onSubmit: (url) => {
16330
+ editor.chain().focus().extendMarkRange("link").setLink({ href: url }).run();
16331
+ },
16332
+ onCancel: () => setShowLinkInput(false)
16333
+ }
16334
+ );
16335
+ }
16336
+ if (showEditorColorPalette) {
16337
+ return /* @__PURE__ */ jsxs64("div", { className: "w-48", children: [
16338
+ /* @__PURE__ */ jsx72(
16339
+ EditorColorPalette,
16340
+ {
16341
+ colors: textColors,
16342
+ currentColor: editor.getAttributes("textStyle").color || "inherit",
16343
+ onSelect: (color) => {
16344
+ if (color === "inherit") {
16345
+ editor.chain().focus().unsetColor().run();
16346
+ } else {
16347
+ editor.chain().focus().setColor(color).run();
16348
+ }
16349
+ },
16350
+ label: t("colors.textColor")
16351
+ }
16352
+ ),
16353
+ /* @__PURE__ */ jsx72("div", { className: "border-t my-1" }),
16354
+ /* @__PURE__ */ jsx72(
16355
+ EditorColorPalette,
16356
+ {
16357
+ colors: highlightColors,
16358
+ currentColor: editor.getAttributes("highlight").color || "",
16359
+ onSelect: (color) => {
16360
+ if (color === "") {
16361
+ editor.chain().focus().unsetHighlight().run();
16362
+ } else {
16363
+ editor.chain().focus().toggleHighlight({ color }).run();
16364
+ }
16365
+ },
16366
+ label: t("colors.highlight")
16367
+ }
16368
+ ),
16369
+ /* @__PURE__ */ jsx72("div", { className: "p-2 border-t", children: /* @__PURE__ */ jsx72(
16370
+ "button",
16371
+ {
16372
+ type: "button",
16373
+ onClick: () => setShowEditorColorPalette(false),
16374
+ className: "w-full py-1.5 text-sm rounded-lg hover:bg-muted transition-colors",
16375
+ children: t("colors.done")
16376
+ }
16377
+ ) })
16378
+ ] });
16379
+ }
16380
+ return /* @__PURE__ */ jsxs64("div", { className: "flex items-center gap-0.5 p-1", children: [
16381
+ /* @__PURE__ */ jsx72(ToolbarButton, { onClick: () => editor.chain().focus().toggleBold().run(), active: editor.isActive("bold"), title: t("toolbar.bold"), children: /* @__PURE__ */ jsx72(BoldIcon2, { className: "w-4 h-4" }) }),
16382
+ /* @__PURE__ */ jsx72(ToolbarButton, { onClick: () => editor.chain().focus().toggleItalic().run(), active: editor.isActive("italic"), title: t("toolbar.italic"), children: /* @__PURE__ */ jsx72(ItalicIcon2, { className: "w-4 h-4" }) }),
16383
+ /* @__PURE__ */ jsx72(
16384
+ ToolbarButton,
16385
+ {
16386
+ onClick: () => editor.chain().focus().toggleUnderline().run(),
16387
+ active: editor.isActive("underline"),
16388
+ title: t("toolbar.underline"),
16389
+ children: /* @__PURE__ */ jsx72(UnderlineIcon2, { className: "w-4 h-4" })
16390
+ }
16391
+ ),
16392
+ /* @__PURE__ */ jsx72(ToolbarButton, { onClick: () => editor.chain().focus().toggleStrike().run(), active: editor.isActive("strike"), title: t("toolbar.strike"), children: /* @__PURE__ */ jsx72(StrikethroughIcon2, { className: "w-4 h-4" }) }),
16393
+ /* @__PURE__ */ jsx72(ToolbarButton, { onClick: () => editor.chain().focus().toggleCode().run(), active: editor.isActive("code"), title: t("toolbar.code"), children: /* @__PURE__ */ jsx72(CodeIcon2, { className: "w-4 h-4" }) }),
16394
+ /* @__PURE__ */ jsx72("div", { className: "w-px h-6 bg-border/50 mx-1" }),
16395
+ /* @__PURE__ */ jsx72(ToolbarButton, { onClick: () => setShowLinkInput(true), active: editor.isActive("link"), title: t("toolbar.link"), children: /* @__PURE__ */ jsx72(LinkIcon2, { className: "w-4 h-4" }) }),
16396
+ /* @__PURE__ */ jsx72(ToolbarButton, { onClick: () => setShowEditorColorPalette(true), title: t("colors.textColor"), children: /* @__PURE__ */ jsx72(Palette3, { className: "w-4 h-4" }) }),
16397
+ /* @__PURE__ */ jsx72("div", { className: "w-px h-6 bg-border/50 mx-1" }),
16398
+ /* @__PURE__ */ jsx72(
16399
+ ToolbarButton,
16400
+ {
16401
+ onClick: () => editor.chain().focus().toggleSubscript().run(),
16402
+ active: editor.isActive("subscript"),
16403
+ title: t("toolbar.subscript"),
16404
+ children: /* @__PURE__ */ jsx72(SubscriptIcon2, { className: "w-4 h-4" })
16405
+ }
16406
+ ),
16407
+ /* @__PURE__ */ jsx72(
16408
+ ToolbarButton,
16409
+ {
16410
+ onClick: () => editor.chain().focus().toggleSuperscript().run(),
16411
+ active: editor.isActive("superscript"),
16412
+ title: t("toolbar.superscript"),
16413
+ children: /* @__PURE__ */ jsx72(SuperscriptIcon2, { className: "w-4 h-4" })
16414
+ }
16415
+ )
16416
+ ] });
16417
+ };
16418
+ var CustomBubbleMenu = ({ editor }) => {
16419
+ const [isVisible, setIsVisible] = useState45(false);
16420
+ const [position, setPosition] = useState45({ top: 0, left: 0 });
16421
+ const menuRef = useRef23(null);
16422
+ useEffect26(() => {
16423
+ const updatePosition = () => {
16424
+ const { state, view } = editor;
16425
+ const { from, to, empty } = state.selection;
16426
+ if (empty || !view.hasFocus()) {
16427
+ setIsVisible(false);
16428
+ return;
16429
+ }
16430
+ const start = view.coordsAtPos(from);
16431
+ const end = view.coordsAtPos(to);
16432
+ const left = (start.left + end.left) / 2;
16433
+ const top = start.top - 10;
16434
+ setPosition({ top, left });
16435
+ setIsVisible(true);
16436
+ };
16437
+ const handleBlur = () => setIsVisible(false);
16438
+ editor.on("selectionUpdate", updatePosition);
16439
+ editor.on("focus", updatePosition);
16440
+ editor.on("blur", handleBlur);
16441
+ return () => {
16442
+ editor.off("selectionUpdate", updatePosition);
16443
+ editor.off("focus", updatePosition);
16444
+ editor.off("blur", handleBlur);
16445
+ };
16446
+ }, [editor]);
16447
+ if (!isVisible) return null;
16448
+ return createPortal9(
16449
+ /* @__PURE__ */ jsx72(
16450
+ "div",
16451
+ {
16452
+ ref: menuRef,
16453
+ className: "fixed z-50 flex rounded-2xl border border-border bg-card text-card-foreground shadow-lg backdrop-blur-sm overflow-hidden animate-in fade-in-0 zoom-in-95",
16454
+ style: {
16455
+ top: `${position.top}px`,
16456
+ left: `${position.left}px`,
16457
+ transform: "translate(-50%, -100%)"
16458
+ },
16459
+ onMouseDown: (e) => e.preventDefault(),
16460
+ children: /* @__PURE__ */ jsx72(BubbleMenuContent, { editor })
16461
+ }
16462
+ ),
16463
+ document.body
16464
+ );
16465
+ };
16466
+ var CustomFloatingMenu = ({ editor }) => {
16467
+ const [isVisible, setIsVisible] = useState45(false);
16468
+ const [position, setPosition] = useState45({ top: 0, left: 0 });
16469
+ useEffect26(() => {
16470
+ const updatePosition = () => {
16471
+ const { state, view } = editor;
16472
+ const { $from, empty } = state.selection;
16473
+ const isEmptyTextBlock = $from.parent.isTextblock && $from.parent.type.name === "paragraph" && $from.parent.textContent === "" && empty;
16474
+ if (!isEmptyTextBlock || !view.hasFocus()) {
16475
+ setIsVisible(false);
16476
+ return;
16477
+ }
16478
+ const coords = view.coordsAtPos($from.pos);
16479
+ setPosition({ top: coords.top - 10, left: coords.left });
16480
+ setIsVisible(true);
16481
+ };
16482
+ const handleBlur = () => setIsVisible(false);
16483
+ editor.on("selectionUpdate", updatePosition);
16484
+ editor.on("focus", updatePosition);
16485
+ editor.on("blur", handleBlur);
16486
+ editor.on("update", updatePosition);
16487
+ return () => {
16488
+ editor.off("selectionUpdate", updatePosition);
16489
+ editor.off("focus", updatePosition);
16490
+ editor.off("blur", handleBlur);
16491
+ editor.off("update", updatePosition);
16492
+ };
16493
+ }, [editor]);
16494
+ if (!isVisible) return null;
16495
+ return createPortal9(
16496
+ /* @__PURE__ */ jsx72(
16497
+ "div",
16498
+ {
16499
+ className: "fixed z-50 rounded-2xl border border-border bg-card text-card-foreground shadow-lg backdrop-blur-sm overflow-hidden animate-in fade-in-0 slide-in-from-bottom-2",
16500
+ style: {
16501
+ top: `${position.top}px`,
16502
+ left: `${position.left}px`,
16503
+ transform: "translate(-50%, -100%)"
16504
+ },
16505
+ onMouseDown: (e) => e.preventDefault(),
16506
+ children: /* @__PURE__ */ jsx72(FloatingMenuContent, { editor })
16507
+ }
16508
+ ),
16509
+ document.body
16510
+ );
16511
+ };
16512
+
16513
+ // ../../components/ui/UEditor/CharacterCount.tsx
16514
+ import { useTranslations as useTranslations6 } from "next-intl";
16515
+ import { jsxs as jsxs65 } from "react/jsx-runtime";
16516
+ var CharacterCountDisplay = ({ editor, maxCharacters }) => {
16517
+ const t = useTranslations6("UEditor");
16518
+ const storage = editor.storage;
16519
+ const characterCount = storage.characterCount?.characters?.() ?? 0;
16520
+ const wordCount = storage.characterCount?.words?.() ?? 0;
16521
+ const percentage = maxCharacters ? Math.round(characterCount / maxCharacters * 100) : 0;
16522
+ return /* @__PURE__ */ jsxs65("div", { className: "flex items-center gap-3 px-3 py-2 text-xs text-muted-foreground border-t bg-muted/20", children: [
16523
+ /* @__PURE__ */ jsxs65("span", { children: [
16524
+ wordCount,
16525
+ " ",
16526
+ t("words")
16527
+ ] }),
16528
+ /* @__PURE__ */ jsxs65("span", { children: [
16529
+ characterCount,
16530
+ " ",
16531
+ t("characters")
16532
+ ] }),
16533
+ maxCharacters && /* @__PURE__ */ jsxs65("span", { className: cn(percentage > 90 && "text-destructive", percentage > 100 && "font-bold"), children: [
16534
+ characterCount,
16535
+ "/",
16536
+ maxCharacters
16537
+ ] })
16538
+ ] });
16539
+ };
16540
+
16541
+ // ../../components/ui/UEditor/UEditor.tsx
16542
+ import { jsx as jsx73, jsxs as jsxs66 } from "react/jsx-runtime";
16543
+ var UEditor = ({
16544
+ content = "",
16545
+ onChange,
16546
+ onHtmlChange,
16547
+ onJsonChange,
16548
+ placeholder,
16549
+ className,
16550
+ editable = true,
16551
+ autofocus = false,
16552
+ showToolbar = true,
16553
+ showBubbleMenu = true,
16554
+ showFloatingMenu = false,
16555
+ showCharacterCount = true,
16556
+ maxCharacters,
16557
+ minHeight = "200px",
16558
+ maxHeight = "auto",
16559
+ variant = "default"
16560
+ }) => {
16561
+ const t = useTranslations7("UEditor");
16562
+ const effectivePlaceholder = placeholder ?? t("placeholder");
16563
+ const extensions = useMemo16(
16564
+ () => buildUEditorExtensions({ placeholder: effectivePlaceholder, maxCharacters }),
16565
+ [effectivePlaceholder, maxCharacters]
16566
+ );
16567
+ const editor = useEditor({
16568
+ immediatelyRender: false,
16569
+ extensions,
16570
+ content,
16571
+ editable,
16572
+ autofocus,
16573
+ editorProps: {
16574
+ handleDOMEvents: {
16575
+ keydown: (_view, event) => {
16576
+ if (!(event instanceof KeyboardEvent)) return false;
16577
+ if (event.key === "ArrowLeft" || event.key === "ArrowRight" || event.key === "ArrowUp" || event.key === "ArrowDown") {
16578
+ event.stopPropagation();
16579
+ }
16580
+ return false;
16581
+ }
16582
+ },
16583
+ attributes: {
16584
+ class: cn(
16585
+ "prose prose-sm sm:prose dark:prose-invert max-w-none",
16586
+ "focus:outline-none",
16587
+ "px-4 py-4",
16588
+ "[&_.is-editor-empty]:before:content-[attr(data-placeholder)]",
16589
+ "[&_.is-editor-empty]:before:text-muted-foreground/50",
16590
+ "[&_.is-editor-empty]:before:float-left",
16591
+ "[&_.is-editor-empty]:before:pointer-events-none",
16592
+ "[&_.is-editor-empty]:before:h-0",
16593
+ "[&_ul[data-type='taskList']]:list-none",
16594
+ "[&_ul[data-type='taskList']]:pl-0",
16595
+ "[&_ul[data-type='taskList']_li]:flex",
16596
+ "[&_ul[data-type='taskList']_li]:items-start",
16597
+ "[&_ul[data-type='taskList']_li]:gap-2",
16598
+ "[&_ul[data-type='taskList']_li>label]:mt-0.5",
16599
+ "[&_ul[data-type='taskList']_li>label>input]:w-4",
16600
+ "[&_ul[data-type='taskList']_li>label>input]:h-4",
16601
+ "[&_ul[data-type='taskList']_li>label>input]:rounded",
16602
+ "[&_ul[data-type='taskList']_li>label>input]:border-2",
16603
+ "[&_ul[data-type='taskList']_li>label>input]:border-primary/50",
16604
+ "[&_ul[data-type='taskList']_li>label>input]:accent-primary",
16605
+ "[&_pre]:!bg-[#1e1e1e]",
16606
+ "[&_pre]:!text-[#d4d4d4]",
16607
+ "[&_pre_code]:!bg-transparent",
16608
+ "[&_hr]:border-t-2",
16609
+ "[&_hr]:border-primary/30",
16610
+ "[&_hr]:my-8",
16611
+ "[&_h1]:text-3xl",
16612
+ "[&_h1]:font-bold",
16613
+ "[&_h1]:mt-6",
16614
+ "[&_h1]:mb-4",
16615
+ "[&_h1]:text-foreground",
16616
+ "[&_h2]:text-2xl",
16617
+ "[&_h2]:font-semibold",
16618
+ "[&_h2]:mt-5",
16619
+ "[&_h2]:mb-3",
16620
+ "[&_h2]:text-foreground",
16621
+ "[&_h3]:text-xl",
16622
+ "[&_h3]:font-semibold",
16623
+ "[&_h3]:mt-4",
16624
+ "[&_h3]:mb-2",
16625
+ "[&_h3]:text-foreground",
16626
+ "[&_ul:not([data-type='taskList'])]:list-disc",
16627
+ "[&_ul:not([data-type='taskList'])]:pl-6",
16628
+ "[&_ul:not([data-type='taskList'])]:my-3",
16629
+ "[&_ol]:list-decimal",
16630
+ "[&_ol]:pl-6",
16631
+ "[&_ol]:my-3",
16632
+ "[&_li]:my-1",
16633
+ "[&_li]:pl-1",
16634
+ "[&_li_p]:my-0",
16635
+ "[&_blockquote]:border-l-4",
16636
+ "[&_blockquote]:border-primary",
16637
+ "[&_blockquote]:pl-4",
16638
+ "[&_blockquote]:py-2",
16639
+ "[&_blockquote]:my-4",
16640
+ "[&_blockquote]:bg-muted/30",
16641
+ "[&_blockquote]:rounded-r-lg",
16642
+ "[&_blockquote]:italic",
16643
+ "[&_blockquote]:text-muted-foreground",
16644
+ "[&_blockquote_p]:my-0"
16645
+ )
16646
+ }
16647
+ },
16648
+ onUpdate: ({ editor: editor2 }) => {
16649
+ const html = editor2.getHTML();
16650
+ onChange?.(html);
16651
+ onHtmlChange?.(html);
16652
+ onJsonChange?.(editor2.getJSON());
16653
+ }
16654
+ });
16655
+ useEffect27(() => {
16656
+ if (editor && content !== editor.getHTML()) {
16657
+ if (editor.isEmpty && content) {
16658
+ editor.commands.setContent(content);
16659
+ }
16660
+ }
16661
+ }, [content, editor]);
16662
+ if (!editor) {
16663
+ return /* @__PURE__ */ jsx73(
16664
+ "div",
16665
+ {
16666
+ className: cn("w-full rounded-lg border bg-background flex items-center justify-center text-muted-foreground", className),
16667
+ style: { minHeight },
16668
+ children: t("loading")
16669
+ }
16670
+ );
16671
+ }
16672
+ return /* @__PURE__ */ jsxs66(
16673
+ "div",
16674
+ {
16675
+ className: cn(
16676
+ "group relative flex flex-col rounded-2xl md:rounded-3xl border border-border bg-card text-card-foreground overflow-hidden",
16677
+ "transition-[transform,box-shadow,border-color,background-color] duration-300 ease-soft",
16678
+ "shadow-sm focus-within:shadow-md focus-within:border-primary/15",
16679
+ "backdrop-blur-sm",
16680
+ variant === "notion" && "hover:shadow-md",
16681
+ className
16682
+ ),
16683
+ children: [
16684
+ editable && showToolbar && /* @__PURE__ */ jsx73(EditorToolbar, { editor, variant }),
16685
+ editable && showBubbleMenu && /* @__PURE__ */ jsx73(CustomBubbleMenu, { editor }),
16686
+ editable && showFloatingMenu && /* @__PURE__ */ jsx73(CustomFloatingMenu, { editor }),
16687
+ /* @__PURE__ */ jsx73(
16688
+ EditorContent,
16689
+ {
16690
+ editor,
16691
+ className: "flex-1 overflow-y-auto",
16692
+ style: {
16693
+ minHeight,
16694
+ maxHeight
16695
+ }
16696
+ }
16697
+ ),
16698
+ showCharacterCount && /* @__PURE__ */ jsx73(CharacterCountDisplay, { editor, maxCharacters })
16699
+ ]
16700
+ }
16701
+ );
16702
+ };
16703
+ var UEditor_default = UEditor;
16704
+
15134
16705
  // src/index.ts
15135
16706
  var underverseMessages = { en: en_default, vi: vi_default, ko: ko_default, ja: ja_default };
15136
16707
  function getUnderverseMessages(locale = "en") {
@@ -15266,6 +16837,7 @@ export {
15266
16837
  Toast_default as ToastProvider,
15267
16838
  Tooltip,
15268
16839
  TranslationProvider,
16840
+ UEditor_default as UEditor,
15269
16841
  UnderverseProvider,
15270
16842
  VARIANT_STYLES_ALERT,
15271
16843
  VARIANT_STYLES_BTN,