@rufous/ui 0.1.99 → 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.js CHANGED
@@ -13100,10 +13100,35 @@ var CustomTaskItem = TaskItem.extend({
13100
13100
  const from = $from.before(taskItemDepth);
13101
13101
  const to = $from.after(taskItemDepth);
13102
13102
  tr.delete(from, to);
13103
- tr.setSelection(TextSelection.near(tr.doc.resolve(Math.max(0, from))));
13103
+ tr.setSelection(TextSelection.near(tr.doc.resolve(Math.max(0, from)), -1));
13104
13104
  this.editor.view.dispatch(tr);
13105
13105
  return true;
13106
13106
  }
13107
+ const indexInList = taskListDepth !== -1 ? $from.index(taskListDepth) : -1;
13108
+ if (indexInList > 0 && taskListDepth !== -1) {
13109
+ const tr = state.tr;
13110
+ const itemStart = $from.before(taskItemDepth);
13111
+ const itemEnd = $from.after(taskItemDepth);
13112
+ const posBefore = itemStart;
13113
+ if (tr.doc.resolve(posBefore).nodeBefore) {
13114
+ const textContent = taskItem.textContent;
13115
+ const contentSlice = taskItem.content;
13116
+ tr.delete(itemStart, itemEnd);
13117
+ const prevItemEndPos = Math.max(0, itemStart - 1);
13118
+ const $prevEnd = tr.doc.resolve(prevItemEndPos);
13119
+ const prevParaEnd = $prevEnd.end($prevEnd.depth);
13120
+ let insertAt = prevParaEnd;
13121
+ contentSlice.forEach((child) => {
13122
+ child.content.forEach((inline) => {
13123
+ tr.insert(insertAt, inline);
13124
+ insertAt += inline.nodeSize;
13125
+ });
13126
+ });
13127
+ tr.setSelection(TextSelection.create(tr.doc, prevParaEnd));
13128
+ this.editor.view.dispatch(tr);
13129
+ return true;
13130
+ }
13131
+ }
13107
13132
  return this.editor.commands.liftListItem(this.name);
13108
13133
  },
13109
13134
  "Shift-Tab": () => this.editor.commands.liftListItem(this.name),
