@rufous/ui 0.1.98 → 0.1.100

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/main.cjs CHANGED
@@ -41672,6 +41672,12 @@ var STATUS_IMAGES = {
41672
41672
  blocked: "https://storage.googleapis.com/rufous-com-bucket-1/static/images/blocked.svg",
41673
41673
  resolved: "https://storage.googleapis.com/rufous-com-bucket-1/static/images/closed.svg"
41674
41674
  };
41675
+ var STATUS_LABELS = {
41676
+ todo: "Todo",
41677
+ working: "Working",
41678
+ blocked: "Blocked",
41679
+ resolved: "Resolved"
41680
+ };
41675
41681
  var STATUS_COLORS = {
41676
41682
  todo: { border: "#dc2626", bg: "#fff", color: "#dc2626" },
41677
41683
  working: { border: "#2563eb", bg: "#eff6ff", color: "#2563eb" },
@@ -41715,14 +41721,16 @@ var CustomTaskItem = import_extension_task_item.default.extend({
41715
41721
  if (afterContent.size > 0) {
41716
41722
  tr.delete(cursorPos, paraEnd);
41717
41723
  }
41718
- const newPara = afterContent.size > 0 ? schema.nodes.paragraph.create(null, afterContent) : schema.nodes.paragraph.create();
41724
+ const statusLabel = STATUS_LABELS[status] || STATUS_LABELS.todo;
41725
+ const newPara = afterContent.size > 0 ? schema.nodes.paragraph.create(null, afterContent) : schema.nodes.paragraph.create(null, schema.text(statusLabel));
41719
41726
  const newItem = schema.nodes.taskItem.create(
41720
41727
  { status, checked: false },
41721
41728
  newPara
41722
41729
  );
41723
41730
  const insertPos = tr.mapping.map($from.after(taskDepth));
41724
41731
  tr.insert(insertPos, newItem);
41725
- tr.setSelection(TextSelection.near(tr.doc.resolve(insertPos + 2)));
41732
+ const textLen = afterContent.size > 0 ? 0 : statusLabel.length;
41733
+ tr.setSelection(TextSelection.near(tr.doc.resolve(insertPos + 2 + textLen)));
41726
41734
  this.editor.view.dispatch(tr);
41727
41735
  return true;
41728
41736
  },
@@ -41762,10 +41770,35 @@ var CustomTaskItem = import_extension_task_item.default.extend({
41762
41770
  const from = $from.before(taskItemDepth);
41763
41771
  const to = $from.after(taskItemDepth);
41764
41772
  tr.delete(from, to);
41765
- tr.setSelection(TextSelection.near(tr.doc.resolve(Math.max(0, from))));
41773
+ tr.setSelection(TextSelection.near(tr.doc.resolve(Math.max(0, from)), -1));
41766
41774
  this.editor.view.dispatch(tr);
41767
41775
  return true;
41768
41776
  }
41777
+ const indexInList = taskListDepth !== -1 ? $from.index(taskListDepth) : -1;
41778
+ if (indexInList > 0 && taskListDepth !== -1) {
41779
+ const tr = state.tr;
41780
+ const itemStart = $from.before(taskItemDepth);
41781
+ const itemEnd = $from.after(taskItemDepth);
41782
+ const posBefore = itemStart;
41783
+ if (tr.doc.resolve(posBefore).nodeBefore) {
41784
+ const textContent = taskItem.textContent;
41785
+ const contentSlice = taskItem.content;
41786
+ tr.delete(itemStart, itemEnd);
41787
+ const prevItemEndPos = Math.max(0, itemStart - 1);
41788
+ const $prevEnd = tr.doc.resolve(prevItemEndPos);
41789
+ const prevParaEnd = $prevEnd.end($prevEnd.depth);
41790
+ let insertAt = prevParaEnd;
41791
+ contentSlice.forEach((child) => {
41792
+ child.content.forEach((inline) => {
41793
+ tr.insert(insertAt, inline);
41794
+ insertAt += inline.nodeSize;
41795
+ });
41796
+ });
41797
+ tr.setSelection(TextSelection.create(tr.doc, prevParaEnd));
41798
+ this.editor.view.dispatch(tr);
41799
+ return true;
41800
+ }
41801
+ }
41769
41802
  return this.editor.commands.liftListItem(this.name);
41770
41803
  },
41771
41804
  "Shift-Tab": () => this.editor.commands.liftListItem(this.name),
@@ -41881,6 +41914,7 @@ var IconFullscreen = () => /* @__PURE__ */ React112.createElement("svg", { ...s
41881
41914
  var IconTranslate = () => /* @__PURE__ */ React112.createElement("svg", { ...s }, /* @__PURE__ */ React112.createElement("path", { d: "M12.87 15.07l-2.54-2.51.03-.03A17.52 17.52 0 0014.07 6H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2.02c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z" }));
41882
41915
  var IconTaskList = () => /* @__PURE__ */ React112.createElement("svg", { ...s }, /* @__PURE__ */ React112.createElement("path", { d: "M22 8c0-.55-.45-1-1-1h-7c-.55 0-1 .45-1 1s.45 1 1 1h7c.55 0 1-.45 1-1zm0 8c0-.55-.45-1-1-1h-7c-.55 0-1 .45-1 1s.45 1 1 1h7c.55 0 1-.45 1-1zM5.54 11L2 7.46l1.41-1.41 2.12 2.12 4.24-4.24 1.41 1.41L5.54 11zm0 8L2 15.46l1.41-1.41 2.12 2.12 4.24-4.24 1.41 1.41L5.54 19z" }));
41883
41916
  var IconCheck = () => /* @__PURE__ */ React112.createElement("svg", { ...s }, /* @__PURE__ */ React112.createElement("path", { d: "M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z" }));
41917
+ var IconPaste = () => /* @__PURE__ */ React112.createElement("svg", { ...s }, /* @__PURE__ */ React112.createElement("path", { d: "M19 2h-4.18C14.4.84 13.3 0 12 0c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm7 18H5V4h2v3h10V4h2v16z" }));
41884
41918
 
41885
41919
  // lib/RufousTextEditor/Toolbar.tsx
41886
41920
  var COLOR_PALETTE = [
@@ -42346,6 +42380,15 @@ var Toolbar = ({ editor, setLink, onAICommand, onTranslate, onSpeechToText, onTe
42346
42380
  setTimeout(() => setCopySuccess(false), 2e3);
42347
42381
  }
42348
42382
  }, [editor]);
42383
+ const handlePaste = (0, import_react56.useCallback)(async () => {
42384
+ if (!editor) return;
42385
+ try {
42386
+ const text = await navigator.clipboard.readText();
42387
+ if (text) editor.chain().focus().insertContent(text).run();
42388
+ } catch {
42389
+ document.execCommand("paste");
42390
+ }
42391
+ }, [editor]);
42349
42392
  const handleQuickTranslate = (0, import_react56.useCallback)(async () => {
42350
42393
  if (!editor) return;
42351
42394
  const { from, to, empty } = editor.state.selection;
@@ -42776,6 +42819,14 @@ var Toolbar = ({ editor, setLink, onAICommand, onTranslate, onSpeechToText, onTe
42776
42819
  title: "Copy selected text"
42777
42820
  },
42778
42821
  copySuccess ? /* @__PURE__ */ import_react56.default.createElement(IconCheck, null) : /* @__PURE__ */ import_react56.default.createElement(IconCopy, null)
42822
+ ), /* @__PURE__ */ import_react56.default.createElement(
42823
+ "button",
42824
+ {
42825
+ className: "toolbar-btn",
42826
+ onClick: handlePaste,
42827
+ title: "Paste (Ctrl+V)"
42828
+ },
42829
+ /* @__PURE__ */ import_react56.default.createElement(IconPaste, null)
42779
42830
  ), /* @__PURE__ */ import_react56.default.createElement(Dropdown, { trigger: { label: "\u03A9", title: "Special characters", className: "special-characters-btn" } }, /* @__PURE__ */ import_react56.default.createElement("div", { className: "char-grid" }, SPECIAL_CHARS.map((char) => /* @__PURE__ */ import_react56.default.createElement(
42780
42831
  "button",
42781
42832
  {
@@ -42787,10 +42838,26 @@ var Toolbar = ({ editor, setLink, onAICommand, onTranslate, onSpeechToText, onTe
42787
42838
  )))), /* @__PURE__ */ import_react56.default.createElement(
42788
42839
  Dropdown,
42789
42840
  {
42790
- trigger: { label: /* @__PURE__ */ import_react56.default.createElement(IconCode, null), title: "Code", className: editor.isActive("code") ? "is-active" : "" }
42841
+ trigger: { label: /* @__PURE__ */ import_react56.default.createElement(IconCode, null), title: "Code", className: editor.isActive("code") || editor.isActive("codeBlock") ? "is-active" : "" }
42791
42842
  },
42792
42843
  /* @__PURE__ */ import_react56.default.createElement("button", { className: "dropdown-item", onClick: () => editor.chain().focus().toggleCode().run() }, "</>", " Inline Code"),
42793
- /* @__PURE__ */ import_react56.default.createElement("button", { className: "dropdown-item", onClick: () => editor.chain().focus().toggleCodeBlock().run() }, "{ }", " Code Block")
42844
+ /* @__PURE__ */ import_react56.default.createElement("button", { className: "dropdown-item", onClick: () => editor.chain().focus().toggleCodeBlock().run() }, "{ }", " Code Block"),
42845
+ editor.isActive("codeBlock") && /* @__PURE__ */ import_react56.default.createElement("button", { className: "dropdown-item", onClick: () => {
42846
+ const text = (() => {
42847
+ const { $from } = editor.state.selection;
42848
+ for (let d = $from.depth; d > 0; d--) {
42849
+ if ($from.node(d).type.name === "codeBlock") return $from.node(d).textContent;
42850
+ }
42851
+ return "";
42852
+ })();
42853
+ if (text) {
42854
+ editor.chain().focus().toggleCodeBlock().run();
42855
+ const { from } = editor.state.selection;
42856
+ editor.chain().focus().setTextSelection({ from, to: from + text.length }).toggleCode().run();
42857
+ } else {
42858
+ editor.chain().focus().toggleCodeBlock().run();
42859
+ }
42860
+ } }, "</> \u2190", " Convert to Inline Code")
42794
42861
  ), /* @__PURE__ */ import_react56.default.createElement(
42795
42862
  "button",
42796
42863
  {
@@ -42807,52 +42874,73 @@ var Toolbar = ({ editor, setLink, onAICommand, onTranslate, onSpeechToText, onTe
42807
42874
  title: "Translate selected text"
42808
42875
  },
42809
42876
  /* @__PURE__ */ import_react56.default.createElement(IconTranslate, null)
42810
- ), /* @__PURE__ */ import_react56.default.createElement(Dropdown, { trigger: { label: "", title: "Translate options", className: "translate-arrow-btn" } }, /* @__PURE__ */ import_react56.default.createElement("button", { className: "dropdown-item", onClick: () => setShowTranslateModal(true) }, "Options")), translateStatus && /* @__PURE__ */ import_react56.default.createElement("span", { className: `translate-toast-popup ${translateStatus === "Please select the text" || translateStatus === "Translation failed" ? "error" : ""}` }, translateStatus)), /* @__PURE__ */ import_react56.default.createElement(
42811
- Dropdown,
42877
+ ), /* @__PURE__ */ import_react56.default.createElement(Dropdown, { trigger: { label: "", title: "Translate options", className: "translate-arrow-btn" } }, /* @__PURE__ */ import_react56.default.createElement("button", { className: "dropdown-item", onClick: () => setShowTranslateModal(true) }, "Options")), translateStatus && /* @__PURE__ */ import_react56.default.createElement("span", { className: `translate-toast-popup ${translateStatus === "Please select the text" || translateStatus === "Translation failed" ? "error" : ""}` }, translateStatus)), /* @__PURE__ */ import_react56.default.createElement("div", { className: "todo-split-btn" }, /* @__PURE__ */ import_react56.default.createElement(
42878
+ "button",
42812
42879
  {
42813
- trigger: { label: /* @__PURE__ */ import_react56.default.createElement(IconTaskList, null), title: "Task list", className: editor.isActive("taskList") ? "is-active" : "" },
42814
- keepOpen: true
42815
- },
42816
- ["todo", "working", "blocked", "resolved"].map((status) => {
42817
- const symbols = { todo: "\u2610", working: "\u27F3", blocked: "\u25A0", resolved: "\u2611" };
42818
- const images = { todo: "https://storage.googleapis.com/rufous-com-bucket-1/static/images/todo-blank.svg", working: "https://storage.googleapis.com/rufous-com-bucket-1/static/images/working.svg", blocked: "https://storage.googleapis.com/rufous-com-bucket-1/static/images/blocked.svg", resolved: "https://storage.googleapis.com/rufous-com-bucket-1/static/images/closed.svg" };
42819
- const labels = { todo: "Todo", working: "Working", blocked: "Blocked", resolved: "Resolved" };
42820
- return /* @__PURE__ */ import_react56.default.createElement("button", { key: status, className: `dropdown-item task-status-item`, onClick: () => {
42821
- const { state } = editor;
42822
- const { schema } = state;
42823
- const taskItemType = schema.nodes.taskItem;
42824
- const taskListType = schema.nodes.taskList;
42825
- if (!taskItemType || !taskListType) return;
42826
- const statusText = schema.text(labels[status]);
42827
- const newTaskItem = taskItemType.create({ status, checked: false }, schema.nodes.paragraph.create(null, statusText));
42828
- editor.chain().focus().command(({ tr, dispatch, state: cmdState }) => {
42829
- if (!dispatch) return true;
42830
- const { $from } = tr.selection;
42831
- let taskItemDepth = -1;
42832
- for (let d = $from.depth; d > 0; d--) {
42833
- if ($from.node(d).type.name === "taskItem") {
42834
- taskItemDepth = d;
42835
- break;
42836
- }
42837
- }
42838
- const textLen = labels[status].length;
42839
- if (taskItemDepth !== -1) {
42840
- const afterPos = $from.after(taskItemDepth);
42841
- tr.insert(afterPos, newTaskItem);
42842
- const resolvedPos = tr.doc.resolve(afterPos + 2 + textLen);
42843
- tr.setSelection(cmdState.selection.constructor.near(resolvedPos));
42844
- } else {
42845
- const newTaskList = taskListType.create(null, newTaskItem);
42880
+ className: `toolbar-btn ${editor.isActive("taskList") ? "is-active" : ""}`,
42881
+ onClick: () => {
42882
+ if (editor.isActive("taskList")) {
42883
+ editor.chain().focus().liftListItem("taskItem").run();
42884
+ } else {
42885
+ const { state } = editor;
42886
+ const { schema } = state;
42887
+ const taskItemType = schema.nodes.taskItem;
42888
+ const taskListType = schema.nodes.taskList;
42889
+ if (!taskItemType || !taskListType) return;
42890
+ const statusText = schema.text("Todo");
42891
+ const newTaskItem = taskItemType.create({ status: "todo", checked: false }, schema.nodes.paragraph.create(null, statusText));
42892
+ const newTaskList = taskListType.create(null, newTaskItem);
42893
+ editor.chain().focus().command(({ tr, dispatch, state: cmdState }) => {
42894
+ if (!dispatch) return true;
42846
42895
  const pos = tr.selection.from;
42847
42896
  tr.replaceSelectionWith(newTaskList);
42848
- const resolvedPos = tr.doc.resolve(pos + 2 + textLen);
42897
+ const resolvedPos = tr.doc.resolve(pos + 2 + 4);
42849
42898
  tr.setSelection(cmdState.selection.constructor.near(resolvedPos));
42899
+ return true;
42900
+ }).run();
42901
+ }
42902
+ },
42903
+ title: editor.isActive("taskList") ? "Disable Task List" : "Enable Task List"
42904
+ },
42905
+ /* @__PURE__ */ import_react56.default.createElement(IconTaskList, null)
42906
+ ), /* @__PURE__ */ import_react56.default.createElement(Dropdown, { trigger: { label: "", title: "Task status", className: "todo-arrow-btn" }, keepOpen: true }, ["todo", "working", "blocked", "resolved"].map((status) => {
42907
+ const images = { todo: "https://storage.googleapis.com/rufous-com-bucket-1/static/images/todo-blank.svg", working: "https://storage.googleapis.com/rufous-com-bucket-1/static/images/working.svg", blocked: "https://storage.googleapis.com/rufous-com-bucket-1/static/images/blocked.svg", resolved: "https://storage.googleapis.com/rufous-com-bucket-1/static/images/closed.svg" };
42908
+ const labels = { todo: "Todo", working: "Working", blocked: "Blocked", resolved: "Resolved" };
42909
+ return /* @__PURE__ */ import_react56.default.createElement("button", { key: status, className: "dropdown-item task-status-item", onClick: () => {
42910
+ const { state } = editor;
42911
+ const { schema } = state;
42912
+ const taskItemType = schema.nodes.taskItem;
42913
+ const taskListType = schema.nodes.taskList;
42914
+ if (!taskItemType || !taskListType) return;
42915
+ const statusText = schema.text(labels[status]);
42916
+ const newTaskItem = taskItemType.create({ status, checked: false }, schema.nodes.paragraph.create(null, statusText));
42917
+ editor.chain().focus().command(({ tr, dispatch, state: cmdState }) => {
42918
+ if (!dispatch) return true;
42919
+ const { $from } = tr.selection;
42920
+ let taskItemDepth = -1;
42921
+ for (let d = $from.depth; d > 0; d--) {
42922
+ if ($from.node(d).type.name === "taskItem") {
42923
+ taskItemDepth = d;
42924
+ break;
42850
42925
  }
42851
- return true;
42852
- }).run();
42853
- } }, /* @__PURE__ */ import_react56.default.createElement("span", { className: `task-icon task-${status}` }, /* @__PURE__ */ import_react56.default.createElement("img", { src: images[status], alt: status })), " ", labels[status]);
42854
- })
42855
- )), onClose && /* @__PURE__ */ import_react56.default.createElement("div", { className: "toolbar-row-right" }, /* @__PURE__ */ import_react56.default.createElement(
42926
+ }
42927
+ const textLen = labels[status].length;
42928
+ if (taskItemDepth !== -1) {
42929
+ const afterPos = $from.after(taskItemDepth);
42930
+ tr.insert(afterPos, newTaskItem);
42931
+ const resolvedPos = tr.doc.resolve(afterPos + 2 + textLen);
42932
+ tr.setSelection(cmdState.selection.constructor.near(resolvedPos));
42933
+ } else {
42934
+ const newTaskList = taskListType.create(null, newTaskItem);
42935
+ const pos = tr.selection.from;
42936
+ tr.replaceSelectionWith(newTaskList);
42937
+ const resolvedPos = tr.doc.resolve(pos + 2 + textLen);
42938
+ tr.setSelection(cmdState.selection.constructor.near(resolvedPos));
42939
+ }
42940
+ return true;
42941
+ }).run();
42942
+ } }, /* @__PURE__ */ import_react56.default.createElement("span", { className: `task-icon task-${status}` }, /* @__PURE__ */ import_react56.default.createElement("img", { src: images[status], alt: status })), " ", labels[status]);
42943
+ })))), onClose && /* @__PURE__ */ import_react56.default.createElement("div", { className: "toolbar-row-right" }, /* @__PURE__ */ import_react56.default.createElement(
42856
42944
  "button",
42857
42945
  {
42858
42946
  className: "toolbar-btn btn-cross",
@@ -43414,9 +43502,13 @@ var RufousTextEditor = ({
43414
43502
  onImageUpload,
43415
43503
  onClose,
43416
43504
  mentions,
43505
+ height,
43506
+ resizable = false,
43417
43507
  className,
43418
- style
43508
+ style,
43509
+ sx
43419
43510
  }) => {
43511
+ const sxClass = useSx(sx);
43420
43512
  const mentionSuggestion = (0, import_react59.useMemo)(() => createMentionSuggestion(mentions), [mentions]);
43421
43513
  const onChangeRef = (0, import_react59.useRef)(onChange);
43422
43514
  const onBlurRef = (0, import_react59.useRef)(onBlur);
@@ -43539,8 +43631,31 @@ var RufousTextEditor = ({
43539
43631
  if (!editor) return;
43540
43632
  const attrs = editor.getAttributes("link");
43541
43633
  const previousUrl = attrs.href || "";
43542
- const { from, to } = editor.state.selection;
43543
- const selectedText = editor.state.doc.textBetween(from, to, "");
43634
+ let { from, to } = editor.state.selection;
43635
+ let selectedText = editor.state.doc.textBetween(from, to, "");
43636
+ if (!selectedText && editor.isActive("link")) {
43637
+ const $pos = editor.state.selection.$from;
43638
+ const linkMark = editor.state.schema.marks.link;
43639
+ const parent = $pos.parent;
43640
+ let offset3 = $pos.parentOffset;
43641
+ let start = 0, end = 0, found2 = false;
43642
+ parent.forEach((child, childOffset) => {
43643
+ if (child.isText && child.marks.some((m) => m.type === linkMark)) {
43644
+ const childStart = childOffset;
43645
+ const childEnd = childOffset + child.nodeSize;
43646
+ if (childStart <= offset3 && childEnd >= offset3) {
43647
+ start = $pos.start() + childStart;
43648
+ end = $pos.start() + childEnd;
43649
+ found2 = true;
43650
+ }
43651
+ }
43652
+ });
43653
+ if (found2) {
43654
+ from = start;
43655
+ to = end;
43656
+ selectedText = editor.state.doc.textBetween(from, to, "");
43657
+ }
43658
+ }
43544
43659
  setLinkUrl(previousUrl);
43545
43660
  setLinkText(selectedText || previousUrl);
43546
43661
  setLinkClassName(attrs.class && attrs.class !== "editor-link" ? attrs.class : "");
@@ -43621,201 +43736,214 @@ var RufousTextEditor = ({
43621
43736
  }
43622
43737
  }, [editor]);
43623
43738
  const providerValue = (0, import_react59.useMemo)(() => ({ editor }), [editor]);
43624
- return /* @__PURE__ */ import_react59.default.createElement("div", { className: `rf-rte-wrapper editor-wrapper ${className || ""}`, style }, /* @__PURE__ */ import_react59.default.createElement(import_react60.EditorContext.Provider, { value: providerValue }, /* @__PURE__ */ import_react59.default.createElement(
43625
- Toolbar_default,
43626
- {
43627
- editor,
43628
- setLink,
43629
- onAICommand,
43630
- onTranslate,
43631
- onSpeechToText,
43632
- onTextToSpeech,
43633
- onImageUpload,
43634
- onClose
43635
- }
43636
- ), /* @__PURE__ */ import_react59.default.createElement(import_react60.EditorContent, { editor, className: "editor-content-wrapper" }), /* @__PURE__ */ import_react59.default.createElement(ImageToolbar_default, { editor }), /* @__PURE__ */ import_react59.default.createElement(VideoToolbar_default, { editor }), editor && /* @__PURE__ */ import_react59.default.createElement(
43637
- import_react60.BubbleMenu,
43739
+ return /* @__PURE__ */ import_react59.default.createElement(
43740
+ "div",
43638
43741
  {
43639
- editor,
43640
- className: "bubble-menu",
43641
- shouldShow: ({ editor: e }) => {
43642
- if (!e || e.isDestroyed) return false;
43643
- try {
43644
- const { selection } = e.state;
43645
- if (selection?.node?.type.name === "image") return false;
43646
- if (selection?.node?.type.name === "youtube") return false;
43647
- if (selection?.node?.type.name === "video") return false;
43648
- return !selection.empty;
43649
- } catch {
43650
- return false;
43651
- }
43742
+ className: `rf-rte-wrapper editor-wrapper ${resizable ? "rf-rte-resizable" : ""} ${sxClass} ${className || ""}`,
43743
+ style: {
43744
+ ...style,
43745
+ ...height ? { height: typeof height === "number" ? `${height}px` : height } : {}
43652
43746
  }
43653
43747
  },
43654
- /* @__PURE__ */ import_react59.default.createElement(
43655
- "button",
43748
+ /* @__PURE__ */ import_react59.default.createElement(import_react60.EditorContext.Provider, { value: providerValue }, /* @__PURE__ */ import_react59.default.createElement(
43749
+ Toolbar_default,
43656
43750
  {
43657
- onClick: () => editor?.chain().focus().toggleBold().run(),
43658
- className: editor?.isActive("bold") ? "is-active" : ""
43659
- },
43660
- /* @__PURE__ */ import_react59.default.createElement("strong", null, "B")
43661
- ),
43662
- /* @__PURE__ */ import_react59.default.createElement(
43663
- "button",
43751
+ editor,
43752
+ setLink,
43753
+ onAICommand,
43754
+ onTranslate,
43755
+ onSpeechToText,
43756
+ onTextToSpeech,
43757
+ onImageUpload,
43758
+ onClose
43759
+ }
43760
+ ), /* @__PURE__ */ import_react59.default.createElement(import_react60.EditorContent, { editor, className: "editor-content-wrapper" }), /* @__PURE__ */ import_react59.default.createElement(ImageToolbar_default, { editor }), /* @__PURE__ */ import_react59.default.createElement(VideoToolbar_default, { editor }), editor && /* @__PURE__ */ import_react59.default.createElement(
43761
+ import_react60.BubbleMenu,
43664
43762
  {
43665
- onClick: () => editor?.chain().focus().toggleItalic().run(),
43666
- className: editor?.isActive("italic") ? "is-active" : ""
43763
+ editor,
43764
+ className: "bubble-menu",
43765
+ shouldShow: ({ editor: e }) => {
43766
+ if (!e || e.isDestroyed) return false;
43767
+ try {
43768
+ const { selection } = e.state;
43769
+ if (selection?.node?.type.name === "image") return false;
43770
+ if (selection?.node?.type.name === "youtube") return false;
43771
+ if (selection?.node?.type.name === "video") return false;
43772
+ return !selection.empty;
43773
+ } catch {
43774
+ return false;
43775
+ }
43776
+ }
43667
43777
  },
43668
- /* @__PURE__ */ import_react59.default.createElement("em", null, "I")
43669
- ),
43670
- /* @__PURE__ */ import_react59.default.createElement(
43671
- "button",
43778
+ /* @__PURE__ */ import_react59.default.createElement(
43779
+ "button",
43780
+ {
43781
+ onClick: () => editor?.chain().focus().toggleBold().run(),
43782
+ className: editor?.isActive("bold") ? "is-active" : ""
43783
+ },
43784
+ /* @__PURE__ */ import_react59.default.createElement("strong", null, "B")
43785
+ ),
43786
+ /* @__PURE__ */ import_react59.default.createElement(
43787
+ "button",
43788
+ {
43789
+ onClick: () => editor?.chain().focus().toggleItalic().run(),
43790
+ className: editor?.isActive("italic") ? "is-active" : ""
43791
+ },
43792
+ /* @__PURE__ */ import_react59.default.createElement("em", null, "I")
43793
+ ),
43794
+ /* @__PURE__ */ import_react59.default.createElement(
43795
+ "button",
43796
+ {
43797
+ onClick: () => editor?.chain().focus().toggleStrike().run(),
43798
+ className: editor?.isActive("strike") ? "is-active" : ""
43799
+ },
43800
+ /* @__PURE__ */ import_react59.default.createElement("s", null, "S")
43801
+ ),
43802
+ /* @__PURE__ */ import_react59.default.createElement(
43803
+ "button",
43804
+ {
43805
+ onClick: () => editor?.chain().focus().toggleCode().run(),
43806
+ className: editor?.isActive("code") ? "is-active" : ""
43807
+ },
43808
+ "</>"
43809
+ ),
43810
+ /* @__PURE__ */ import_react59.default.createElement(
43811
+ "button",
43812
+ {
43813
+ onClick: setLink,
43814
+ className: editor?.isActive("link") ? "is-active" : ""
43815
+ },
43816
+ "\u{1F517}"
43817
+ )
43818
+ ), editor && /* @__PURE__ */ import_react59.default.createElement(
43819
+ import_react60.FloatingMenu,
43672
43820
  {
43673
- onClick: () => editor?.chain().focus().toggleStrike().run(),
43674
- className: editor?.isActive("strike") ? "is-active" : ""
43821
+ editor,
43822
+ className: "floating-menu",
43823
+ shouldShow: ({ editor: e }) => {
43824
+ if (!e || e.isDestroyed) return false;
43825
+ try {
43826
+ const { selection } = e.state;
43827
+ return selection.empty && e.state.doc.textContent.length === 0;
43828
+ } catch {
43829
+ return false;
43830
+ }
43831
+ }
43675
43832
  },
43676
- /* @__PURE__ */ import_react59.default.createElement("s", null, "S")
43677
- ),
43678
- /* @__PURE__ */ import_react59.default.createElement(
43679
- "button",
43833
+ /* @__PURE__ */ import_react59.default.createElement(
43834
+ "button",
43835
+ {
43836
+ onClick: () => editor?.chain().focus().toggleHeading({ level: 1 }).run(),
43837
+ className: editor?.isActive("heading", { level: 1 }) ? "is-active" : ""
43838
+ },
43839
+ "H1"
43840
+ ),
43841
+ /* @__PURE__ */ import_react59.default.createElement(
43842
+ "button",
43843
+ {
43844
+ onClick: () => editor?.chain().focus().toggleHeading({ level: 2 }).run(),
43845
+ className: editor?.isActive("heading", { level: 2 }) ? "is-active" : ""
43846
+ },
43847
+ "H2"
43848
+ ),
43849
+ /* @__PURE__ */ import_react59.default.createElement(
43850
+ "button",
43851
+ {
43852
+ onClick: () => editor?.chain().focus().toggleBulletList().run(),
43853
+ className: editor?.isActive("bulletList") ? "is-active" : ""
43854
+ },
43855
+ "\u2022 List"
43856
+ ),
43857
+ /* @__PURE__ */ import_react59.default.createElement(
43858
+ "button",
43859
+ {
43860
+ onClick: () => editor?.chain().focus().toggleOrderedList().run(),
43861
+ className: editor?.isActive("orderedList") ? "is-active" : ""
43862
+ },
43863
+ "1. List"
43864
+ ),
43865
+ /* @__PURE__ */ import_react59.default.createElement(
43866
+ "button",
43867
+ {
43868
+ onClick: () => editor?.chain().focus().toggleBlockquote().run(),
43869
+ className: editor?.isActive("blockquote") ? "is-active" : ""
43870
+ },
43871
+ "\u201C Quote"
43872
+ )
43873
+ ), /* @__PURE__ */ import_react59.default.createElement("div", { className: "status-bar" }, /* @__PURE__ */ import_react59.default.createElement("div", { className: "status-bar-left" }, /* @__PURE__ */ import_react59.default.createElement(
43874
+ "select",
43680
43875
  {
43681
- onClick: () => editor?.chain().focus().toggleCode().run(),
43682
- className: editor?.isActive("code") ? "is-active" : ""
43876
+ value: saveFormat,
43877
+ onChange: (e) => setSaveFormat(e.target.value),
43878
+ className: "format-select"
43683
43879
  },
43684
- "</>"
43685
- ),
43686
- /* @__PURE__ */ import_react59.default.createElement(
43687
- "button",
43880
+ /* @__PURE__ */ import_react59.default.createElement("option", { value: "html" }, "HTML"),
43881
+ /* @__PURE__ */ import_react59.default.createElement("option", { value: "json" }, "JSON")
43882
+ ), onSaveProp && /* @__PURE__ */ import_react59.default.createElement("button", { onClick: handleSave, className: "status-btn save-btn" }, "Save"), onExportProp && /* @__PURE__ */ import_react59.default.createElement("button", { onClick: handleExport, className: "status-btn export-btn" }, "Export"), /* @__PURE__ */ import_react59.default.createElement("button", { onClick: handleClear, className: "status-btn clear-btn" }, "Clear")), /* @__PURE__ */ import_react59.default.createElement("div", { className: "status-bar-right" }, saveStatus && /* @__PURE__ */ import_react59.default.createElement("span", { className: "save-status" }, saveStatus), editor && /* @__PURE__ */ import_react59.default.createElement(import_react59.default.Fragment, null, /* @__PURE__ */ import_react59.default.createElement("span", { className: "word-count" }, "CHARS: ", editor.storage.characterCount?.characters?.() ?? editor.getText().length), /* @__PURE__ */ import_react59.default.createElement("span", { className: "word-count" }, "WORDS: ", editor.storage.characterCount?.words?.() ?? editor.getText().split(/\s+/).filter(Boolean).length)))), linkModalOpen && /* @__PURE__ */ import_react59.default.createElement("div", { className: "link-modal-overlay", onClick: handleLinkCancel }, /* @__PURE__ */ import_react59.default.createElement("div", { className: "link-modal", onClick: (e) => e.stopPropagation() }, /* @__PURE__ */ import_react59.default.createElement("div", { className: "link-modal-body" }, /* @__PURE__ */ import_react59.default.createElement("div", { className: "link-modal-field" }, /* @__PURE__ */ import_react59.default.createElement("label", { className: "link-modal-label" }, "URL"), /* @__PURE__ */ import_react59.default.createElement(
43883
+ "input",
43688
43884
  {
43689
- onClick: setLink,
43690
- className: editor?.isActive("link") ? "is-active" : ""
43691
- },
43692
- "\u{1F517}"
43693
- )
43694
- ), editor && /* @__PURE__ */ import_react59.default.createElement(
43695
- import_react60.FloatingMenu,
43696
- {
43697
- editor,
43698
- className: "floating-menu",
43699
- shouldShow: ({ editor: e }) => {
43700
- if (!e || e.isDestroyed) return false;
43701
- try {
43702
- const { selection } = e.state;
43703
- return selection.empty && e.state.doc.textContent.length === 0;
43704
- } catch {
43705
- return false;
43706
- }
43885
+ type: "url",
43886
+ className: "link-modal-input",
43887
+ value: linkUrl,
43888
+ onChange: (e) => setLinkUrl(e.target.value),
43889
+ onKeyDown: (e) => {
43890
+ if (e.key === "Enter") handleLinkSubmit();
43891
+ },
43892
+ placeholder: "https://example.com",
43893
+ autoFocus: true
43707
43894
  }
43708
- },
43709
- /* @__PURE__ */ import_react59.default.createElement(
43710
- "button",
43711
- {
43712
- onClick: () => editor?.chain().focus().toggleHeading({ level: 1 }).run(),
43713
- className: editor?.isActive("heading", { level: 1 }) ? "is-active" : ""
43714
- },
43715
- "H1"
43716
- ),
43717
- /* @__PURE__ */ import_react59.default.createElement(
43718
- "button",
43895
+ )), /* @__PURE__ */ import_react59.default.createElement("div", { className: "link-modal-field" }, /* @__PURE__ */ import_react59.default.createElement("label", { className: "link-modal-label" }, "Text"), /* @__PURE__ */ import_react59.default.createElement(
43896
+ "input",
43719
43897
  {
43720
- onClick: () => editor?.chain().focus().toggleHeading({ level: 2 }).run(),
43721
- className: editor?.isActive("heading", { level: 2 }) ? "is-active" : ""
43722
- },
43723
- "H2"
43724
- ),
43725
- /* @__PURE__ */ import_react59.default.createElement(
43726
- "button",
43898
+ type: "text",
43899
+ className: "link-modal-input",
43900
+ value: linkText,
43901
+ onChange: (e) => setLinkText(e.target.value),
43902
+ onKeyDown: (e) => {
43903
+ if (e.key === "Enter") handleLinkSubmit();
43904
+ },
43905
+ placeholder: "Link text"
43906
+ }
43907
+ )), /* @__PURE__ */ import_react59.default.createElement("div", { className: "link-modal-field" }, /* @__PURE__ */ import_react59.default.createElement("label", { className: "link-modal-label" }, "Class name"), /* @__PURE__ */ import_react59.default.createElement(
43908
+ "input",
43727
43909
  {
43728
- onClick: () => editor?.chain().focus().toggleBulletList().run(),
43729
- className: editor?.isActive("bulletList") ? "is-active" : ""
43730
- },
43731
- "\u2022 List"
43732
- ),
43733
- /* @__PURE__ */ import_react59.default.createElement(
43734
- "button",
43910
+ type: "text",
43911
+ className: "link-modal-input",
43912
+ value: linkClassName,
43913
+ onChange: (e) => setLinkClassName(e.target.value),
43914
+ onKeyDown: (e) => {
43915
+ if (e.key === "Enter") handleLinkSubmit();
43916
+ },
43917
+ placeholder: ""
43918
+ }
43919
+ )), /* @__PURE__ */ import_react59.default.createElement("div", { className: "link-modal-checkboxes" }, /* @__PURE__ */ import_react59.default.createElement("label", { className: "link-modal-checkbox" }, /* @__PURE__ */ import_react59.default.createElement(
43920
+ "input",
43735
43921
  {
43736
- onClick: () => editor?.chain().focus().toggleOrderedList().run(),
43737
- className: editor?.isActive("orderedList") ? "is-active" : ""
43738
- },
43739
- "1. List"
43740
- ),
43741
- /* @__PURE__ */ import_react59.default.createElement(
43742
- "button",
43922
+ type: "checkbox",
43923
+ checked: linkNewTab,
43924
+ onChange: (e) => setLinkNewTab(e.target.checked)
43925
+ }
43926
+ ), "Open in new tab"), /* @__PURE__ */ import_react59.default.createElement("label", { className: "link-modal-checkbox" }, /* @__PURE__ */ import_react59.default.createElement(
43927
+ "input",
43743
43928
  {
43744
- onClick: () => editor?.chain().focus().toggleBlockquote().run(),
43745
- className: editor?.isActive("blockquote") ? "is-active" : ""
43746
- },
43747
- "\u201C Quote"
43748
- )
43749
- ), /* @__PURE__ */ import_react59.default.createElement("div", { className: "status-bar" }, /* @__PURE__ */ import_react59.default.createElement("div", { className: "status-bar-left" }, /* @__PURE__ */ import_react59.default.createElement(
43750
- "select",
43751
- {
43752
- value: saveFormat,
43753
- onChange: (e) => setSaveFormat(e.target.value),
43754
- className: "format-select"
43755
- },
43756
- /* @__PURE__ */ import_react59.default.createElement("option", { value: "html" }, "HTML"),
43757
- /* @__PURE__ */ import_react59.default.createElement("option", { value: "json" }, "JSON")
43758
- ), onSaveProp && /* @__PURE__ */ import_react59.default.createElement("button", { onClick: handleSave, className: "status-btn save-btn" }, "Save"), onExportProp && /* @__PURE__ */ import_react59.default.createElement("button", { onClick: handleExport, className: "status-btn export-btn" }, "Export"), /* @__PURE__ */ import_react59.default.createElement("button", { onClick: handleClear, className: "status-btn clear-btn" }, "Clear")), /* @__PURE__ */ import_react59.default.createElement("div", { className: "status-bar-right" }, saveStatus && /* @__PURE__ */ import_react59.default.createElement("span", { className: "save-status" }, saveStatus), editor && /* @__PURE__ */ import_react59.default.createElement(import_react59.default.Fragment, null, /* @__PURE__ */ import_react59.default.createElement("span", { className: "word-count" }, "CHARS: ", editor.storage.characterCount?.characters?.() ?? editor.getText().length), /* @__PURE__ */ import_react59.default.createElement("span", { className: "word-count" }, "WORDS: ", editor.storage.characterCount?.words?.() ?? editor.getText().split(/\s+/).filter(Boolean).length)))), linkModalOpen && /* @__PURE__ */ import_react59.default.createElement("div", { className: "link-modal-overlay", onClick: handleLinkCancel }, /* @__PURE__ */ import_react59.default.createElement("div", { className: "link-modal", onClick: (e) => e.stopPropagation() }, /* @__PURE__ */ import_react59.default.createElement("div", { className: "link-modal-body" }, /* @__PURE__ */ import_react59.default.createElement("div", { className: "link-modal-field" }, /* @__PURE__ */ import_react59.default.createElement("label", { className: "link-modal-label" }, "URL"), /* @__PURE__ */ import_react59.default.createElement(
43759
- "input",
43760
- {
43761
- type: "url",
43762
- className: "link-modal-input",
43763
- value: linkUrl,
43764
- onChange: (e) => setLinkUrl(e.target.value),
43765
- onKeyDown: (e) => {
43766
- if (e.key === "Enter") handleLinkSubmit();
43767
- },
43768
- placeholder: "https://example.com",
43769
- autoFocus: true
43770
- }
43771
- )), /* @__PURE__ */ import_react59.default.createElement("div", { className: "link-modal-field" }, /* @__PURE__ */ import_react59.default.createElement("label", { className: "link-modal-label" }, "Text"), /* @__PURE__ */ import_react59.default.createElement(
43772
- "input",
43773
- {
43774
- type: "text",
43775
- className: "link-modal-input",
43776
- value: linkText,
43777
- onChange: (e) => setLinkText(e.target.value),
43778
- onKeyDown: (e) => {
43779
- if (e.key === "Enter") handleLinkSubmit();
43780
- },
43781
- placeholder: "Link text"
43782
- }
43783
- )), /* @__PURE__ */ import_react59.default.createElement("div", { className: "link-modal-field" }, /* @__PURE__ */ import_react59.default.createElement("label", { className: "link-modal-label" }, "Class name"), /* @__PURE__ */ import_react59.default.createElement(
43784
- "input",
43785
- {
43786
- type: "text",
43787
- className: "link-modal-input",
43788
- value: linkClassName,
43789
- onChange: (e) => setLinkClassName(e.target.value),
43790
- onKeyDown: (e) => {
43791
- if (e.key === "Enter") handleLinkSubmit();
43792
- },
43793
- placeholder: ""
43794
- }
43795
- )), /* @__PURE__ */ import_react59.default.createElement("div", { className: "link-modal-checkboxes" }, /* @__PURE__ */ import_react59.default.createElement("label", { className: "link-modal-checkbox" }, /* @__PURE__ */ import_react59.default.createElement(
43796
- "input",
43797
- {
43798
- type: "checkbox",
43799
- checked: linkNewTab,
43800
- onChange: (e) => setLinkNewTab(e.target.checked)
43801
- }
43802
- ), "Open in new tab"), /* @__PURE__ */ import_react59.default.createElement("label", { className: "link-modal-checkbox" }, /* @__PURE__ */ import_react59.default.createElement(
43803
- "input",
43929
+ type: "checkbox",
43930
+ checked: linkNoFollow,
43931
+ onChange: (e) => setLinkNoFollow(e.target.checked)
43932
+ }
43933
+ ), "No follow"))), /* @__PURE__ */ import_react59.default.createElement("div", { className: "link-modal-footer" }, /* @__PURE__ */ import_react59.default.createElement("button", { className: "link-modal-btn-unlink", onClick: handleLinkRemove }, "Unlink"), /* @__PURE__ */ import_react59.default.createElement("button", { className: "link-modal-btn-apply", onClick: handleLinkSubmit }, "Update")))))
43934
+ );
43935
+ };
43936
+ var RufousTextContent = ({ content, className, style, sx }) => {
43937
+ const sxClass = useSx(sx);
43938
+ return /* @__PURE__ */ import_react59.default.createElement(
43939
+ "div",
43804
43940
  {
43805
- type: "checkbox",
43806
- checked: linkNoFollow,
43807
- onChange: (e) => setLinkNoFollow(e.target.checked)
43941
+ className: `rf-rte-content ${sxClass} ${className || ""}`,
43942
+ style,
43943
+ dangerouslySetInnerHTML: { __html: content }
43808
43944
  }
43809
- ), "No follow"))), /* @__PURE__ */ import_react59.default.createElement("div", { className: "link-modal-footer" }, /* @__PURE__ */ import_react59.default.createElement("button", { className: "link-modal-btn-unlink", onClick: handleLinkRemove }, "Unlink"), /* @__PURE__ */ import_react59.default.createElement("button", { className: "link-modal-btn-apply", onClick: handleLinkSubmit }, "Update"))))));
43945
+ );
43810
43946
  };
43811
- var RufousTextContent = ({ content, className, style }) => /* @__PURE__ */ import_react59.default.createElement(
43812
- "div",
43813
- {
43814
- className: `rf-rte-content ${className || ""}`,
43815
- style,
43816
- dangerouslySetInnerHTML: { __html: content }
43817
- }
43818
- );
43819
43947
  // Annotate the CommonJS export names for ESM import in node:
43820
43948
  0 && (module.exports = {
43821
43949
  APP_THEMES,