@@ -13219,6 +13244,7 @@ var IconFullscreen = () => /* @__PURE__ */ React112.createElement("svg", { ...s
13219
13244
  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" }));
13220
13245
  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" }));
13221
13246
  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" }));
13247
+ 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" }));
13222
13248
 
13223
13249
  // lib/RufousTextEditor/Toolbar.tsx
13224
13250
  var COLOR_PALETTE = [
@@ -13684,6 +13710,15 @@ var Toolbar = ({ editor, setLink, onAICommand, onTranslate, onSpeechToText, onTe
13684
13710
  setTimeout(() => setCopySuccess(false), 2e3);
13685
13711
  }
13686
13712
  }, [editor]);
13713
+ const handlePaste = useCallback12(async () => {
13714
+ if (!editor) return;
13715
+ try {
13716
+ const text = await navigator.clipboard.readText();
13717
+ if (text) editor.chain().focus().insertContent(text).run();
13718
+ } catch {
13719
+ document.execCommand("paste");
13720
+ }
13721
+ }, [editor]);
13687
13722
  const handleQuickTranslate = useCallback12(async () => {
13688
13723
  if (!editor) return;
13689
13724
  const { from, to, empty } = editor.state.selection;
@@ -14114,6 +14149,14 @@ var Toolbar = ({ editor, setLink, onAICommand, onTranslate, onSpeechToText, onTe
14114
14149
  title: "Copy selected text"
14115
14150
  },
14116
14151
  copySuccess ? /* @__PURE__ */ React113.createElement(IconCheck, null) : /* @__PURE__ */ React113.createElement(IconCopy, null)
14152
+ ), /* @__PURE__ */ React113.createElement(
14153
+ "button",
14154
+ {
14155
+ className: "toolbar-btn",
14156
+ onClick: handlePaste,
14157
+ title: "Paste (Ctrl+V)"
14158
+ },
14159
+ /* @__PURE__ */ React113.createElement(IconPaste, null)
14117
14160
  ), /* @__PURE__ */ React113.createElement(Dropdown, { trigger: { label: "\u03A9", title: "Special characters", className: "special-characters-btn" } }, /* @__PURE__ */ React113.createElement("div", { className: "char-grid" }, SPECIAL_CHARS.map((char) => /* @__PURE__ */ React113.createElement(
14118
14161
  "button",
14119
14162
  {
@@ -14125,10 +14168,26 @@ var Toolbar = ({ editor, setLink, onAICommand, onTranslate, onSpeechToText, onTe
14125
14168
  )))), /* @__PURE__ */ React113.createElement(
14126
14169
  Dropdown,
14127
14170
  {
14128
- trigger: { label: /* @__PURE__ */ React113.createElement(IconCode, null), title: "Code", className: editor.isActive("code") ? "is-active" : "" }
14171
+ trigger: { label: /* @__PURE__ */ React113.createElement(IconCode, null), title: "Code", className: editor.isActive("code") || editor.isActive("codeBlock") ? "is-active" : "" }
14129
14172
  },
14130
14173
  /* @__PURE__ */ React113.createElement("button", { className: "dropdown-item", onClick: () => editor.chain().focus().toggleCode().run() }, "</>", " Inline Code"),
14131
- /* @__PURE__ */ React113.createElement("button", { className: "dropdown-item", onClick: () => editor.chain().focus().toggleCodeBlock().run() }, "{ }", " Code Block")
14174
+ /* @__PURE__ */ React113.createElement("button", { className: "dropdown-item", onClick: () => editor.chain().focus().toggleCodeBlock().run() }, "{ }", " Code Block"),
14175
+ editor.isActive("codeBlock") && /* @__PURE__ */ React113.createElement("button", { className: "dropdown-item", onClick: () => {
14176
+ const text = (() => {
14177
+ const { $from } = editor.state.selection;
14178
+ for (let d = $from.depth; d > 0; d--) {
14179
+ if ($from.node(d).type.name === "codeBlock") return $from.node(d).textContent;
14180
+ }
14181
+ return "";
14182
+ })();
14183
+ if (text) {
14184
+ editor.chain().focus().toggleCodeBlock().run();
14185
+ const { from } = editor.state.selection;
14186
+ editor.chain().focus().setTextSelection({ from, to: from + text.length }).toggleCode().run();
14187
+ } else {
14188
+ editor.chain().focus().toggleCodeBlock().run();
14189
+ }
14190
+ } }, "</> \u2190", " Convert to Inline Code")
14132
14191
  ), /* @__PURE__ */ React113.createElement(
14133
14192
  "button",
14134
14193
  {
@@ -14145,52 +14204,73 @@ var Toolbar = ({ editor, setLink, onAICommand, onTranslate, onSpeechToText, onTe
14145
14204
  title: "Translate selected text"
14146
14205
  },
14147
14206
  /* @__PURE__ */ React113.createElement(IconTranslate, null)
14148
- ), /* @__PURE__ */ React113.createElement(Dropdown, { trigger: { label: "", title: "Translate options", className: "translate-arrow-btn" } }, /* @__PURE__ */ React113.createElement("button", { className: "dropdown-item", onClick: () => setShowTranslateModal(true) }, "Options")), translateStatus && /* @__PURE__ */ React113.createElement("span", { className: `translate-toast-popup ${translateStatus === "Please select the text" || translateStatus === "Translation failed" ? "error" : ""}` }, translateStatus)), /* @__PURE__ */ React113.createElement(
14149
- Dropdown,
14207
+ ), /* @__PURE__ */ React113.createElement(Dropdown, { trigger: { label: "", title: "Translate options", className: "translate-arrow-btn" } }, /* @__PURE__ */ React113.createElement("button", { className: "dropdown-item", onClick: () => setShowTranslateModal(true) }, "Options")), translateStatus && /* @__PURE__ */ React113.createElement("span", { className: `translate-toast-popup ${translateStatus === "Please select the text" || translateStatus === "Translation failed" ? "error" : ""}` }, translateStatus)), /* @__PURE__ */ React113.createElement("div", { className: "todo-split-btn" }, /* @__PURE__ */ React113.createElement(
14208
+ "button",
14150
14209
  {
14151
- trigger: { label: /* @__PURE__ */ React113.createElement(IconTaskList, null), title: "Task list", className: editor.isActive("taskList") ? "is-active" : "" },
14152
- keepOpen: true
14153
- },
14154
- ["todo", "working", "blocked", "resolved"].map((status) => {
14155
- const symbols = { todo: "\u2610", working: "\u27F3", blocked: "\u25A0", resolved: "\u2611" };
14156
- 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" };
14157
- const labels = { todo: "Todo", working: "Working", blocked: "Blocked", resolved: "Resolved" };
14158
- return /* @__PURE__ */ React113.createElement("button", { key: status, className: `dropdown-item task-status-item`, onClick: () => {
14159
- const { state } = editor;
14160
- const { schema } = state;
14161
- const taskItemType = schema.nodes.taskItem;
14162
- const taskListType = schema.nodes.taskList;
14163
- if (!taskItemType || !taskListType) return;
14164
- const statusText = schema.text(labels[status]);
14165
- const newTaskItem = taskItemType.create({ status, checked: false }, schema.nodes.paragraph.create(null, statusText));
14166
- editor.chain().focus().command(({ tr, dispatch, state: cmdState }) => {
14167
- if (!dispatch) return true;
14168
- const { $from } = tr.selection;
14169
- let taskItemDepth = -1;
14170
- for (let d = $from.depth; d > 0; d--) {
14171
- if ($from.node(d).type.name === "taskItem") {
14172
- taskItemDepth = d;
14173
- break;
14174
- }
14175
- }
14176
- const textLen = labels[status].length;
14177
- if (taskItemDepth !== -1) {
14178
- const afterPos = $from.after(taskItemDepth);
14179
- tr.insert(afterPos, newTaskItem);
14180
- const resolvedPos = tr.doc.resolve(afterPos + 2 + textLen);
14181
- tr.setSelection(cmdState.selection.constructor.near(resolvedPos));
14182
- } else {
14183
- const newTaskList = taskListType.create(null, newTaskItem);
14210
+ className: `toolbar-btn ${editor.isActive("taskList") ? "is-active" : ""}`,
14211
+ onClick: () => {
14212
+ if (editor.isActive("taskList")) {
14213
+ editor.chain().focus().liftListItem("taskItem").run();
14214
+ } else {
14215
+ const { state } = editor;
14216
+ const { schema } = state;
14217
+ const taskItemType = schema.nodes.taskItem;
14218
+ const taskListType = schema.nodes.taskList;
14219
+ if (!taskItemType || !taskListType) return;
14220
+ const statusText = schema.text("Todo");
14221
+ const newTaskItem = taskItemType.create({ status: "todo", checked: false }, schema.nodes.paragraph.create(null, statusText));
14222
+ const newTaskList = taskListType.create(null, newTaskItem);
14223
+ editor.chain().focus().command(({ tr, dispatch, state: cmdState }) => {
14224
+ if (!dispatch) return true;
14184
14225
  const pos = tr.selection.from;
14185
14226
  tr.replaceSelectionWith(newTaskList);
14186
- const resolvedPos = tr.doc.resolve(pos + 2 + textLen);
14227
+ const resolvedPos = tr.doc.resolve(pos + 2 + 4);
14187
14228
  tr.setSelection(cmdState.selection.constructor.near(resolvedPos));
14229
+ return true;
14230
+ }).run();
14231
+ }
14232
+ },
14233
+ title: editor.isActive("taskList") ? "Disable Task List" : "Enable Task List"
14234
+ },
14235
+ /* @__PURE__ */ React113.createElement(IconTaskList, null)
14236
+ ), /* @__PURE__ */ React113.createElement(Dropdown, { trigger: { label: "", title: "Task status", className: "todo-arrow-btn" }, keepOpen: true }, ["todo", "working", "blocked", "resolved"].map((status) => {
14237
+ 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" };
14238
+ const labels = { todo: "Todo", working: "Working", blocked: "Blocked", resolved: "Resolved" };
14239
+ return /* @__PURE__ */ React113.createElement("button", { key: status, className: "dropdown-item task-status-item", onClick: () => {
14240
+ const { state } = editor;
14241
+ const { schema } = state;
14242
+ const taskItemType = schema.nodes.taskItem;
14243
+ const taskListType = schema.nodes.taskList;
14244
+ if (!taskItemType || !taskListType) return;
14245
+ const statusText = schema.text(labels[status]);
14246
+ const newTaskItem = taskItemType.create({ status, checked: false }, schema.nodes.paragraph.create(null, statusText));
14247
+ editor.chain().focus().command(({ tr, dispatch, state: cmdState }) => {
14248
+ if (!dispatch) return true;
14249
+ const { $from } = tr.selection;
14250
+ let taskItemDepth = -1;
14251
+ for (let d = $from.depth; d > 0; d--) {
14252
+ if ($from.node(d).type.name === "taskItem") {
14253
+ taskItemDepth = d;
14254
+ break;
14188
14255
  }
14189
- return true;
14190
- }).run();
14191
- } }, /* @__PURE__ */ React113.createElement("span", { className: `task-icon task-${status}` }, /* @__PURE__ */ React113.createElement("img", { src: images[status], alt: status })), " ", labels[status]);
14192
- })
14193
- )), onClose && /* @__PURE__ */ React113.createElement("div", { className: "toolbar-row-right" }, /* @__PURE__ */ React113.createElement(
14256
+ }
14257
+ const textLen = labels[status].length;
14258
+ if (taskItemDepth !== -1) {
14259
+ const afterPos = $from.after(taskItemDepth);
14260
+ tr.insert(afterPos, newTaskItem);
14261
+ const resolvedPos = tr.doc.resolve(afterPos + 2 + textLen);
14262
+ tr.setSelection(cmdState.selection.constructor.near(resolvedPos));
14263
+ } else {
14264
+ const newTaskList = taskListType.create(null, newTaskItem);
14265
+ const pos = tr.selection.from;
14266
+ tr.replaceSelectionWith(newTaskList);
14267
+ const resolvedPos = tr.doc.resolve(pos + 2 + textLen);
14268
+ tr.setSelection(cmdState.selection.constructor.near(resolvedPos));
14269
+ }
14270
+ return true;
14271
+ }).run();
14272
+ } }, /* @__PURE__ */ React113.createElement("span", { className: `task-icon task-${status}` }, /* @__PURE__ */ React113.createElement("img", { src: images[status], alt: status })), " ", labels[status]);
14273
+ })))), onClose && /* @__PURE__ */ React113.createElement("div", { className: "toolbar-row-right" }, /* @__PURE__ */ React113.createElement(
14194
14274
  "button",
14195
14275
  {
14196
14276
  className: "toolbar-btn btn-cross",
@@ -14752,9 +14832,13 @@ var RufousTextEditor = ({
14752
14832
  onImageUpload,
14753
14833
  onClose,
14754
14834
  mentions,
14835
+ height,
14836
+ resizable = false,
14755
14837
  className,
14756
- style
14838
+ style,
14839
+ sx
14757
14840
  }) => {
14841
+ const sxClass = useSx(sx);
14758
14842
  const mentionSuggestion = useMemo4(() => createMentionSuggestion(mentions), [mentions]);
14759
14843
  const onChangeRef = useRef30(onChange);
14760
14844
  const onBlurRef = useRef30(onBlur);
@@ -14877,8 +14961,31 @@ var RufousTextEditor = ({
14877
14961
  if (!editor) return;
14878
14962
  const attrs = editor.getAttributes("link");
14879
14963
  const previousUrl = attrs.href || "";
14880
- const { from, to } = editor.state.selection;
14881
- const selectedText = editor.state.doc.textBetween(from, to, "");
14964
+ let { from, to } = editor.state.selection;
14965
+ let selectedText = editor.state.doc.textBetween(from, to, "");
14966
+ if (!selectedText && editor.isActive("link")) {
14967
+ const $pos = editor.state.selection.$from;
14968
+ const linkMark = editor.state.schema.marks.link;
14969
+ const parent = $pos.parent;
14970
+ let offset2 = $pos.parentOffset;
14971
+ let start = 0, end = 0, found2 = false;
14972
+ parent.forEach((child, childOffset) => {
14973
+ if (child.isText && child.marks.some((m) => m.type === linkMark)) {
14974
+ const childStart = childOffset;
14975
+ const childEnd = childOffset + child.nodeSize;
14976
+ if (childStart <= offset2 && childEnd >= offset2) {
14977
+ start = $pos.start() + childStart;
14978
+ end = $pos.start() + childEnd;
14979
+ found2 = true;
14980
+ }
14981
+ }
14982
+ });
14983
+ if (found2) {
14984
+ from = start;
14985
+ to = end;
14986
+ selectedText = editor.state.doc.textBetween(from, to, "");
14987
+ }
14988
+ }
14882
14989
  setLinkUrl(previousUrl);
14883
14990
  setLinkText(selectedText || previousUrl);
14884
14991
  setLinkClassName(attrs.class && attrs.class !== "editor-link" ? attrs.class : "");
@@ -14959,201 +15066,214 @@ var RufousTextEditor = ({
14959
15066
  }
14960
15067
  }, [editor]);
14961
15068
  const providerValue = useMemo4(() => ({ editor }), [editor]);
14962
- return /* @__PURE__ */ React116.createElement("div", { className: `rf-rte-wrapper editor-wrapper ${className || ""}`, style }, /* @__PURE__ */ React116.createElement(EditorContext.Provider, { value: providerValue }, /* @__PURE__ */ React116.createElement(
14963
- Toolbar_default,
14964
- {
14965
- editor,
14966
- setLink,
14967
- onAICommand,
14968
- onTranslate,
14969
- onSpeechToText,
14970
- onTextToSpeech,
14971
- onImageUpload,
14972
- onClose
14973
- }
14974
- ), /* @__PURE__ */ React116.createElement(EditorContent, { editor, className: "editor-content-wrapper" }), /* @__PURE__ */ React116.createElement(ImageToolbar_default, { editor }), /* @__PURE__ */ React116.createElement(VideoToolbar_default, { editor }), editor && /* @__PURE__ */ React116.createElement(
14975
- BubbleMenu,
15069
+ return /* @__PURE__ */ React116.createElement(
15070
+ "div",
14976
15071
  {
14977
- editor,
14978
- className: "bubble-menu",
14979
- shouldShow: ({ editor: e }) => {
14980
- if (!e || e.isDestroyed) return false;
14981
- try {
14982
- const { selection } = e.state;
14983
- if (selection?.node?.type.name === "image") return false;
14984
- if (selection?.node?.type.name === "youtube") return false;
14985
- if (selection?.node?.type.name === "video") return false;
14986
- return !selection.empty;
14987
- } catch {
14988
- return false;
14989
- }
15072
+ className: `rf-rte-wrapper editor-wrapper ${resizable ? "rf-rte-resizable" : ""} ${sxClass} ${className || ""}`,
15073
+ style: {
15074
+ ...style,
15075
+ ...height ? { height: typeof height === "number" ? `${height}px` : height } : {}
14990
15076
  }
14991
15077
  },
14992
- /* @__PURE__ */ React116.createElement(
14993
- "button",
15078
+ /* @__PURE__ */ React116.createElement(EditorContext.Provider, { value: providerValue }, /* @__PURE__ */ React116.createElement(
15079
+ Toolbar_default,
14994
15080
  {
14995
- onClick: () => editor?.chain().focus().toggleBold().run(),
14996
- className: editor?.isActive("bold") ? "is-active" : ""
14997
- },
14998
- /* @__PURE__ */ React116.createElement("strong", null, "B")
14999
- ),
15000
- /* @__PURE__ */ React116.createElement(
15001
- "button",
15081
+ editor,
15082
+ setLink,
15083
+ onAICommand,
15084
+ onTranslate,
15085
+ onSpeechToText,
15086
+ onTextToSpeech,
15087
+ onImageUpload,
15088
+ onClose
15089
+ }
15090
+ ), /* @__PURE__ */ React116.createElement(EditorContent, { editor, className: "editor-content-wrapper" }), /* @__PURE__ */ React116.createElement(ImageToolbar_default, { editor }), /* @__PURE__ */ React116.createElement(VideoToolbar_default, { editor }), editor && /* @__PURE__ */ React116.createElement(
15091
+ BubbleMenu,
15002
15092
  {
15003
- onClick: () => editor?.chain().focus().toggleItalic().run(),
15004
- className: editor?.isActive("italic") ? "is-active" : ""
15093
+ editor,
15094
+ className: "bubble-menu",
15095
+ shouldShow: ({ editor: e }) => {
15096
+ if (!e || e.isDestroyed) return false;
15097
+ try {
15098
+ const { selection } = e.state;
15099
+ if (selection?.node?.type.name === "image") return false;
15100
+ if (selection?.node?.type.name === "youtube") return false;
15101
+ if (selection?.node?.type.name === "video") return false;
15102
+ return !selection.empty;
15103
+ } catch {
15104
+ return false;
15105
+ }
15106
+ }
15005
15107
  },
15006
- /* @__PURE__ */ React116.createElement("em", null, "I")
15007
- ),
15008
- /* @__PURE__ */ React116.createElement(
15009
- "button",
15108
+ /* @__PURE__ */ React116.createElement(
15109
+ "button",
15110
+ {
15111
+ onClick: () => editor?.chain().focus().toggleBold().run(),
15112
+ className: editor?.isActive("bold") ? "is-active" : ""
15113
+ },
15114
+ /* @__PURE__ */ React116.createElement("strong", null, "B")
15115
+ ),
15116
+ /* @__PURE__ */ React116.createElement(
15117
+ "button",
15118
+ {
15119
+ onClick: () => editor?.chain().focus().toggleItalic().run(),
15120
+ className: editor?.isActive("italic") ? "is-active" : ""
15121
+ },
15122
+ /* @__PURE__ */ React116.createElement("em", null, "I")
15123
+ ),
15124
+ /* @__PURE__ */ React116.createElement(
15125
+ "button",
15126
+ {
15127
+ onClick: () => editor?.chain().focus().toggleStrike().run(),
15128
+ className: editor?.isActive("strike") ? "is-active" : ""
15129
+ },
15130
+ /* @__PURE__ */ React116.createElement("s", null, "S")
15131
+ ),
15132
+ /* @__PURE__ */ React116.createElement(
15133
+ "button",
15134
+ {
15135
+ onClick: () => editor?.chain().focus().toggleCode().run(),
15136
+ className: editor?.isActive("code") ? "is-active" : ""
15137
+ },
15138
+ "</>"
15139
+ ),
15140
+ /* @__PURE__ */ React116.createElement(
15141
+ "button",
15142
+ {
15143
+ onClick: setLink,
15144
+ className: editor?.isActive("link") ? "is-active" : ""
15145
+ },
15146
+ "\u{1F517}"
15147
+ )
15148
+ ), editor && /* @__PURE__ */ React116.createElement(
15149
+ FloatingMenu,
15010
15150
  {
15011
- onClick: () => editor?.chain().focus().toggleStrike().run(),
15012
- className: editor?.isActive("strike") ? "is-active" : ""
15151
+ editor,
15152
+ className: "floating-menu",
15153
+ shouldShow: ({ editor: e }) => {
15154
+ if (!e || e.isDestroyed) return false;
15155
+ try {
15156
+ const { selection } = e.state;
15157
+ return selection.empty && e.state.doc.textContent.length === 0;
15158
+ } catch {
15159
+ return false;
15160
+ }
15161
+ }
15013
15162
  },
15014
- /* @__PURE__ */ React116.createElement("s", null, "S")
15015
- ),
15016
- /* @__PURE__ */ React116.createElement(
15017
- "button",
15163
+ /* @__PURE__ */ React116.createElement(
15164
+ "button",
15165
+ {
15166
+ onClick: () => editor?.chain().focus().toggleHeading({ level: 1 }).run(),
15167
+ className: editor?.isActive("heading", { level: 1 }) ? "is-active" : ""
15168
+ },
15169
+ "H1"
15170
+ ),
15171
+ /* @__PURE__ */ React116.createElement(
15172
+ "button",
15173
+ {
15174
+ onClick: () => editor?.chain().focus().toggleHeading({ level: 2 }).run(),
15175
+ className: editor?.isActive("heading", { level: 2 }) ? "is-active" : ""
15176
+ },
15177
+ "H2"
15178
+ ),
15179
+ /* @__PURE__ */ React116.createElement(
15180
+ "button",
15181
+ {
15182
+ onClick: () => editor?.chain().focus().toggleBulletList().run(),
15183
+ className: editor?.isActive("bulletList") ? "is-active" : ""
15184
+ },
15185
+ "\u2022 List"
15186
+ ),
15187
+ /* @__PURE__ */ React116.createElement(
15188
+ "button",
15189
+ {
15190
+ onClick: () => editor?.chain().focus().toggleOrderedList().run(),
15191
+ className: editor?.isActive("orderedList") ? "is-active" : ""
15192
+ },
15193
+ "1. List"
15194
+ ),
15195
+ /* @__PURE__ */ React116.createElement(
15196
+ "button",
15197
+ {
15198
+ onClick: () => editor?.chain().focus().toggleBlockquote().run(),
15199
+ className: editor?.isActive("blockquote") ? "is-active" : ""
15200
+ },
15201
+ "\u201C Quote"
15202
+ )
15203
+ ), /* @__PURE__ */ React116.createElement("div", { className: "status-bar" }, /* @__PURE__ */ React116.createElement("div", { className: "status-bar-left" }, /* @__PURE__ */ React116.createElement(
15204
+ "select",
15018
15205
  {
15019
- onClick: () => editor?.chain().focus().toggleCode().run(),
15020
- className: editor?.isActive("code") ? "is-active" : ""
15206
+ value: saveFormat,
15207
+ onChange: (e) => setSaveFormat(e.target.value),
15208
+ className: "format-select"
15021
15209
  },
15022
- "</>"
15023
- ),
15024
- /* @__PURE__ */ React116.createElement(
15025
- "button",
15210
+ /* @__PURE__ */ React116.createElement("option", { value: "html" }, "HTML"),
15211
+ /* @__PURE__ */ React116.createElement("option", { value: "json" }, "JSON")
15212
+ ), onSaveProp && /* @__PURE__ */ React116.createElement("button", { onClick: handleSave, className: "status-btn save-btn" }, "Save"), onExportProp && /* @__PURE__ */ React116.createElement("button", { onClick: handleExport, className: "status-btn export-btn" }, "Export"), /* @__PURE__ */ React116.createElement("button", { onClick: handleClear, className: "status-btn clear-btn" }, "Clear")), /* @__PURE__ */ React116.createElement("div", { className: "status-bar-right" }, saveStatus && /* @__PURE__ */ React116.createElement("span", { className: "save-status" }, saveStatus), editor && /* @__PURE__ */ React116.createElement(React116.Fragment, null, /* @__PURE__ */ React116.createElement("span", { className: "word-count" }, "CHARS: ", editor.storage.characterCount?.characters?.() ?? editor.getText().length), /* @__PURE__ */ React116.createElement("span", { className: "word-count" }, "WORDS: ", editor.storage.characterCount?.words?.() ?? editor.getText().split(/\s+/).filter(Boolean).length)))), linkModalOpen && /* @__PURE__ */ React116.createElement("div", { className: "link-modal-overlay", onClick: handleLinkCancel }, /* @__PURE__ */ React116.createElement("div", { className: "link-modal", onClick: (e) => e.stopPropagation() }, /* @__PURE__ */ React116.createElement("div", { className: "link-modal-body" }, /* @__PURE__ */ React116.createElement("div", { className: "link-modal-field" }, /* @__PURE__ */ React116.createElement("label", { className: "link-modal-label" }, "URL"), /* @__PURE__ */ React116.createElement(
15213
+ "input",
15026
15214
  {
15027
- onClick: setLink,
15028
- className: editor?.isActive("link") ? "is-active" : ""
15029
- },
15030
- "\u{1F517}"
15031
- )
15032
- ), editor && /* @__PURE__ */ React116.createElement(
15033
- FloatingMenu,
15034
- {
15035
- editor,
15036
- className: "floating-menu",
15037
- shouldShow: ({ editor: e }) => {
15038
- if (!e || e.isDestroyed) return false;
15039
- try {
15040
- const { selection } = e.state;
15041
- return selection.empty && e.state.doc.textContent.length === 0;
15042
- } catch {
15043
- return false;
15044
- }
15215
+ type: "url",
15216
+ className: "link-modal-input",
15217
+ value: linkUrl,
15218
+ onChange: (e) => setLinkUrl(e.target.value),
15219
+ onKeyDown: (e) => {
15220
+ if (e.key === "Enter") handleLinkSubmit();
15221
+ },
15222
+ placeholder: "https://example.com",
15223
+ autoFocus: true
15045
15224
  }
15046
- },
15047
- /* @__PURE__ */ React116.createElement(
15048
- "button",
15049
- {
15050
- onClick: () => editor?.chain().focus().toggleHeading({ level: 1 }).run(),
15051
- className: editor?.isActive("heading", { level: 1 }) ? "is-active" : ""
15052
- },
15053
- "H1"
15054
- ),
15055
- /* @__PURE__ */ React116.createElement(
15056
- "button",
15225
+ )), /* @__PURE__ */ React116.createElement("div", { className: "link-modal-field" }, /* @__PURE__ */ React116.createElement("label", { className: "link-modal-label" }, "Text"), /* @__PURE__ */ React116.createElement(
15226
+ "input",
15057
15227
  {
15058
- onClick: () => editor?.chain().focus().toggleHeading({ level: 2 }).run(),
15059
- className: editor?.isActive("heading", { level: 2 }) ? "is-active" : ""
15060
- },
15061
- "H2"
15062
- ),
15063
- /* @__PURE__ */ React116.createElement(
15064
- "button",
15228
+ type: "text",
15229
+ className: "link-modal-input",
15230
+ value: linkText,
15231
+ onChange: (e) => setLinkText(e.target.value),
15232
+ onKeyDown: (e) => {
15233
+ if (e.key === "Enter") handleLinkSubmit();
15234
+ },
15235
+ placeholder: "Link text"
15236
+ }
15237
+ )), /* @__PURE__ */ React116.createElement("div", { className: "link-modal-field" }, /* @__PURE__ */ React116.createElement("label", { className: "link-modal-label" }, "Class name"), /* @__PURE__ */ React116.createElement(
15238
+ "input",
15065
15239
  {
15066
- onClick: () => editor?.chain().focus().toggleBulletList().run(),
15067
- className: editor?.isActive("bulletList") ? "is-active" : ""
15068
- },
15069
- "\u2022 List"
15070
- ),
15071
- /* @__PURE__ */ React116.createElement(
15072
- "button",
15240
+ type: "text",
15241
+ className: "link-modal-input",
15242
+ value: linkClassName,
15243
+ onChange: (e) => setLinkClassName(e.target.value),
15244
+ onKeyDown: (e) => {
15245
+ if (e.key === "Enter") handleLinkSubmit();
15246
+ },
15247
+ placeholder: ""
15248
+ }
15249
+ )), /* @__PURE__ */ React116.createElement("div", { className: "link-modal-checkboxes" }, /* @__PURE__ */ React116.createElement("label", { className: "link-modal-checkbox" }, /* @__PURE__ */ React116.createElement(
15250
+ "input",
15073
15251
  {
15074
- onClick: () => editor?.chain().focus().toggleOrderedList().run(),
15075
- className: editor?.isActive("orderedList") ? "is-active" : ""
15076
- },
15077
- "1. List"
15078
- ),
15079
- /* @__PURE__ */ React116.createElement(
15080
- "button",
15252
+ type: "checkbox",
15253
+ checked: linkNewTab,
15254
+ onChange: (e) => setLinkNewTab(e.target.checked)
15255
+ }
15256
+ ), "Open in new tab"), /* @__PURE__ */ React116.createElement("label", { className: "link-modal-checkbox" }, /* @__PURE__ */ React116.createElement(
15257
+ "input",
15081
15258
  {
15082
- onClick: () => editor?.chain().focus().toggleBlockquote().run(),
15083
- className: editor?.isActive("blockquote") ? "is-active" : ""
15084
- },
15085
- "\u201C Quote"
15086
- )
15087
- ), /* @__PURE__ */ React116.createElement("div", { className: "status-bar" }, /* @__PURE__ */ React116.createElement("div", { className: "status-bar-left" }, /* @__PURE__ */ React116.createElement(
15088
- "select",
15089
- {
15090
- value: saveFormat,
15091
- onChange: (e) => setSaveFormat(e.target.value),
15092
- className: "format-select"
15093
- },
15094
- /* @__PURE__ */ React116.createElement("option", { value: "html" }, "HTML"),
15095
- /* @__PURE__ */ React116.createElement("option", { value: "json" }, "JSON")
15096
- ), onSaveProp && /* @__PURE__ */ React116.createElement("button", { onClick: handleSave, className: "status-btn save-btn" }, "Save"), onExportProp && /* @__PURE__ */ React116.createElement("button", { onClick: handleExport, className: "status-btn export-btn" }, "Export"), /* @__PURE__ */ React116.createElement("button", { onClick: handleClear, className: "status-btn clear-btn" }, "Clear")), /* @__PURE__ */ React116.createElement("div", { className: "status-bar-right" }, saveStatus && /* @__PURE__ */ React116.createElement("span", { className: "save-status" }, saveStatus), editor && /* @__PURE__ */ React116.createElement(React116.Fragment, null, /* @__PURE__ */ React116.createElement("span", { className: "word-count" }, "CHARS: ", editor.storage.characterCount?.characters?.() ?? editor.getText().length), /* @__PURE__ */ React116.createElement("span", { className: "word-count" }, "WORDS: ", editor.storage.characterCount?.words?.() ?? editor.getText().split(/\s+/).filter(Boolean).length)))), linkModalOpen && /* @__PURE__ */ React116.createElement("div", { className: "link-modal-overlay", onClick: handleLinkCancel }, /* @__PURE__ */ React116.createElement("div", { className: "link-modal", onClick: (e) => e.stopPropagation() }, /* @__PURE__ */ React116.createElement("div", { className: "link-modal-body" }, /* @__PURE__ */ React116.createElement("div", { className: "link-modal-field" }, /* @__PURE__ */ React116.createElement("label", { className: "link-modal-label" }, "URL"), /* @__PURE__ */ React116.createElement(
15097
- "input",
15098
- {
15099
- type: "url",
15100
- className: "link-modal-input",
15101
- value: linkUrl,
15102
- onChange: (e) => setLinkUrl(e.target.value),
15103
- onKeyDown: (e) => {
15104
- if (e.key === "Enter") handleLinkSubmit();
15105
- },
15106
- placeholder: "https://example.com",
15107
- autoFocus: true
15108
- }
15109
- )), /* @__PURE__ */ React116.createElement("div", { className: "link-modal-field" }, /* @__PURE__ */ React116.createElement("label", { className: "link-modal-label" }, "Text"), /* @__PURE__ */ React116.createElement(
15110
- "input",
15111
- {
15112
- type: "text",
15113
- className: "link-modal-input",
15114
- value: linkText,
15115
- onChange: (e) => setLinkText(e.target.value),
15116
- onKeyDown: (e) => {
15117
- if (e.key === "Enter") handleLinkSubmit();
15118
- },
15119
- placeholder: "Link text"
15120
- }
15121
- )), /* @__PURE__ */ React116.createElement("div", { className: "link-modal-field" }, /* @__PURE__ */ React116.createElement("label", { className: "link-modal-label" }, "Class name"), /* @__PURE__ */ React116.createElement(
15122
- "input",
15123
- {
15124
- type: "text",
15125
- className: "link-modal-input",
15126
- value: linkClassName,
15127
- onChange: (e) => setLinkClassName(e.target.value),
15128
- onKeyDown: (e) => {
15129
- if (e.key === "Enter") handleLinkSubmit();
15130
- },
15131
- placeholder: ""
15132
- }
15133
- )), /* @__PURE__ */ React116.createElement("div", { className: "link-modal-checkboxes" }, /* @__PURE__ */ React116.createElement("label", { className: "link-modal-checkbox" }, /* @__PURE__ */ React116.createElement(
15134
- "input",
15135
- {
15136
- type: "checkbox",
15137
- checked: linkNewTab,
15138
- onChange: (e) => setLinkNewTab(e.target.checked)
15139
- }
15140
- ), "Open in new tab"), /* @__PURE__ */ React116.createElement("label", { className: "link-modal-checkbox" }, /* @__PURE__ */ React116.createElement(
15141
- "input",
15259
+ type: "checkbox",
15260
+ checked: linkNoFollow,
15261
+ onChange: (e) => setLinkNoFollow(e.target.checked)
15262
+ }
15263
+ ), "No follow"))), /* @__PURE__ */ React116.createElement("div", { className: "link-modal-footer" }, /* @__PURE__ */ React116.createElement("button", { className: "link-modal-btn-unlink", onClick: handleLinkRemove }, "Unlink"), /* @__PURE__ */ React116.createElement("button", { className: "link-modal-btn-apply", onClick: handleLinkSubmit }, "Update")))))
15264
+ );
15265
+ };
15266
+ var RufousTextContent = ({ content, className, style, sx }) => {
15267
+ const sxClass = useSx(sx);
15268
+ return /* @__PURE__ */ React116.createElement(
15269
+ "div",
15142
15270
  {
15143
- type: "checkbox",
15144
- checked: linkNoFollow,
15145
- onChange: (e) => setLinkNoFollow(e.target.checked)
15271
+ className: `rf-rte-content ${sxClass} ${className || ""}`,
15272
+ style,
15273
+ dangerouslySetInnerHTML: { __html: content }
15146
15274
  }
15147
- ), "No follow"))), /* @__PURE__ */ React116.createElement("div", { className: "link-modal-footer" }, /* @__PURE__ */ React116.createElement("button", { className: "link-modal-btn-unlink", onClick: handleLinkRemove }, "Unlink"), /* @__PURE__ */ React116.createElement("button", { className: "link-modal-btn-apply", onClick: handleLinkSubmit }, "Update"))))));
15275
+ );
15148
15276
  };
15149
- var RufousTextContent = ({ content, className, style }) => /* @__PURE__ */ React116.createElement(
15150
- "div",
15151
- {
15152
- className: `rf-rte-content ${className || ""}`,
15153
- style,
15154
- dangerouslySetInnerHTML: { __html: content }
15155
- }
15156
- );
15157
15277
  export {
15158
15278
  APP_THEMES,
15159
15279
  Accordion,