@kopexa/tiptap 1.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (213) hide show
  1. package/dist/{chunk-AASYBJDX.mjs → chunk-2SI7MRAE.mjs} +1 -1
  2. package/dist/{chunk-6W7J7PHZ.mjs → chunk-B2DHYFSH.mjs} +6 -7
  3. package/dist/{chunk-RQPJU4UB.mjs → chunk-B7WJOQ3X.mjs} +1 -1
  4. package/dist/{chunk-ACWAVTTK.mjs → chunk-BEV5U2DK.mjs} +6 -6
  5. package/dist/{chunk-TGQP45HH.mjs → chunk-EHY2NAW7.mjs} +1 -3
  6. package/dist/{chunk-O5P45H3I.mjs → chunk-GYIYX2JH.mjs} +1 -1
  7. package/dist/{chunk-QCULSZRZ.mjs → chunk-IOB3REX6.mjs} +1 -3
  8. package/dist/{chunk-ILPDDC4W.mjs → chunk-IQERE7KP.mjs} +1 -4
  9. package/dist/{chunk-6SS62RYU.mjs → chunk-JNL4KY45.mjs} +1 -3
  10. package/dist/{chunk-R2RRQUU5.mjs → chunk-LHXRE26G.mjs} +2 -2
  11. package/dist/{chunk-F2HHFSM4.mjs → chunk-LNVWG34E.mjs} +1 -4
  12. package/dist/chunk-NUCXXNTA.mjs +131 -0
  13. package/dist/{chunk-GLQRF7PR.mjs → chunk-OEVR5N7X.mjs} +2 -10
  14. package/dist/{chunk-YYHNT322.mjs → chunk-OZWCQMRA.mjs} +27 -19
  15. package/dist/{chunk-OX2A52WL.mjs → chunk-Q7DFJ5NI.mjs} +2 -4
  16. package/dist/{chunk-ODBSAQ5V.mjs → chunk-QF3YHPWM.mjs} +2 -4
  17. package/dist/{chunk-R5AMMJTQ.mjs → chunk-REJEJXOZ.mjs} +3 -3
  18. package/dist/chunk-TZQQ6C2Q.mjs +101 -0
  19. package/dist/{chunk-KI3YOPAA.mjs → chunk-UJ4BNZ63.mjs} +1 -4
  20. package/dist/{chunk-4LAWYE7B.mjs → chunk-V6TAZMQN.mjs} +2 -4
  21. package/dist/{chunk-QP2LCU5N.mjs → chunk-VX3HSJ76.mjs} +2 -2
  22. package/dist/{chunk-WCBSINO5.mjs → chunk-W2FLOOJ6.mjs} +1 -1
  23. package/dist/{chunk-JHMEXFB3.mjs → chunk-WHJ4B43N.mjs} +1 -1
  24. package/dist/{chunk-YD56B5SG.mjs → chunk-WPRDVMPN.mjs} +19 -18
  25. package/dist/{chunk-44V2Y6IU.mjs → chunk-XL5FS7LN.mjs} +3 -3
  26. package/dist/{chunk-ZSYXHD7D.mjs → chunk-YJAHZXLG.mjs} +1 -4
  27. package/dist/{chunk-T7LL5ZSR.mjs → chunk-ZVTJ6XD7.mjs} +1 -3
  28. package/dist/{chunk-I7WKP3OM.mjs → chunk-ZZ4OU46C.mjs} +6 -6
  29. package/dist/context/editor-context.d.mts +4 -4
  30. package/dist/context/editor-context.d.ts +4 -4
  31. package/dist/context/editor-context.js +5 -5
  32. package/dist/context/editor-context.mjs +5 -6
  33. package/dist/extensions/link/index.mjs +0 -1
  34. package/dist/extensions/selection/index.mjs +0 -1
  35. package/dist/extensions/trailing-node/index.mjs +0 -1
  36. package/dist/extensions/ui-state/index.mjs +0 -1
  37. package/dist/hooks/use-create-editor.d.mts +16 -5
  38. package/dist/hooks/use-create-editor.d.ts +16 -5
  39. package/dist/hooks/use-create-editor.js +84 -1062
  40. package/dist/hooks/use-create-editor.mjs +5 -18
  41. package/dist/hooks/use-cursor-visibility.mjs +0 -1
  42. package/dist/hooks/use-floating-element.mjs +0 -1
  43. package/dist/hooks/use-floating-toolbar-visibility.mjs +0 -1
  44. package/dist/hooks/use-menu-navigation.mjs +0 -1
  45. package/dist/hooks/use-tiptap-editor.mjs +0 -1
  46. package/dist/hooks/use-ui-editor-state.mjs +0 -1
  47. package/dist/hooks/use-window-size.mjs +0 -1
  48. package/dist/index.d.mts +6 -5
  49. package/dist/index.d.ts +6 -5
  50. package/dist/index.js +483 -1584
  51. package/dist/index.mjs +39 -60
  52. package/dist/presets/basic/editor-header.js +112 -167
  53. package/dist/presets/basic/editor-header.mjs +25 -25
  54. package/dist/presets/basic/index.d.mts +6 -3
  55. package/dist/presets/basic/index.d.ts +6 -3
  56. package/dist/presets/basic/index.js +386 -1468
  57. package/dist/presets/basic/index.mjs +32 -46
  58. package/dist/ui/blockquote-button/blockquote-button.js +12 -67
  59. package/dist/ui/blockquote-button/blockquote-button.mjs +2 -4
  60. package/dist/ui/blockquote-button/index.js +12 -67
  61. package/dist/ui/blockquote-button/index.mjs +2 -4
  62. package/dist/ui/blockquote-button/use-blockquote.js +12 -65
  63. package/dist/ui/blockquote-button/use-blockquote.mjs +1 -3
  64. package/dist/ui/codeblock-button/code-block-button.js +13 -76
  65. package/dist/ui/codeblock-button/code-block-button.mjs +2 -4
  66. package/dist/ui/codeblock-button/index.js +13 -76
  67. package/dist/ui/codeblock-button/index.mjs +2 -4
  68. package/dist/ui/codeblock-button/use-code-block.js +12 -65
  69. package/dist/ui/codeblock-button/use-code-block.mjs +1 -3
  70. package/dist/ui/color-highlight-button/color-highlight-button.js +3 -23
  71. package/dist/ui/color-highlight-button/color-highlight-button.mjs +2 -4
  72. package/dist/ui/color-highlight-button/index.js +3 -23
  73. package/dist/ui/color-highlight-button/index.mjs +2 -4
  74. package/dist/ui/color-highlight-button/use-color-highlight.js +3 -21
  75. package/dist/ui/color-highlight-button/use-color-highlight.mjs +1 -3
  76. package/dist/ui/color-highlight-popover/color-highlight-popover.js +4 -24
  77. package/dist/ui/color-highlight-popover/color-highlight-popover.mjs +3 -5
  78. package/dist/ui/color-highlight-popover/index.js +4 -24
  79. package/dist/ui/color-highlight-popover/index.mjs +3 -5
  80. package/dist/ui/copy-anchor-link-button/use-scroll-to-hash.js +2 -18
  81. package/dist/ui/copy-anchor-link-button/use-scroll-to-hash.mjs +1 -3
  82. package/dist/ui/heading-button/index.js +2 -9
  83. package/dist/ui/heading-button/index.mjs +1 -3
  84. package/dist/ui/heading-button/utils.mjs +0 -1
  85. package/dist/ui/heading-dropdown-menu/index.js +4 -10
  86. package/dist/ui/heading-dropdown-menu/index.mjs +2 -4
  87. package/dist/ui/link-popover/index.js +2 -6
  88. package/dist/ui/link-popover/index.mjs +3 -4
  89. package/dist/ui/link-popover/link-popover.js +2 -6
  90. package/dist/ui/link-popover/link-popover.mjs +3 -4
  91. package/dist/ui/link-popover/use-link-popover.js +2 -6
  92. package/dist/ui/link-popover/use-link-popover.mjs +2 -3
  93. package/dist/ui/list-button/index.js +2 -9
  94. package/dist/ui/list-button/index.mjs +1 -3
  95. package/dist/ui/list-dropdown-menu/index.js +4 -10
  96. package/dist/ui/list-dropdown-menu/index.mjs +2 -4
  97. package/dist/ui/mark-button/index.js +3 -21
  98. package/dist/ui/mark-button/index.mjs +1 -3
  99. package/dist/ui/reset-all-formatting-button/index.mjs +0 -1
  100. package/dist/ui/reset-all-formatting-button/reset-all-formatting-button.mjs +0 -1
  101. package/dist/ui/reset-all-formatting-button/use-reset-all-formatting.mjs +0 -1
  102. package/dist/ui/slash-dropdown-menu/index.js +27 -129
  103. package/dist/ui/slash-dropdown-menu/index.mjs +3 -5
  104. package/dist/ui/slash-dropdown-menu/slash-dropdown-menu.js +27 -129
  105. package/dist/ui/slash-dropdown-menu/slash-dropdown-menu.mjs +3 -5
  106. package/dist/ui/slash-dropdown-menu/use-slash-dropdown-menu.js +23 -116
  107. package/dist/ui/slash-dropdown-menu/use-slash-dropdown-menu.mjs +2 -4
  108. package/dist/ui/suggestion-menu/index.mjs +0 -1
  109. package/dist/ui/suggestion-menu/suggestion-menu-utils.mjs +0 -1
  110. package/dist/ui/suggestion-menu/suggestion-menu.mjs +0 -1
  111. package/dist/ui/table-button/index.js +4 -24
  112. package/dist/ui/table-button/index.mjs +2 -4
  113. package/dist/ui/table-button/use-table.js +3 -21
  114. package/dist/ui/table-button/use-table.mjs +1 -3
  115. package/dist/ui/text-align-button/index.js +3 -32
  116. package/dist/ui/text-align-button/index.mjs +2 -4
  117. package/dist/ui/text-align-button/text-align-button.js +3 -32
  118. package/dist/ui/text-align-button/text-align-button.mjs +2 -4
  119. package/dist/ui/text-align-button/use-text-align.js +3 -30
  120. package/dist/ui/text-align-button/use-text-align.mjs +1 -3
  121. package/dist/ui/undo-redo-button/index.js +2 -18
  122. package/dist/ui/undo-redo-button/index.mjs +2 -4
  123. package/dist/ui/undo-redo-button/undo-redo-button.js +2 -18
  124. package/dist/ui/undo-redo-button/undo-redo-button.mjs +2 -4
  125. package/dist/ui/undo-redo-button/use-undo-redo.js +2 -16
  126. package/dist/ui/undo-redo-button/use-undo-redo.mjs +1 -3
  127. package/dist/utils/index.d.mts +1 -101
  128. package/dist/utils/index.d.ts +1 -101
  129. package/dist/utils/index.js +0 -166
  130. package/dist/utils/index.mjs +1 -28
  131. package/dist/utils/safe-parse.mjs +0 -1
  132. package/package.json +36 -30
  133. package/dist/chunk-4HTILXJM.mjs +0 -104
  134. package/dist/chunk-4IIGLBTD.mjs +0 -81
  135. package/dist/chunk-574UV65T.mjs +0 -111
  136. package/dist/chunk-7HC7D256.mjs +0 -91
  137. package/dist/chunk-AC22DSDA.mjs +0 -540
  138. package/dist/chunk-AGOMESFC.mjs +0 -1
  139. package/dist/chunk-BXPGSCTT.mjs +0 -39
  140. package/dist/chunk-C6M3CDOK.mjs +0 -254
  141. package/dist/chunk-EN3J5AMF.mjs +0 -12
  142. package/dist/chunk-HYDS6H67.mjs +0 -58
  143. package/dist/chunk-KRLE4MMD.mjs +0 -116
  144. package/dist/chunk-LKOQAQPZ.mjs +0 -13
  145. package/dist/chunk-LXZ53XU7.mjs +0 -1
  146. package/dist/chunk-T6P7CS4F.mjs +0 -42
  147. package/dist/chunk-TVFWG7IC.mjs +0 -43
  148. package/dist/chunk-VULWMVYS.mjs +0 -11
  149. package/dist/chunk-WKV76XOR.mjs +0 -8
  150. package/dist/extensions/table/index.d.mts +0 -8
  151. package/dist/extensions/table/index.d.ts +0 -8
  152. package/dist/extensions/table/index.js +0 -1044
  153. package/dist/extensions/table/index.mjs +0 -33
  154. package/dist/extensions/table/kit.d.mts +0 -30
  155. package/dist/extensions/table/kit.d.ts +0 -30
  156. package/dist/extensions/table/kit.js +0 -1034
  157. package/dist/extensions/table/kit.mjs +0 -20
  158. package/dist/extensions/table/table/icons.d.mts +0 -13
  159. package/dist/extensions/table/table/icons.d.ts +0 -13
  160. package/dist/extensions/table/table/icons.js +0 -81
  161. package/dist/extensions/table/table/icons.mjs +0 -8
  162. package/dist/extensions/table/table/index.d.mts +0 -3
  163. package/dist/extensions/table/table/index.d.ts +0 -3
  164. package/dist/extensions/table/table/index.js +0 -818
  165. package/dist/extensions/table/table/index.mjs +0 -16
  166. package/dist/extensions/table/table/table-controls.d.mts +0 -10
  167. package/dist/extensions/table/table/table-controls.d.ts +0 -10
  168. package/dist/extensions/table/table/table-controls.js +0 -129
  169. package/dist/extensions/table/table/table-controls.mjs +0 -8
  170. package/dist/extensions/table/table/table-view.d.mts +0 -43
  171. package/dist/extensions/table/table/table-view.d.ts +0 -43
  172. package/dist/extensions/table/table/table-view.js +0 -610
  173. package/dist/extensions/table/table/table-view.mjs +0 -12
  174. package/dist/extensions/table/table/table.d.mts +0 -17
  175. package/dist/extensions/table/table/table.d.ts +0 -17
  176. package/dist/extensions/table/table/table.js +0 -816
  177. package/dist/extensions/table/table/table.mjs +0 -15
  178. package/dist/extensions/table/table/utilities/col-style.d.mts +0 -3
  179. package/dist/extensions/table/table/utilities/col-style.d.ts +0 -3
  180. package/dist/extensions/table/table/utilities/col-style.js +0 -36
  181. package/dist/extensions/table/table/utilities/col-style.mjs +0 -8
  182. package/dist/extensions/table/table/utilities/delete-table-when-all-cells-selected.d.mts +0 -5
  183. package/dist/extensions/table/table/utilities/delete-table-when-all-cells-selected.d.ts +0 -5
  184. package/dist/extensions/table/table/utilities/delete-table-when-all-cells-selected.js +0 -66
  185. package/dist/extensions/table/table/utilities/delete-table-when-all-cells-selected.mjs +0 -40
  186. package/dist/extensions/table/table/utilities/get-table-node-types.d.mts +0 -7
  187. package/dist/extensions/table/table/utilities/get-table-node-types.d.ts +0 -7
  188. package/dist/extensions/table/table/utilities/get-table-node-types.js +0 -44
  189. package/dist/extensions/table/table/utilities/get-table-node-types.mjs +0 -21
  190. package/dist/extensions/table/table/utilities/insert-line-above-table-action.d.mts +0 -5
  191. package/dist/extensions/table/table/utilities/insert-line-above-table-action.d.ts +0 -5
  192. package/dist/extensions/table/table/utilities/insert-line-above-table-action.js +0 -80
  193. package/dist/extensions/table/table/utilities/insert-line-above-table-action.mjs +0 -9
  194. package/dist/extensions/table/table/utilities/insert-line-below-table-action.d.mts +0 -5
  195. package/dist/extensions/table/table/utilities/insert-line-below-table-action.d.ts +0 -5
  196. package/dist/extensions/table/table/utilities/insert-line-below-table-action.js +0 -79
  197. package/dist/extensions/table/table/utilities/insert-line-below-table-action.mjs +0 -9
  198. package/dist/extensions/table/table/utilities/is-cell-selection.d.mts +0 -5
  199. package/dist/extensions/table/table/utilities/is-cell-selection.d.ts +0 -5
  200. package/dist/extensions/table/table/utilities/is-cell-selection.js +0 -34
  201. package/dist/extensions/table/table/utilities/is-cell-selection.mjs +0 -8
  202. package/dist/extensions/table/table-cell.d.mts +0 -8
  203. package/dist/extensions/table/table-cell.d.ts +0 -8
  204. package/dist/extensions/table/table-cell.js +0 -139
  205. package/dist/extensions/table/table-cell.mjs +0 -8
  206. package/dist/extensions/table/table-header.d.mts +0 -6
  207. package/dist/extensions/table/table-header.d.ts +0 -6
  208. package/dist/extensions/table/table-header.js +0 -104
  209. package/dist/extensions/table/table-header.mjs +0 -8
  210. package/dist/extensions/table/table-row.d.mts +0 -6
  211. package/dist/extensions/table/table-row.d.ts +0 -6
  212. package/dist/extensions/table/table-row.js +0 -35
  213. package/dist/extensions/table/table-row.mjs +0 -8
package/dist/index.js CHANGED
@@ -6,16 +6,15 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
7
  var __getProtoOf = Object.getPrototypeOf;
8
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __defNormalProp = (obj, key2, value) => key2 in obj ? __defProp(obj, key2, { enumerable: true, configurable: true, writable: true, value }) : obj[key2] = value;
10
9
  var __export = (target, all) => {
11
10
  for (var name in all)
12
11
  __defProp(target, name, { get: all[name], enumerable: true });
13
12
  };
14
13
  var __copyProps = (to, from, except, desc) => {
15
14
  if (from && typeof from === "object" || typeof from === "function") {
16
- for (let key2 of __getOwnPropNames(from))
17
- if (!__hasOwnProp.call(to, key2) && key2 !== except)
18
- __defProp(to, key2, { get: () => from[key2], enumerable: !(desc = __getOwnPropDesc(from, key2)) || desc.enumerable });
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
19
18
  }
20
19
  return to;
21
20
  };
@@ -28,45 +27,35 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
27
  mod
29
28
  ));
30
29
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
31
- var __publicField = (obj, key2, value) => __defNormalProp(obj, typeof key2 !== "symbol" ? key2 + "" : key2, value);
32
30
 
33
31
  // src/index.ts
34
32
  var index_exports = {};
35
33
  __export(index_exports, {
36
- BasicEditor: () => BasicEditor,
34
+ Editor: () => BasicEditor,
37
35
  convertFileToBase64: () => convertFileToBase64,
38
- findNodePosition: () => findNodePosition,
39
- getActiveMarkAttrs: () => getActiveMarkAttrs,
36
+ getExtensions: () => getExtensions,
40
37
  handleImageUpload: () => handleImageUpload,
41
38
  isAllowedUri: () => isAllowedUri,
42
- isEmptyNode: () => isEmptyNode,
43
- isMarkInSchema: () => isMarkInSchema,
44
- isNodeInSchema: () => isNodeInSchema,
45
39
  sanitizeUrl: () => sanitizeUrl
46
40
  });
47
41
  module.exports = __toCommonJS(index_exports);
48
42
 
49
- // src/presets/basic/index.tsx
50
- var import_theme3 = require("@kopexa/theme");
51
- var import_react32 = require("@tiptap/react");
52
- var import_react33 = require("react");
53
-
54
- // src/context/editor-context.ts
55
- var import_react_utils = require("@kopexa/react-utils");
56
- var [EditorWrapperProvider, useEditorWrapper] = (0, import_react_utils.createContext)();
57
-
58
43
  // src/hooks/use-create-editor.ts
44
+ var import_extension_code = require("@kopexa/extension-code");
59
45
  var import_extension_controlref = require("@kopexa/extension-controlref");
46
+ var import_extension_table = require("@kopexa/extension-table");
60
47
  var import_extension_highlight = require("@tiptap/extension-highlight");
48
+ var import_extension_invisible_characters = __toESM(require("@tiptap/extension-invisible-characters"));
49
+ var import_extension_list = require("@tiptap/extension-list");
61
50
  var import_extension_subscript = require("@tiptap/extension-subscript");
62
51
  var import_extension_superscript = require("@tiptap/extension-superscript");
63
- var import_extension_task_item = require("@tiptap/extension-task-item");
64
- var import_extension_task_list = require("@tiptap/extension-task-list");
52
+ var import_extension_table_of_contents = require("@tiptap/extension-table-of-contents");
65
53
  var import_extension_text_align = require("@tiptap/extension-text-align");
54
+ var import_extension_text_style = require("@tiptap/extension-text-style");
66
55
  var import_extension_typography = require("@tiptap/extension-typography");
67
56
  var import_extension_unique_id = require("@tiptap/extension-unique-id");
68
57
  var import_extensions = require("@tiptap/extensions");
69
- var import_react5 = require("@tiptap/react");
58
+ var import_react4 = require("@tiptap/react");
70
59
  var import_starter_kit = require("@tiptap/starter-kit");
71
60
 
72
61
  // src/extensions/link/index.ts
@@ -110,1279 +99,58 @@ var Link = import_extension_link.default.extend({
110
99
  const start = Math.min(from, to);
111
100
  const end = Math.max(from, to);
112
101
  if (pos < start || pos > end) {
113
- return;
114
- }
115
- const $start = doc.resolve(start);
116
- const $end = doc.resolve(end);
117
- const transaction = tr.setSelection(
118
- new import_state.TextSelection($start, $end)
119
- );
120
- view.dispatch(transaction);
121
- }
122
- }
123
- })
124
- ];
125
- }
126
- });
127
-
128
- // src/extensions/selection/index.ts
129
- var import_state2 = require("@tiptap/pm/state");
130
- var import_view = require("@tiptap/pm/view");
131
- var import_react2 = require("@tiptap/react");
132
- var Selection = import_react2.Extension.create({
133
- name: "selection",
134
- addProseMirrorPlugins() {
135
- const { editor } = this;
136
- return [
137
- new import_state2.Plugin({
138
- key: new import_state2.PluginKey("selection"),
139
- props: {
140
- decorations(state) {
141
- if (state.selection.empty) {
142
- return null;
143
- }
144
- if (editor.isFocused === true || !editor.isEditable) {
145
- return null;
146
- }
147
- if ((0, import_react2.isNodeSelection)(state.selection)) {
148
- return null;
149
- }
150
- return import_view.DecorationSet.create(state.doc, [
151
- import_view.Decoration.inline(state.selection.from, state.selection.to, {
152
- class: "selection"
153
- })
154
- ]);
155
- }
156
- }
157
- })
158
- ];
159
- }
160
- });
161
-
162
- // src/extensions/table/kit.ts
163
- var import_react3 = require("@tiptap/react");
164
-
165
- // src/extensions/table/table/table.ts
166
- var import_extension_table = require("@tiptap/extension-table");
167
- var import_tables2 = require("@tiptap/pm/tables");
168
-
169
- // src/extensions/table/table/table-controls.ts
170
- var import_core = require("@tiptap/core");
171
- var import_state3 = require("@tiptap/pm/state");
172
- var import_view2 = require("@tiptap/pm/view");
173
- var key = new import_state3.PluginKey("tableControls");
174
- function tableControls() {
175
- return new import_state3.Plugin({
176
- key,
177
- state: {
178
- init() {
179
- return new TableControlsState();
180
- },
181
- apply(tr, prev) {
182
- return prev.apply(tr);
183
- }
184
- },
185
- props: {
186
- handleDOMEvents: {
187
- mousemove: (view, event) => {
188
- var _a;
189
- const pluginState = key.getState(view.state);
190
- if (!event.target.closest(".table-wrapper") && pluginState.values.hoveredTable) {
191
- return view.dispatch(
192
- view.state.tr.setMeta(key, {
193
- setHoveredTable: null,
194
- setHoveredCell: null
195
- })
196
- );
197
- }
198
- const pos = view.posAtCoords({
199
- left: event.clientX,
200
- top: event.clientY
201
- });
202
- if (!pos || pos.pos < 0 || pos.pos > view.state.doc.content.size)
203
- return;
204
- const table = (0, import_core.findParentNode)((node) => node.type.name === "table")(
205
- import_state3.TextSelection.create(view.state.doc, pos.pos)
206
- );
207
- const cell = (0, import_core.findParentNode)(
208
- (node) => node.type.name === "tableCell" || node.type.name === "tableHeader"
209
- )(import_state3.TextSelection.create(view.state.doc, pos.pos));
210
- if (!table || !cell) return;
211
- if (((_a = pluginState.values.hoveredCell) == null ? void 0 : _a.pos) !== cell.pos) {
212
- return view.dispatch(
213
- view.state.tr.setMeta(key, {
214
- setHoveredTable: table,
215
- setHoveredCell: cell
216
- })
217
- );
218
- }
219
- }
220
- },
221
- decorations: (state) => {
222
- const pluginState = key.getState(state);
223
- if (!pluginState) {
224
- return null;
225
- }
226
- const { hoveredTable, hoveredCell } = pluginState.values;
227
- const docSize = state.doc.content.size;
228
- if (hoveredTable && hoveredCell && hoveredTable.pos < docSize && hoveredCell.pos < docSize) {
229
- const decorations = [
230
- import_view2.Decoration.node(
231
- hoveredTable.pos,
232
- hoveredTable.pos + hoveredTable.node.nodeSize,
233
- {},
234
- {
235
- hoveredTable,
236
- hoveredCell
237
- }
238
- )
239
- ];
240
- return import_view2.DecorationSet.create(state.doc, decorations);
241
- }
242
- return null;
243
- }
244
- }
245
- });
246
- }
247
- var TableControlsState = class {
248
- constructor(props = {}) {
249
- __publicField(this, "values");
250
- this.values = {
251
- hoveredTable: null,
252
- hoveredCell: null,
253
- ...props
254
- };
255
- }
256
- apply(tr) {
257
- const actions = tr.getMeta(key);
258
- if ((actions == null ? void 0 : actions.setHoveredTable) !== void 0) {
259
- this.values.hoveredTable = actions.setHoveredTable;
260
- }
261
- if ((actions == null ? void 0 : actions.setHoveredCell) !== void 0) {
262
- this.values.hoveredCell = actions.setHoveredCell;
263
- }
264
- return this;
265
- }
266
- };
267
-
268
- // src/extensions/table/table/table-view.tsx
269
- var import_dom = require("@floating-ui/dom");
270
- var import_tables = require("@tiptap/pm/tables");
271
- var import_jsx_dom_cjs = require("jsx-dom-cjs");
272
-
273
- // src/extensions/table/table/icons.ts
274
- var icons = {
275
- colorPicker: `<svg xmlns="http://www.w3.org/2000/svg" length="24" viewBox="0 0 24 24" style="transform: ;msFilter:;"><path fill="rgb(var(--color-text-300))" d="M20 14c-.092.064-2 2.083-2 3.5 0 1.494.949 2.448 2 2.5.906.044 2-.891 2-2.5 0-1.5-1.908-3.436-2-3.5zM9.586 20c.378.378.88.586 1.414.586s1.036-.208 1.414-.586l7-7-.707-.707L11 4.586 8.707 2.293 7.293 3.707 9.586 6 4 11.586c-.378.378-.586.88-.586 1.414s.208 1.036.586 1.414L9.586 20zM11 7.414 16.586 13H5.414L11 7.414z"></path></svg>`,
276
- deleteColumn: `<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-trash-2"><path d="M3 6h18"/><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/><line x1="10" x2="10" y1="11" y2="17"/><line x1="14" x2="14" y1="11" y2="17"/></svg>`,
277
- deleteRow: `<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-trash-2"><path d="M3 6h18"/><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/><line x1="10" x2="10" y1="11" y2="17"/><line x1="14" x2="14" y1="11" y2="17"/></svg>`,
278
- insertLeftTableIcon: `<svg
279
- xmlns="http://www.w3.org/2000/svg"
280
- length={12}
281
- viewBox="0 -960 960 960"
282
- >
283
- <path
284
- d="M224.617-140.001q-30.307 0-51.307-21-21-21-21-51.308v-535.382q0-30.308 21-51.308t51.307-21H360q30.307 0 51.307 21 21 21 21 51.308v535.382q0 30.308-21 51.308t-51.307 21H224.617Zm375.383 0q-30.307 0-51.307-21-21-21-21-51.308v-535.382q0-30.308 21-51.308t51.307-21h135.383q30.307 0 51.307 21 21 21 21 51.308v535.382q0 30.308-21 51.308t-51.307 21H600Zm147.691-607.69q0-4.616-3.846-8.463-3.846-3.846-8.462-3.846H600q-4.616 0-8.462 3.846-3.847 3.847-3.847 8.463v535.382q0 4.616 3.847 8.463Q595.384-200 600-200h135.383q4.616 0 8.462-3.846 3.846-3.847 3.846-8.463v-535.382ZM587.691-200h160-160Z"
285
- fill="rgb(var(--color-text-300))"
286
- />
287
- </svg>
288
- `,
289
- insertRightTableIcon: `<svg
290
- xmlns="http://www.w3.org/2000/svg"
291
- length={12}
292
- viewBox="0 -960 960 960"
293
- >
294
- <path
295
- d="M600-140.001q-30.307 0-51.307-21-21-21-21-51.308v-535.382q0-30.308 21-51.308t51.307-21h135.383q30.307 0 51.307 21 21 21 21 51.308v535.382q0 30.308-21 51.308t-51.307 21H600Zm-375.383 0q-30.307 0-51.307-21-21-21-21-51.308v-535.382q0-30.308 21-51.308t51.307-21H360q30.307 0 51.307 21 21 21 21 51.308v535.382q0 30.308-21 51.308t-51.307 21H224.617Zm-12.308-607.69v535.382q0 4.616 3.846 8.463 3.846 3.846 8.462 3.846H360q4.616 0 8.462-3.846 3.847-3.847 3.847-8.463v-535.382q0-4.616-3.847-8.463Q364.616-760 360-760H224.617q-4.616 0-8.462 3.846-3.846 3.847-3.846 8.463Zm160 547.691h-160 160Z"
296
- fill="rgb(var(--color-text-300))"
297
- />
298
- </svg>
299
- `,
300
- insertTopTableIcon: `<svg
301
- xmlns="http://www.w3.org/2000/svg"
302
- length={24}
303
- viewBox="0 -960 960 960"
304
- >
305
- <path
306
- d="M212.309-527.693q-30.308 0-51.308-21t-21-51.307v-135.383q0-30.307 21-51.307 21-21 51.308-21h535.382q30.308 0 51.308 21t21 51.307V-600q0 30.307-21 51.307-21 21-51.308 21H212.309Zm0 375.383q-30.308 0-51.308-21t-21-51.307V-360q0-30.307 21-51.307 21-21 51.308-21h535.382q30.308 0 51.308 21t21 51.307v135.383q0 30.307-21 51.307-21 21-51.308 21H212.309Zm0-59.999h535.382q4.616 0 8.463-3.846 3.846-3.846 3.846-8.462V-360q0-4.616-3.846-8.462-3.847-3.847-8.463-3.847H212.309q-4.616 0-8.463 3.847Q200-364.616 200-360v135.383q0 4.616 3.846 8.462 3.847 3.846 8.463 3.846Zm-12.309-160v160-160Z"
307
- fill="rgb(var(--color-text-300))"
308
- />
309
- </svg>
310
- `,
311
- toggleColumnHeader: `<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-toggle-right"><rect width="20" height="12" x="2" y="6" rx="6" ry="6"/><circle cx="16" cy="12" r="2"/></svg>`,
312
- toggleRowHeader: `<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-toggle-right"><rect width="20" height="12" x="2" y="6" rx="6" ry="6"/><circle cx="16" cy="12" r="2"/></svg>`,
313
- insertBottomTableIcon: `<svg
314
- xmlns="http://www.w3.org/2000/svg"
315
- length={24}
316
- viewBox="0 -960 960 960"
317
- >
318
- <path
319
- d="M212.309-152.31q-30.308 0-51.308-21t-21-51.307V-360q0-30.307 21-51.307 21-21 51.308-21h535.382q30.308 0 51.308 21t21 51.307v135.383q0 30.307-21 51.307-21 21-51.308 21H212.309Zm0-375.383q-30.308 0-51.308-21t-21-51.307v-135.383q0-30.307 21-51.307 21-21 51.308-21h535.382q30.308 0 51.308 21t21 51.307V-600q0 30.307-21 51.307-21 21-51.308 21H212.309Zm535.382-219.998H212.309q-4.616 0-8.463 3.846-3.846 3.846-3.846 8.462V-600q0 4.616 3.846 8.462 3.847 3.847 8.463 3.847h535.382q4.616 0 8.463-3.847Q760-595.384 760-600v-135.383q0-4.616-3.846-8.462-3.847-3.846-8.463-3.846ZM200-587.691v-160 160Z"
320
- fill="rgb(var(--color-text-300))"
321
- />
322
- </svg>
323
- `
324
- };
325
-
326
- // src/extensions/table/table/table-view.tsx
327
- var Popover = class {
328
- constructor(content, opts) {
329
- __publicField(this, "reference");
330
- __publicField(this, "floating");
331
- __publicField(this, "cleanupAutoUpdate", null);
332
- __publicField(this, "onDocClick", (e) => {
333
- if (!this.floating.contains(e.target) && !this.reference.contains(e.target)) {
334
- this.hide();
335
- }
336
- });
337
- __publicField(this, "onEsc", (e) => {
338
- if (e.key === "Escape") this.hide();
339
- });
340
- __publicField(this, "_placement");
341
- __publicField(this, "_offsetPx");
342
- // biome-ignore lint/correctness/noUnusedPrivateClassMembers: backwards. will be used later
343
- __publicField(this, "_interactive");
344
- var _a, _b, _c, _d;
345
- this.reference = opts.reference;
346
- this.floating = document.createElement("div");
347
- this.floating.setAttribute("role", "dialog");
348
- this.floating.setAttribute("aria-modal", "false");
349
- this.floating.style.position = "fixed";
350
- this.floating.style.zIndex = "9999";
351
- this.floating.style.display = "none";
352
- this.floating.className = "rounded-md border bg-background px-2 py-2.5 text-xs shadow-sm min-w-[12rem] whitespace-nowrap";
353
- this.floating.appendChild(content);
354
- const host = (_a = opts.container) != null ? _a : document.body;
355
- host.appendChild(this.floating);
356
- this._placement = (_b = opts.placement) != null ? _b : "right";
357
- this._offsetPx = (_c = opts.offsetPx) != null ? _c : 6;
358
- this._interactive = (_d = opts.interactive) != null ? _d : true;
359
- }
360
- async _updatePosition() {
361
- const { x, y } = await (0, import_dom.computePosition)(this.reference, this.floating, {
362
- placement: this._placement,
363
- middleware: [(0, import_dom.offset)(this._offsetPx), (0, import_dom.flip)(), (0, import_dom.shift)({ padding: 8 })]
364
- });
365
- Object.assign(this.floating.style, { left: `${x}px`, top: `${y}px` });
366
- }
367
- show() {
368
- if (this.floating.style.display !== "none") return;
369
- this.floating.style.display = "block";
370
- this.cleanupAutoUpdate = (0, import_dom.autoUpdate)(
371
- this.reference,
372
- this.floating,
373
- () => this._updatePosition()
374
- );
375
- document.addEventListener("keydown", this.onEsc, { passive: true });
376
- document.addEventListener("mousedown", this.onDocClick, { capture: true });
377
- requestAnimationFrame(() => this._updatePosition());
378
- }
379
- hide() {
380
- var _a;
381
- if (this.floating.style.display === "none") return;
382
- this.floating.style.display = "none";
383
- (_a = this.cleanupAutoUpdate) == null ? void 0 : _a.call(this);
384
- this.cleanupAutoUpdate = null;
385
- document.removeEventListener("keydown", this.onEsc);
386
- document.removeEventListener("mousedown", this.onDocClick, {
387
- capture: true
388
- });
389
- }
390
- toggle() {
391
- if (this.floating.style.display === "none") this.show();
392
- else this.hide();
393
- }
394
- destroy() {
395
- this.hide();
396
- this.floating.remove();
397
- }
398
- get el() {
399
- return this.floating;
400
- }
401
- };
402
- function setCellsBackgroundColor(editor, color) {
403
- return editor.chain().focus().updateAttributes("tableCell", {
404
- background: color.backgroundColor,
405
- textColor: color.textColor
406
- }).run();
407
- }
408
- function setTableRowBackgroundColor(editor, color) {
409
- const { state, dispatch } = editor.view;
410
- const { selection } = state;
411
- if (!(selection instanceof import_tables.CellSelection)) return false;
412
- const hoveredCell = selection.$headCell || selection.$anchorCell;
413
- let rowDepth = hoveredCell.depth;
414
- while (rowDepth > 0 && hoveredCell.node(rowDepth).type.name !== "tableRow") {
415
- rowDepth--;
416
- }
417
- if (hoveredCell.node(rowDepth).type.name !== "tableRow") return false;
418
- const rowStartPos = hoveredCell.start(rowDepth);
419
- const tr = state.tr.setNodeMarkup(rowStartPos - 1, null, {
420
- ...hoveredCell.node(rowDepth).attrs,
421
- background: color.backgroundColor,
422
- textColor: color.textColor
423
- });
424
- dispatch(tr);
425
- return true;
426
- }
427
- var columnsToolboxItems = [
428
- {
429
- label: "Toggle column header",
430
- icon: icons.toggleColumnHeader,
431
- action: ({ editor }) => editor.chain().focus().toggleHeaderColumn().run()
432
- },
433
- {
434
- label: "Add column before",
435
- icon: icons.insertLeftTableIcon,
436
- action: ({ editor }) => editor.chain().focus().addColumnBefore().run()
437
- },
438
- {
439
- label: "Add column after",
440
- icon: icons.insertRightTableIcon,
441
- action: ({ editor }) => editor.chain().focus().addColumnAfter().run()
442
- },
443
- { label: "Pick color", icon: "", action: () => {
444
- } },
445
- {
446
- label: "Delete column",
447
- icon: icons.deleteColumn,
448
- action: ({ editor }) => editor.chain().focus().deleteColumn().run()
449
- }
450
- ];
451
- var rowsToolboxItems = [
452
- {
453
- label: "Toggle row header",
454
- icon: icons.toggleRowHeader,
455
- action: ({ editor }) => editor.chain().focus().toggleHeaderRow().run()
456
- },
457
- {
458
- label: "Add row above",
459
- icon: icons.insertTopTableIcon,
460
- action: ({ editor }) => editor.chain().focus().addRowBefore().run()
461
- },
462
- {
463
- label: "Add row below",
464
- icon: icons.insertBottomTableIcon,
465
- action: ({ editor }) => editor.chain().focus().addRowAfter().run()
466
- },
467
- { label: "Pick color", icon: "", action: () => {
468
- } },
469
- {
470
- label: "Delete row",
471
- icon: icons.deleteRow,
472
- action: ({ editor }) => editor.chain().focus().deleteRow().run()
473
- }
474
- ];
475
- function buildToolboxContent({
476
- items,
477
- onClickItem,
478
- onSelectColor,
479
- colors
480
- }) {
481
- return (0, import_jsx_dom_cjs.h)(
482
- "div",
483
- { className: "space-y-2" },
484
- items.map((item) => {
485
- if (item.label === "Pick color") {
486
- return (0, import_jsx_dom_cjs.h)("div", { className: "flex flex-col" }, [
487
- (0, import_jsx_dom_cjs.h)("hr", { className: "!my-2 border" }),
488
- (0, import_jsx_dom_cjs.h)("div", { className: "text-foreground text-sm" }, item.label),
489
- (0, import_jsx_dom_cjs.h)(
490
- "div",
491
- { className: "grid grid-cols-6 gap-x-1 gap-y-2.5 mt-2" },
492
- Object.entries(colors).map(
493
- ([_, colorValue]) => {
494
- var _a;
495
- return (0, import_jsx_dom_cjs.h)("button", {
496
- // @ts-expect-error JSX
497
- type: "button",
498
- className: "grid place-items-center size-6 rounded outline-none ring-offset-2 focus-visible:ring",
499
- style: `background-color:${colorValue.backgroundColor};color:${colorValue.textColor || "inherit"};`,
500
- innerHTML: (_a = colorValue.icon) != null ? _a : `<span class="text-md" style="color:${colorValue.textColor || "inherit"}">A</span>`,
501
- onClick: (e) => {
502
- e.stopPropagation();
503
- onSelectColor(colorValue);
504
- }
505
- });
506
- }
507
- )
508
- ),
509
- (0, import_jsx_dom_cjs.h)("hr", { className: "!my-2 border" })
510
- ]);
511
- }
512
- return (0, import_jsx_dom_cjs.h)(
513
- "button",
514
- {
515
- // @ts-expect-error JSX
516
- type: "button",
517
- className: "w-full flex items-center gap-2 px-1 py-1.5 bg-background hover:bg-muted text-sm text-foreground rounded",
518
- onClick: (e) => {
519
- e.stopPropagation();
520
- onClickItem(item);
521
- }
522
- },
523
- [
524
- (0, import_jsx_dom_cjs.h)("span", { className: "h-3 w-3 shrink-0", innerHTML: item.icon }),
525
- (0, import_jsx_dom_cjs.h)("div", { className: "label" }, item.label)
526
- ]
527
- );
528
- })
529
- );
530
- }
531
- function createToolbox({
532
- triggerButton,
533
- items,
534
- onSelectColor,
535
- onClickItem,
536
- colors,
537
- appendTo
538
- }) {
539
- if (!triggerButton) {
540
- return null;
541
- }
542
- const content = buildToolboxContent({
543
- items,
544
- onClickItem,
545
- onSelectColor,
546
- colors
547
- });
548
- const pop = new Popover(content, {
549
- reference: triggerButton,
550
- container: appendTo != null ? appendTo : void 0,
551
- placement: "right",
552
- offsetPx: 6,
553
- interactive: true
554
- });
555
- const onTrigger = (e) => {
556
- e.stopPropagation();
557
- pop.toggle();
558
- };
559
- triggerButton.addEventListener("click", onTrigger);
560
- return {
561
- show: () => pop.show(),
562
- hide: () => pop.hide(),
563
- destroy: () => {
564
- pop.destroy();
565
- triggerButton.removeEventListener("click", onTrigger);
566
- }
567
- };
568
- }
569
- var TableView = class {
570
- constructor(node, cellMinWidth, decorations, editor, getPos) {
571
- __publicField(this, "node");
572
- __publicField(this, "cellMinWidth");
573
- __publicField(this, "decorations");
574
- __publicField(this, "editor");
575
- __publicField(this, "getPos");
576
- __publicField(this, "hoveredCell", null);
577
- __publicField(this, "map");
578
- __publicField(this, "root");
579
- __publicField(this, "table");
580
- __publicField(this, "colgroup");
581
- __publicField(this, "tbody");
582
- __publicField(this, "rowsControl");
583
- __publicField(this, "columnsControl");
584
- __publicField(this, "columnsToolbox");
585
- __publicField(this, "rowsToolbox");
586
- __publicField(this, "controls");
587
- var _a, _b, _c, _d;
588
- this.node = node;
589
- this.cellMinWidth = cellMinWidth;
590
- this.decorations = decorations.slice();
591
- this.editor = editor;
592
- this.getPos = getPos;
593
- this.hoveredCell = null;
594
- this.map = import_tables.TableMap.get(node);
595
- if (editor.isEditable) {
596
- this.rowsControl = (0, import_jsx_dom_cjs.h)(
597
- "div",
598
- { className: "rows-control" },
599
- (0, import_jsx_dom_cjs.h)("button", {
600
- // @ts-expect-error JSX
601
- type: "button",
602
- className: "rows-control-div",
603
- onClick: () => this.selectRow(),
604
- "aria-label": "Row actions"
605
- })
606
- );
607
- this.columnsControl = (0, import_jsx_dom_cjs.h)(
608
- "div",
609
- { className: "columns-control" },
610
- (0, import_jsx_dom_cjs.h)("button", {
611
- // @ts-expect-error JSX
612
- type: "button",
613
- className: "columns-control-div",
614
- onClick: () => this.selectColumn(),
615
- "aria-label": "Column actions"
616
- })
617
- );
618
- this.controls = (0, import_jsx_dom_cjs.h)(
619
- "div",
620
- { className: "table-controls", contentEditable: "false" },
621
- this.rowsControl,
622
- this.columnsControl
623
- );
624
- const palette = {
625
- Blue: { backgroundColor: "#D9E4FF", textColor: "#171717" },
626
- Orange: { backgroundColor: "#FFEDD5", textColor: "#171717" },
627
- Grey: { backgroundColor: "#F1F1F1", textColor: "#171717" },
628
- Yellow: { backgroundColor: "#FEF3C7", textColor: "#171717" },
629
- Green: { backgroundColor: "#DCFCE7", textColor: "#171717" },
630
- Red: { backgroundColor: "#FFDDDD", textColor: "#171717" },
631
- Pink: { backgroundColor: "#FFE8FA", textColor: "#171717" },
632
- Purple: { backgroundColor: "#E8DAFB", textColor: "#171717" },
633
- None: {
634
- backgroundColor: "transparent",
635
- textColor: "inherit",
636
- icon: `<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="gray" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-ban"><circle cx="12" cy="12" r="10"/><path d="m4.9 4.9 14.2 14.2"/></svg>`
637
- }
638
- };
639
- this.columnsToolbox = createToolbox({
640
- triggerButton: (_a = this.columnsControl) == null ? void 0 : _a.querySelector(
641
- ".columns-control-div"
642
- ),
643
- items: columnsToolboxItems,
644
- colors: palette,
645
- appendTo: (_b = this.controls) != null ? _b : null,
646
- onSelectColor: (color) => setCellsBackgroundColor(this.editor, color),
647
- onClickItem: (item) => {
648
- var _a2, _b2;
649
- item.action({
650
- editor: this.editor,
651
- triggerButton: (_a2 = this.columnsControl) == null ? void 0 : _a2.firstElementChild,
652
- controlsContainer: this.controls
653
- });
654
- (_b2 = this.columnsToolbox) == null ? void 0 : _b2.hide();
655
- }
656
- });
657
- this.rowsToolbox = createToolbox({
658
- triggerButton: (_c = this.rowsControl) == null ? void 0 : _c.querySelector(
659
- ".rows-control-div"
660
- ),
661
- items: rowsToolboxItems,
662
- colors: palette,
663
- appendTo: (_d = this.controls) != null ? _d : null,
664
- onSelectColor: (color) => setTableRowBackgroundColor(editor, color),
665
- onClickItem: (item) => {
666
- var _a2, _b2;
667
- item.action({
668
- editor: this.editor,
669
- triggerButton: (_a2 = this.rowsControl) == null ? void 0 : _a2.firstElementChild,
670
- controlsContainer: this.controls
671
- });
672
- (_b2 = this.rowsToolbox) == null ? void 0 : _b2.hide();
673
- }
674
- });
675
- }
676
- this.colgroup = (0, import_jsx_dom_cjs.h)(
677
- "colgroup",
678
- null,
679
- Array.from({ length: this.map.width }, () => 1).map(() => (0, import_jsx_dom_cjs.h)("col"))
680
- );
681
- this.tbody = (0, import_jsx_dom_cjs.h)("tbody");
682
- this.table = (0, import_jsx_dom_cjs.h)(
683
- "table",
684
- null,
685
- this.colgroup,
686
- this.tbody
687
- );
688
- this.root = (0, import_jsx_dom_cjs.h)(
689
- "div",
690
- {
691
- className: "table-wrapper horizontal-scrollbar scrollbar-md controls--disabled"
692
- },
693
- this.controls,
694
- this.table
695
- );
696
- this.render();
697
- }
698
- get dom() {
699
- return this.root;
700
- }
701
- get contentDOM() {
702
- return this.tbody;
703
- }
704
- update(node, decorations) {
705
- if (node.type !== this.node.type) return false;
706
- this.node = node;
707
- this.decorations = [...decorations];
708
- this.map = import_tables.TableMap.get(this.node);
709
- if (this.editor.isEditable) this.updateControls();
710
- this.render();
711
- return true;
712
- }
713
- render() {
714
- if (this.colgroup.children.length !== this.map.width) {
715
- const cols = Array.from({ length: this.map.width }, () => 1).map(
716
- () => (0, import_jsx_dom_cjs.h)("col")
717
- );
718
- this.colgroup.replaceChildren(...cols);
719
- }
720
- (0, import_tables.updateColumnsOnResize)(
721
- this.node,
722
- this.colgroup,
723
- this.table,
724
- this.cellMinWidth
725
- );
726
- }
727
- ignoreMutation() {
728
- return true;
729
- }
730
- updateControls() {
731
- var _a;
732
- const { hoveredTable: table, hoveredCell: cell } = Object.values(
733
- this.decorations
734
- ).reduce(
735
- (acc, curr) => {
736
- if (curr.spec.hoveredCell !== void 0)
737
- acc.hoveredCell = curr.spec.hoveredCell;
738
- if (curr.spec.hoveredTable !== void 0)
739
- acc.hoveredTable = curr.spec.hoveredTable;
740
- return acc;
741
- },
742
- {}
743
- );
744
- if (table === void 0 || cell === void 0) {
745
- this.root.classList.add("controls--disabled");
746
- return;
747
- }
748
- this.root.classList.remove("controls--disabled");
749
- this.hoveredCell = cell;
750
- const cellDom = this.editor.view.nodeDOM(cell.pos);
751
- if (!this.table || !cellDom) return;
752
- const tableRect = this.table.getBoundingClientRect();
753
- const cellRect = cellDom.getBoundingClientRect();
754
- if (this.columnsControl) {
755
- this.columnsControl.style.left = `${cellRect.left - tableRect.left - (((_a = this.table.parentElement) == null ? void 0 : _a.scrollLeft) || 0)}px`;
756
- this.columnsControl.style.width = `${cellRect.width}px`;
757
- }
758
- if (this.rowsControl) {
759
- this.rowsControl.style.top = `${cellRect.top - tableRect.top}px`;
760
- this.rowsControl.style.height = `${cellRect.height}px`;
761
- }
762
- }
763
- selectColumn() {
764
- if (!this.hoveredCell) return;
765
- const colIndex = this.map.colCount(
766
- this.hoveredCell.pos - (this.getPos() + 1)
767
- );
768
- const anchorCellPos = this.hoveredCell.pos;
769
- const headCellPos = this.map.map[colIndex + this.map.width * (this.map.height - 1)] + (this.getPos() + 1);
770
- const cellSelection = import_tables.CellSelection.create(
771
- this.editor.view.state.doc,
772
- anchorCellPos,
773
- headCellPos
774
- );
775
- this.editor.view.dispatch(this.editor.state.tr.setSelection(cellSelection));
776
- }
777
- selectRow() {
778
- if (!this.hoveredCell) return;
779
- const anchorCellPos = this.hoveredCell.pos;
780
- const anchorCellIndex = this.map.map.indexOf(
781
- anchorCellPos - (this.getPos() + 1)
782
- );
783
- const headCellPos = this.map.map[anchorCellIndex + (this.map.width - 1)] + (this.getPos() + 1);
784
- const cellSelection = import_tables.CellSelection.create(
785
- this.editor.state.doc,
786
- anchorCellPos,
787
- headCellPos
788
- );
789
- this.editor.view.dispatch(
790
- this.editor.view.state.tr.setSelection(cellSelection)
791
- );
792
- }
793
- };
794
-
795
- // src/utils/index.ts
796
- var import_state4 = require("@tiptap/pm/state");
797
- var MAX_FILE_SIZE = 5 * 1024 * 1024;
798
- var isMarkInSchema = (markName, editor) => {
799
- if (!(editor == null ? void 0 : editor.schema)) return false;
800
- return editor.schema.spec.marks.get(markName) !== void 0;
801
- };
802
- var isNodeInSchema = (nodeName, editor) => {
803
- if (!(editor == null ? void 0 : editor.schema)) return false;
804
- return editor.schema.spec.nodes.get(nodeName) !== void 0;
805
- };
806
- function getActiveMarkAttrs(editor, markName) {
807
- var _a;
808
- if (!editor) return null;
809
- const { state } = editor;
810
- const marks = state.storedMarks || state.selection.$from.marks();
811
- const mark = marks.find((mark2) => mark2.type.name === markName);
812
- return (_a = mark == null ? void 0 : mark.attrs) != null ? _a : null;
813
- }
814
- function isEmptyNode(node) {
815
- return !!node && node.content.size === 0;
816
- }
817
- function findNodePosition(props) {
818
- var _a;
819
- const { editor, node, nodePos } = props;
820
- if (!editor || !((_a = editor.state) == null ? void 0 : _a.doc)) return null;
821
- const hasValidNode = node !== void 0 && node !== null;
822
- const hasValidPos = nodePos !== void 0 && nodePos !== null;
823
- if (!hasValidNode && !hasValidPos) {
824
- return null;
825
- }
826
- if (hasValidPos) {
827
- try {
828
- const nodeAtPos = editor.state.doc.nodeAt(nodePos);
829
- if (nodeAtPos) {
830
- return { pos: nodePos, node: nodeAtPos };
831
- }
832
- } catch (error) {
833
- console.error("Error checking node at position:", error);
834
- return null;
835
- }
836
- }
837
- let foundPos = -1;
838
- let foundNode = null;
839
- editor.state.doc.descendants((currentNode, pos) => {
840
- if (currentNode === node) {
841
- foundPos = pos;
842
- foundNode = currentNode;
843
- return false;
844
- }
845
- return true;
846
- });
847
- return foundPos !== -1 && foundNode !== null ? { pos: foundPos, node: foundNode } : null;
848
- }
849
- var handleImageUpload = async (file, onProgress, abortSignal) => {
850
- if (!file) {
851
- throw new Error("No file provided");
852
- }
853
- if (file.size > MAX_FILE_SIZE) {
854
- throw new Error(
855
- `File size exceeds maximum allowed (${MAX_FILE_SIZE / (1024 * 1024)}MB)`
856
- );
857
- }
858
- for (let progress = 0; progress <= 100; progress += 10) {
859
- if (abortSignal == null ? void 0 : abortSignal.aborted) {
860
- throw new Error("Upload cancelled");
861
- }
862
- await new Promise((resolve) => setTimeout(resolve, 500));
863
- onProgress == null ? void 0 : onProgress({ progress });
864
- }
865
- return "/images/placeholder-image.png";
866
- };
867
- var convertFileToBase64 = (file, abortSignal) => {
868
- if (!file) {
869
- return Promise.reject(new Error("No file provided"));
870
- }
871
- return new Promise((resolve, reject) => {
872
- const reader = new FileReader();
873
- const abortHandler = () => {
874
- reader.abort();
875
- reject(new Error("Upload cancelled"));
876
- };
877
- if (abortSignal) {
878
- abortSignal.addEventListener("abort", abortHandler);
879
- }
880
- reader.onloadend = () => {
881
- if (abortSignal) {
882
- abortSignal.removeEventListener("abort", abortHandler);
883
- }
884
- if (typeof reader.result === "string") {
885
- resolve(reader.result);
886
- } else {
887
- reject(new Error("Failed to convert File to base64"));
888
- }
889
- };
890
- reader.onerror = (error) => reject(new Error(`File reading error: ${error}`));
891
- reader.readAsDataURL(file);
892
- });
893
- };
894
- var ATTR_WHITESPACE = (
895
- // eslint-disable-next-line no-control-regex
896
- // biome-ignore lint/suspicious/noControlCharactersInRegex: we can do this yay
897
- /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g
898
- );
899
- function isAllowedUri(uri, protocols) {
900
- const allowedProtocols = [
901
- "http",
902
- "https",
903
- "ftp",
904
- "ftps",
905
- "mailto",
906
- "tel",
907
- "callto",
908
- "sms",
909
- "cid",
910
- "xmpp"
911
- ];
912
- if (protocols) {
913
- for (const protocol of protocols) {
914
- const nextProtocol = typeof protocol === "string" ? protocol : protocol.scheme;
915
- if (nextProtocol) {
916
- allowedProtocols.push(nextProtocol);
917
- }
918
- }
919
- }
920
- return !uri || uri.replace(ATTR_WHITESPACE, "").match(
921
- new RegExp(
922
- // eslint-disable-next-line no-useless-escape
923
- `^(?:(?:${allowedProtocols.join("|")}):|[^a-z]|[a-z0-9+.-]+(?:[^a-z+.-:]|$))`,
924
- "i"
925
- )
926
- );
927
- }
928
- function sanitizeUrl(inputUrl, baseUrl, protocols) {
929
- try {
930
- const url = new URL(inputUrl, baseUrl);
931
- if (isAllowedUri(url.href, protocols)) {
932
- return url.href;
933
- }
934
- } catch {
935
- }
936
- return "#";
937
- }
938
- function isNodeTypeSelected(editor, types = []) {
939
- if (!editor || !editor.state.selection) return false;
940
- const { state } = editor;
941
- const { selection } = state;
942
- if (selection.empty) return false;
943
- if (selection instanceof import_state4.NodeSelection) {
944
- const node = selection.node;
945
- return node ? types.includes(node.type.name) : false;
946
- }
947
- return false;
948
- }
949
- function isExtensionAvailable(editor, extensionNames) {
950
- if (!editor) return false;
951
- const names = Array.isArray(extensionNames) ? extensionNames : [extensionNames];
952
- const found = names.some(
953
- (name) => editor.extensionManager.extensions.some((ext) => ext.name === name)
954
- );
955
- if (!found) {
956
- console.warn(
957
- `None of the extensions [${names.join(", ")}] were found in the editor schema. Ensure they are included in the editor configuration.`
958
- );
959
- }
960
- return found;
961
- }
962
- function getEditorExtension(editor, extensionName) {
963
- if (!editor) return null;
964
- const extension = editor.extensionManager.extensions.find(
965
- (ext) => ext.name === extensionName
966
- );
967
- if (!extension) {
968
- console.warn(
969
- `Extension "${extensionName}" not found in the editor schema. Ensure it is included in the editor configuration.`
970
- );
971
- return null;
972
- }
973
- return extension;
974
- }
975
- function hasContentAbove(editor) {
976
- if (!editor) return { hasContent: false, content: "" };
977
- const { state } = editor;
978
- const { $from } = state.selection;
979
- for (let i = $from.index(0) - 1; i >= 0; i--) {
980
- const node = state.doc.child(i);
981
- const content = node.textContent.trim();
982
- if (content) {
983
- return { hasContent: true, content };
984
- }
985
- }
986
- return { hasContent: false, content: "" };
987
- }
988
- function findSelectionPosition(params) {
989
- const { editor, node, nodePos } = params;
990
- if (isValidPosition(nodePos)) return nodePos;
991
- if (node) {
992
- const found = findNodePosition({ editor, node });
993
- if (found) return found.pos;
994
- }
995
- const { selection } = editor.state;
996
- if (!selection.empty) return null;
997
- const resolvedPos = selection.$anchor;
998
- const nodeDepth = 1;
999
- const selectedNode = resolvedPos.node(nodeDepth);
1000
- return selectedNode ? resolvedPos.before(nodeDepth) : null;
1001
- }
1002
- function isValidPosition(pos) {
1003
- return typeof pos === "number" && pos >= 0;
1004
- }
1005
- function getElementOverflowPosition(targetElement, containerElement) {
1006
- const targetBounds = targetElement.getBoundingClientRect();
1007
- const containerBounds = containerElement.getBoundingClientRect();
1008
- const isOverflowingTop = targetBounds.top < containerBounds.top;
1009
- const isOverflowingBottom = targetBounds.bottom > containerBounds.bottom;
1010
- if (isOverflowingTop && isOverflowingBottom) return "both";
1011
- if (isOverflowingTop) return "top";
1012
- if (isOverflowingBottom) return "bottom";
1013
- return "none";
1014
- }
1015
- function findParentNodeOfType(selection, typeName) {
1016
- let depth = selection.$anchor.depth;
1017
- while (depth > 0) {
1018
- const node = selection.$anchor.node(depth);
1019
- if (node.type.name === typeName) {
1020
- return { node, pos: selection.$anchor.start(depth) - 1 };
1021
- }
1022
- depth--;
1023
- }
1024
- return null;
1025
- }
1026
-
1027
- // src/extensions/table/table/utilities/insert-line-above-table-action.ts
1028
- var insertLineAboveTableAction = ({
1029
- editor
1030
- }) => {
1031
- if (!editor.isActive("table")) return false;
1032
- try {
1033
- const { selection } = editor.state;
1034
- const tableNode = findParentNodeOfType(selection, "table");
1035
- if (!tableNode) return false;
1036
- const tablePos = tableNode.pos;
1037
- const firstRow = tableNode.node.child(0);
1038
- const selectionPath = selection.$anchor.path;
1039
- const selectionInFirstRow = selectionPath.includes(firstRow);
1040
- if (!selectionInFirstRow) return false;
1041
- if (tablePos === 0) {
1042
- editor.chain().insertContentAt(tablePos, { type: "paragraph" }).run();
1043
- editor.chain().setTextSelection(tablePos + 1).run();
1044
- } else {
1045
- const prevNodePos = tablePos - 1;
1046
- if (prevNodePos <= 0) return false;
1047
- const prevNode = editor.state.doc.nodeAt(prevNodePos - 1);
1048
- if (prevNode && prevNode.type.name === "paragraph") {
1049
- const endOfParagraphPos = tablePos - prevNode.nodeSize;
1050
- editor.chain().setTextSelection(endOfParagraphPos).run();
1051
- } else {
1052
- return false;
1053
- }
1054
- }
1055
- return true;
1056
- } catch (e) {
1057
- console.error("failed to insert line above table", e);
1058
- return false;
1059
- }
1060
- };
1061
-
1062
- // src/extensions/table/table/utilities/insert-line-below-table-action.ts
1063
- var insertLineBelowTableAction = ({
1064
- editor
1065
- }) => {
1066
- if (!editor.isActive("table")) return false;
1067
- try {
1068
- const { selection } = editor.state;
1069
- const tableNode = findParentNodeOfType(selection, "table");
1070
- if (!tableNode) return false;
1071
- const tablePos = tableNode.pos;
1072
- const table = tableNode.node;
1073
- const rowCount = table.childCount;
1074
- const lastRow = table.child(rowCount - 1);
1075
- const selectionPath = selection.$anchor.path;
1076
- const selectionInLastRow = selectionPath.includes(lastRow);
1077
- if (!selectionInLastRow) return false;
1078
- const nextNodePos = tablePos + table.nodeSize;
1079
- const nextNode = editor.state.doc.nodeAt(nextNodePos);
1080
- if (nextNode && nextNode.type.name === "paragraph") {
1081
- const endOfParagraphPos = nextNodePos + nextNode.nodeSize - 1;
1082
- editor.chain().setTextSelection(endOfParagraphPos).run();
1083
- } else if (!nextNode) {
1084
- editor.chain().insertContentAt(nextNodePos, { type: "paragraph" }).run();
1085
- editor.chain().setTextSelection(nextNodePos + 1).run();
1086
- } else {
1087
- return false;
1088
- }
1089
- return true;
1090
- } catch (e) {
1091
- console.error("failed to insert line above table", e);
1092
- return false;
1093
- }
1094
- };
1095
-
1096
- // src/extensions/table/table/table.ts
1097
- var Table = import_extension_table.Table.extend({
1098
- addOptions() {
1099
- var _a;
1100
- return {
1101
- ...(_a = this.parent) == null ? void 0 : _a.call(this),
1102
- HTMLAttributes: {},
1103
- resizable: true,
1104
- handleWidth: 5,
1105
- cellMinWidth: 100,
1106
- lastColumnResizable: true,
1107
- allowTableNodeSelection: true
1108
- };
1109
- },
1110
- addKeyboardShortcuts() {
1111
- var _a;
1112
- return {
1113
- ...(_a = this.parent) == null ? void 0 : _a.call(this),
1114
- Tab: () => {
1115
- if (this.editor.isActive("table")) {
1116
- if (this.editor.isActive("listItem") || this.editor.isActive("taskItem")) {
1117
- return false;
1118
- }
1119
- if (this.editor.commands.goToNextCell()) {
1120
- return true;
1121
- }
1122
- if (!this.editor.can().addRowAfter()) {
1123
- return false;
1124
- }
1125
- return this.editor.chain().addRowAfter().goToNextCell().run();
1126
- }
1127
- return false;
1128
- },
1129
- ArrowDown: insertLineBelowTableAction,
1130
- ArrowUp: insertLineAboveTableAction
1131
- };
1132
- },
1133
- addNodeView() {
1134
- return ({ editor, getPos, node, decorations }) => {
1135
- const { cellMinWidth } = this.options;
1136
- return new TableView(
1137
- node,
1138
- cellMinWidth,
1139
- // biome-ignore lint/suspicious/noExplicitAny: prosemirror
1140
- decorations,
1141
- editor,
1142
- getPos
1143
- );
1144
- };
1145
- },
1146
- addProseMirrorPlugins() {
1147
- const isResizable = this.options.resizable && this.editor.isEditable;
1148
- const plugins = [
1149
- (0, import_tables2.tableEditing)({
1150
- allowTableNodeSelection: this.options.allowTableNodeSelection
1151
- }),
1152
- tableControls()
1153
- ];
1154
- if (isResizable) {
1155
- plugins.unshift(
1156
- (0, import_tables2.columnResizing)({
1157
- handleWidth: this.options.handleWidth,
1158
- cellMinWidth: this.options.cellMinWidth,
1159
- // View: TableView,
1160
- lastColumnResizable: this.options.lastColumnResizable
1161
- })
1162
- );
1163
- }
1164
- return plugins;
1165
- }
1166
- });
1167
-
1168
- // src/extensions/table/table-cell.ts
1169
- var import_core2 = require("@tiptap/core");
1170
- var TableCell = import_core2.Node.create({
1171
- name: "tableCell",
1172
- content: "block+",
1173
- // DONT allow table in table.
1174
- tableRole: "cell",
1175
- isolating: true,
1176
- addOptions() {
1177
- return {
1178
- HTMLAttributes: {}
1179
- };
1180
- },
1181
- parseHTML() {
1182
- return [{ tag: "td" }];
1183
- },
1184
- renderHTML({ node, HTMLAttributes }) {
1185
- return [
1186
- "td",
1187
- (0, import_core2.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes, {
1188
- style: `background-color: ${node.attrs.background}; color: ${node.attrs.textColor}`
1189
- }),
1190
- 0
1191
- ];
1192
- },
1193
- addAttributes() {
1194
- return {
1195
- colspan: {
1196
- default: 1,
1197
- parseHTML: (element) => {
1198
- const colspan = element.getAttribute("colspan");
1199
- const value = colspan ? Number.parseInt(colspan, 10) : 1;
1200
- return value;
1201
- }
1202
- },
1203
- rowspan: {
1204
- default: 1,
1205
- parseHTML: (element) => {
1206
- const rowspan = element.getAttribute("rowspan");
1207
- const value = rowspan ? Number.parseInt(rowspan, 10) : 1;
1208
- return value;
1209
- }
1210
- },
1211
- colwidth: {
1212
- default: null,
1213
- parseHTML: (element) => {
1214
- const colwidth = element.getAttribute("colwidth");
1215
- const value = colwidth ? [Number.parseInt(colwidth, 10)] : null;
1216
- return value;
1217
- }
1218
- },
1219
- background: {
1220
- default: null
1221
- },
1222
- textColor: {
1223
- default: null
1224
- },
1225
- style: {
1226
- default: null
1227
- }
1228
- };
1229
- }
1230
- // addProseMirrorPlugins() {
1231
- // return [
1232
- // new Plugin({
1233
- // props: {
1234
- // decorations: (state) => {
1235
- // const { isEditable } = this.editor;
1236
- // if (!isEditable) {
1237
- // return DecorationSet.empty;
1238
- // }
1239
- // const { doc, selection } = state;
1240
- // const decorations: Decoration[] = [];
1241
- // const cells = getCellsInColumn(0)(selection);
1242
- // if (cells) {
1243
- // cells.forEach(({ pos }: { pos: number }, index: number) => {
1244
- // decorations.push(
1245
- // Decoration.widget(pos + 1, () => {
1246
- // const rowSelected = isRowSelected(index)(selection);
1247
- // let className = "grip-row";
1248
- // if (rowSelected) {
1249
- // className += " selected";
1250
- // }
1251
- // if (index === 0) {
1252
- // className += " first";
1253
- // }
1254
- // if (index === cells.length - 1) {
1255
- // className += " last";
1256
- // }
1257
- // const grip = document.createElement("a");
1258
- // grip.className = className;
1259
- // grip.addEventListener("mousedown", (event) => {
1260
- // event.preventDefault();
1261
- // event.stopImmediatePropagation();
1262
- // this.editor.view.dispatch(
1263
- // selectRow(index)(this.editor.state.tr),
1264
- // );
1265
- // });
1266
- // return grip;
1267
- // }),
1268
- // );
1269
- // });
1270
- // }
1271
- // return DecorationSet.create(doc, decorations);
1272
- // },
1273
- // },
1274
- // }),
1275
- // ];
1276
- // },
1277
- });
1278
-
1279
- // src/extensions/table/table-header.ts
1280
- var import_extension_table2 = require("@tiptap/extension-table");
1281
- var TableHeader = import_extension_table2.TableHeader.extend({
1282
- addAttributes() {
1283
- return {
1284
- colspan: {
1285
- default: 1
1286
- },
1287
- rowspan: {
1288
- default: 1
1289
- },
1290
- colwidth: {
1291
- default: null,
1292
- parseHTML: (element) => {
1293
- const colwidth = element.getAttribute("colwidth");
1294
- const value = colwidth ? [Number.parseInt(colwidth, 10)] : null;
1295
- return value;
102
+ return;
103
+ }
104
+ const $start = doc.resolve(start);
105
+ const $end = doc.resolve(end);
106
+ const transaction = tr.setSelection(
107
+ new import_state.TextSelection($start, $end)
108
+ );
109
+ view.dispatch(transaction);
110
+ }
1296
111
  }
1297
- },
1298
- background: {
1299
- default: "none"
1300
- },
1301
- style: {
1302
- default: null
1303
- }
1304
- };
112
+ })
113
+ ];
1305
114
  }
1306
- // addProseMirrorPlugins() {
1307
- // return [
1308
- // new Plugin({
1309
- // props: {
1310
- // decorations: (state) => {
1311
- // const { isEditable } = this.editor;
1312
- // if (!isEditable) {
1313
- // return DecorationSet.empty;
1314
- // }
1315
- // const { doc, selection } = state;
1316
- // const decorations: Decoration[] = [];
1317
- // const cells = getCellsInRow(0)(selection);
1318
- // if (cells) {
1319
- // cells.forEach(({ pos }, index) => {
1320
- // decorations.push(
1321
- // Decoration.widget(pos + 1, () => {
1322
- // const colSelected = isColumnSelected(index)(selection);
1323
- // let className = "grip-column";
1324
- // if (colSelected) {
1325
- // className += " selected";
1326
- // }
1327
- // if (index === 0) {
1328
- // className += " first";
1329
- // }
1330
- // if (index === cells.length - 1) {
1331
- // className += " last";
1332
- // }
1333
- // const grip = document.createElement("a");
1334
- // grip.className = className;
1335
- // grip.addEventListener("mousedown", (event) => {
1336
- // event.preventDefault();
1337
- // event.stopImmediatePropagation();
1338
- // this.editor.view.dispatch(
1339
- // selectColumn(index)(this.editor.state.tr),
1340
- // );
1341
- // });
1342
- // return grip;
1343
- // }),
1344
- // );
1345
- // });
1346
- // }
1347
- // return DecorationSet.create(doc, decorations);
1348
- // },
1349
- // },
1350
- // }),
1351
- // ];
1352
- // },
1353
- });
1354
-
1355
- // src/extensions/table/table-row.ts
1356
- var import_extension_table3 = require("@tiptap/extension-table");
1357
- var TableRow = import_extension_table3.TableRow.extend({
1358
- allowGapCursor: false,
1359
- content: "(tableCell | tableHeader)*"
1360
115
  });
1361
116
 
1362
- // src/extensions/table/kit.ts
1363
- var TableKit = import_react3.Extension.create({
1364
- name: "tableKit",
1365
- addExtensions() {
1366
- const extensions = [];
1367
- if (this.options.table !== false) {
1368
- extensions.push(Table.configure(this.options.table));
1369
- }
1370
- if (this.options.tableCell !== false) {
1371
- extensions.push(TableCell.configure(this.options.tableCell));
1372
- }
1373
- if (this.options.tableHeader !== false) {
1374
- extensions.push(TableHeader.configure(this.options.tableHeader));
1375
- }
1376
- if (this.options.tableRow !== false) {
1377
- extensions.push(TableRow.configure(this.options.tableRow));
1378
- }
1379
- return extensions;
117
+ // src/extensions/selection/index.ts
118
+ var import_state2 = require("@tiptap/pm/state");
119
+ var import_view = require("@tiptap/pm/view");
120
+ var import_react2 = require("@tiptap/react");
121
+ var Selection = import_react2.Extension.create({
122
+ name: "selection",
123
+ addProseMirrorPlugins() {
124
+ const { editor } = this;
125
+ return [
126
+ new import_state2.Plugin({
127
+ key: new import_state2.PluginKey("selection"),
128
+ props: {
129
+ decorations(state) {
130
+ if (state.selection.empty) {
131
+ return null;
132
+ }
133
+ if (editor.isFocused === true || !editor.isEditable) {
134
+ return null;
135
+ }
136
+ if ((0, import_react2.isNodeSelection)(state.selection)) {
137
+ return null;
138
+ }
139
+ return import_view.DecorationSet.create(state.doc, [
140
+ import_view.Decoration.inline(state.selection.from, state.selection.to, {
141
+ class: "selection"
142
+ })
143
+ ]);
144
+ }
145
+ }
146
+ })
147
+ ];
1380
148
  }
1381
149
  });
1382
150
 
1383
151
  // src/extensions/trailing-node/index.ts
1384
- var import_state5 = require("@tiptap/pm/state");
1385
- var import_react4 = require("@tiptap/react");
152
+ var import_state3 = require("@tiptap/pm/state");
153
+ var import_react3 = require("@tiptap/react");
1386
154
  function nodeEqualsType({
1387
155
  types,
1388
156
  node
@@ -1393,7 +161,7 @@ function nodeEqualsType({
1393
161
  }
1394
162
  return node.type === types;
1395
163
  }
1396
- var TrailingNode = import_react4.Extension.create({
164
+ var TrailingNode = import_react3.Extension.create({
1397
165
  name: "trailingNode",
1398
166
  addOptions() {
1399
167
  return {
@@ -1402,10 +170,10 @@ var TrailingNode = import_react4.Extension.create({
1402
170
  };
1403
171
  },
1404
172
  addProseMirrorPlugins() {
1405
- const plugin = new import_state5.PluginKey(this.name);
173
+ const plugin = new import_state3.PluginKey(this.name);
1406
174
  const disabledNodes = Object.entries(this.editor.schema.nodes).map(([, value]) => value).filter((node) => this.options.notAfter.includes(node.name));
1407
175
  return [
1408
- new import_state5.Plugin({
176
+ new import_state3.Plugin({
1409
177
  key: plugin,
1410
178
  appendTransaction: (_, __, state) => {
1411
179
  const { doc, tr, schema } = state;
@@ -1439,7 +207,7 @@ var TrailingNode = import_react4.Extension.create({
1439
207
  });
1440
208
 
1441
209
  // src/extensions/ui-state/index.ts
1442
- var import_core3 = require("@tiptap/core");
210
+ var import_core = require("@tiptap/core");
1443
211
  var defaultUiState = {
1444
212
  aiGenerationIsSelection: false,
1445
213
  aiGenerationIsLoading: false,
@@ -1449,7 +217,7 @@ var defaultUiState = {
1449
217
  lockDragHandle: false,
1450
218
  isDragging: false
1451
219
  };
1452
- var UiState = import_core3.Extension.create({
220
+ var UiState = import_core.Extension.create({
1453
221
  name: "uiState",
1454
222
  addStorage() {
1455
223
  return {
@@ -1457,12 +225,12 @@ var UiState = import_core3.Extension.create({
1457
225
  };
1458
226
  },
1459
227
  addCommands() {
1460
- const createBooleanSetter = (key2) => (value) => () => {
1461
- this.storage[key2] = value;
228
+ const createBooleanSetter = (key) => (value) => () => {
229
+ this.storage[key] = value;
1462
230
  return true;
1463
231
  };
1464
- const createToggle = (key2, value) => () => () => {
1465
- this.storage[key2] = value;
232
+ const createToggle = (key, value) => () => () => {
233
+ this.storage[key] = value;
1466
234
  return true;
1467
235
  };
1468
236
  return {
@@ -1553,9 +321,10 @@ var useCreateEditor = ({
1553
321
  editable = true,
1554
322
  placeholder = "Write, type '/' for commands\u2026",
1555
323
  onChange,
324
+ controlResolver,
1556
325
  ...options
1557
326
  }) => {
1558
- const editor = (0, import_react5.useEditor)({
327
+ const editor = (0, import_react4.useEditor)({
1559
328
  editorProps: {
1560
329
  attributes: {
1561
330
  autocomplete: "off",
@@ -1566,44 +335,7 @@ var useCreateEditor = ({
1566
335
  },
1567
336
  immediatelyRender: false,
1568
337
  shouldRerenderOnTransaction: false,
1569
- extensions: [
1570
- import_starter_kit.StarterKit.configure({
1571
- trailingNode: false,
1572
- // we use our custom trailing node extension
1573
- link: false
1574
- // we use our custom link extension
1575
- }),
1576
- import_extension_text_align.TextAlign.configure({ types: ["heading", "paragraph"] }),
1577
- import_extension_task_list.TaskList,
1578
- import_extension_task_item.TaskItem.configure({ nested: true }),
1579
- import_extension_highlight.Highlight.configure({ multicolor: true }),
1580
- import_extension_typography.Typography,
1581
- import_extension_superscript.Superscript,
1582
- import_extension_subscript.Subscript,
1583
- Selection,
1584
- TrailingNode,
1585
- Link.configure({ openOnClick: !editable }),
1586
- // disable link click when editing
1587
- import_extension_unique_id.UniqueID.configure({
1588
- types: [
1589
- "paragraph",
1590
- "bulletList",
1591
- "orderedList",
1592
- "taskList",
1593
- "heading",
1594
- "blockquote",
1595
- "codeBlock"
1596
- ]
1597
- // filterTransaction: (transaction) => !isChangeOrigin(transaction),
1598
- }),
1599
- UiState,
1600
- TableKit,
1601
- import_extensions.Placeholder.configure({
1602
- placeholder,
1603
- emptyNodeClass: "is-empty with-slash"
1604
- }),
1605
- import_extension_controlref.ControlKit
1606
- ],
338
+ extensions: getExtensions({ editable, placeholder, controlResolver }),
1607
339
  editable,
1608
340
  onUpdate: ({ editor: editor2 }) => {
1609
341
  onChange == null ? void 0 : onChange(editor2.getJSON());
@@ -1613,12 +345,79 @@ var useCreateEditor = ({
1613
345
  });
1614
346
  return editor;
1615
347
  };
348
+ function getExtensions({
349
+ editable,
350
+ placeholder,
351
+ controlResolver
352
+ }) {
353
+ return [
354
+ import_starter_kit.StarterKit.configure({
355
+ trailingNode: false,
356
+ // we use our custom trailing node extension
357
+ link: false,
358
+ // we use our custom link extension
359
+ code: false,
360
+ // we use our own
361
+ codeBlock: false
362
+ // we use our own
363
+ // undoRedo should be dynamic based on collaboration, later.^
364
+ }),
365
+ import_extension_text_align.TextAlign.configure({ types: ["heading", "paragraph"] }),
366
+ import_extension_list.TaskList,
367
+ import_extension_list.TaskItem.configure({ nested: true }),
368
+ import_extension_invisible_characters.default.configure({
369
+ visible: false
370
+ }),
371
+ import_extension_table_of_contents.TableOfContents.configure({
372
+ getIndex: import_extension_table_of_contents.getHierarchicalIndexes
373
+ }),
374
+ Selection,
375
+ Link.configure({ openOnClick: !editable }),
376
+ // disable link click when editing
377
+ import_extension_text_style.TextStyleKit,
378
+ import_extension_highlight.Highlight.configure({ multicolor: true }),
379
+ import_extensions.CharacterCount,
380
+ import_extension_typography.Typography,
381
+ import_extension_superscript.Superscript,
382
+ import_extension_subscript.Subscript,
383
+ import_extension_code.CodeKit,
384
+ TrailingNode,
385
+ import_extension_unique_id.UniqueID.configure({
386
+ types: [
387
+ "paragraph",
388
+ "bulletList",
389
+ "orderedList",
390
+ "taskList",
391
+ "heading",
392
+ "blockquote",
393
+ "codeBlock"
394
+ ]
395
+ // filterTransaction: (transaction) => !isChangeOrigin(transaction),
396
+ }),
397
+ UiState,
398
+ import_extension_table.TableKit,
399
+ import_extensions.Placeholder.configure({
400
+ placeholder,
401
+ emptyNodeClass: "is-empty with-slash"
402
+ }),
403
+ import_extension_controlref.ControlKit.configure({ resolver: controlResolver })
404
+ ];
405
+ }
406
+
407
+ // src/presets/basic/index.tsx
408
+ var import_theme3 = require("@kopexa/theme");
409
+ var import_react31 = require("@tiptap/react");
410
+ var import_react32 = require("react");
411
+
412
+ // src/context/editor-context.ts
413
+ var import_react_utils = require("@kopexa/react-utils");
414
+ var [EditorUIProvider, useEditorUIContext] = (0, import_react_utils.createContext)();
1616
415
 
1617
416
  // src/hooks/use-ui-editor-state.ts
1618
- var import_react6 = require("@tiptap/react");
417
+ var import_react5 = require("@tiptap/react");
1619
418
  function useUiEditorState(editor) {
1620
419
  var _a;
1621
- return (_a = (0, import_react6.useEditorState)({
420
+ return (_a = (0, import_react5.useEditorState)({
1622
421
  editor,
1623
422
  selector: ({ editor: editor2 }) => {
1624
423
  if (!editor2) return defaultUiState;
@@ -1635,31 +434,32 @@ function useUiEditorState(editor) {
1635
434
  }
1636
435
 
1637
436
  // src/ui/copy-anchor-link-button/use-scroll-to-hash.ts
437
+ var import_editor_utils = require("@kopexa/editor-utils");
1638
438
  var React2 = __toESM(require("react"));
1639
439
 
1640
440
  // src/hooks/use-floating-toolbar-visibility.ts
1641
- var import_state6 = require("@tiptap/pm/state");
1642
- var import_react7 = require("@tiptap/react");
441
+ var import_state4 = require("@tiptap/pm/state");
442
+ var import_react6 = require("@tiptap/react");
1643
443
  var React = __toESM(require("react"));
1644
444
  var HIDE_FLOATING_META = "hideFloatingToolbar";
1645
445
  var selectNodeAndHideFloating = (editor, pos) => {
1646
446
  if (!editor) return;
1647
447
  const { state, view } = editor;
1648
448
  view.dispatch(
1649
- state.tr.setSelection(import_state6.NodeSelection.create(state.doc, pos)).setMeta(HIDE_FLOATING_META, true)
449
+ state.tr.setSelection(import_state4.NodeSelection.create(state.doc, pos)).setMeta(HIDE_FLOATING_META, true)
1650
450
  );
1651
451
  };
1652
452
 
1653
453
  // src/hooks/use-tiptap-editor.ts
1654
- var import_react8 = require("@tiptap/react");
1655
- var import_react9 = require("react");
454
+ var import_react7 = require("@tiptap/react");
455
+ var import_react8 = require("react");
1656
456
  function useTiptapEditor(providedEditor) {
1657
- const { editor: coreEditor } = (0, import_react8.useCurrentEditor)();
1658
- const mainEditor = (0, import_react9.useMemo)(
457
+ const { editor: coreEditor } = (0, import_react7.useCurrentEditor)();
458
+ const mainEditor = (0, import_react8.useMemo)(
1659
459
  () => providedEditor || coreEditor,
1660
460
  [providedEditor, coreEditor]
1661
461
  );
1662
- const editorState = (0, import_react8.useEditorState)({
462
+ const editorState = (0, import_react7.useEditorState)({
1663
463
  editor: mainEditor,
1664
464
  selector(context) {
1665
465
  if (!context.editor) {
@@ -1693,7 +493,7 @@ function useScrollToHash(config = {}) {
1693
493
  (id) => {
1694
494
  var _a, _b, _c;
1695
495
  if (!editor) return false;
1696
- const attributeName = (_c = (_b = (_a = getEditorExtension(editor, "uniqueID")) == null ? void 0 : _a.options) == null ? void 0 : _b.attributeName) != null ? _c : "data-id";
496
+ const attributeName = (_c = (_b = (_a = (0, import_editor_utils.getEditorExtension)(editor, "uniqueID")) == null ? void 0 : _a.options) == null ? void 0 : _b.attributeName) != null ? _c : "data-id";
1697
497
  let position = null;
1698
498
  editor.state.doc.descendants((node, pos) => {
1699
499
  var _a2;
@@ -1767,28 +567,29 @@ function useScrollToHash(config = {}) {
1767
567
 
1768
568
  // src/ui/slash-dropdown-menu/slash-dropdown-menu.tsx
1769
569
  var import_button = require("@kopexa/button");
570
+ var import_editor_utils4 = require("@kopexa/editor-utils");
1770
571
  var import_separator = require("@kopexa/separator");
1771
572
  var import_theme = require("@kopexa/theme");
1772
573
  var React7 = __toESM(require("react"));
1773
574
 
1774
575
  // src/ui/suggestion-menu/suggestion-menu.tsx
1775
- var import_react11 = require("@floating-ui/react");
1776
- var import_state7 = require("@tiptap/pm/state");
576
+ var import_react10 = require("@floating-ui/react");
577
+ var import_state5 = require("@tiptap/pm/state");
1777
578
  var import_suggestion = require("@tiptap/suggestion");
1778
579
  var React5 = __toESM(require("react"));
1779
580
 
1780
581
  // src/hooks/use-floating-element.ts
1781
- var import_react10 = require("@floating-ui/react");
582
+ var import_react9 = require("@floating-ui/react");
1782
583
  var React3 = __toESM(require("react"));
1783
584
  function useFloatingElement(show, referencePos, zIndex, options) {
1784
585
  const { dismissOptions, ...floatingOptions } = options || {};
1785
- const { refs, update, context, floatingStyles } = (0, import_react10.useFloating)({
586
+ const { refs, update, context, floatingStyles } = (0, import_react9.useFloating)({
1786
587
  open: show,
1787
588
  ...floatingOptions
1788
589
  });
1789
- const { isMounted, styles } = (0, import_react10.useTransitionStyles)(context);
1790
- const dismiss = (0, import_react10.useDismiss)(context, dismissOptions);
1791
- const { getReferenceProps, getFloatingProps } = (0, import_react10.useInteractions)([dismiss]);
590
+ const { isMounted, styles } = (0, import_react9.useTransitionStyles)(context);
591
+ const dismiss = (0, import_react9.useDismiss)(context, dismissOptions);
592
+ const { getReferenceProps, getFloatingProps } = (0, import_react9.useInteractions)([dismiss]);
1792
593
  React3.useEffect(() => {
1793
594
  update();
1794
595
  }, [referencePos, update]);
@@ -2022,13 +823,13 @@ var SuggestionMenu = ({
2022
823
  {
2023
824
  placement: "bottom-start",
2024
825
  middleware: [
2025
- (0, import_react11.offset)(10),
2026
- (0, import_react11.flip)({
826
+ (0, import_react10.offset)(10),
827
+ (0, import_react10.flip)({
2027
828
  mainAxis: true,
2028
829
  crossAxis: false
2029
830
  }),
2030
- (0, import_react11.shift)(),
2031
- (0, import_react11.size)({
831
+ (0, import_react10.shift)(),
832
+ (0, import_react10.size)({
2032
833
  apply({ availableHeight, elements }) {
2033
834
  if (elements.floating) {
2034
835
  const maxHeightValue = maxHeight ? Math.min(maxHeight, availableHeight) : availableHeight;
@@ -2066,7 +867,7 @@ var SuggestionMenu = ({
2066
867
  editor.unregisterPlugin(pluginKey);
2067
868
  }
2068
869
  const suggestion = (0, import_suggestion.Suggestion)({
2069
- pluginKey: pluginKey instanceof import_state7.PluginKey ? pluginKey : new import_state7.PluginKey(pluginKey),
870
+ pluginKey: pluginKey instanceof import_state5.PluginKey ? pluginKey : new import_state5.PluginKey(pluginKey),
2070
871
  editor,
2071
872
  command({ editor: editor2, range, props }) {
2072
873
  var _a, _b;
@@ -2188,16 +989,18 @@ var SuggestionMenu = ({
2188
989
  };
2189
990
 
2190
991
  // src/ui/slash-dropdown-menu/use-slash-dropdown-menu.ts
2191
- var import_icons3 = require("@kopexa/icons");
992
+ var import_editor_utils3 = require("@kopexa/editor-utils");
993
+ var import_icons2 = require("@kopexa/icons");
2192
994
  var React6 = __toESM(require("react"));
2193
995
 
2194
996
  // src/ui/table-button/use-table.ts
2195
- var import_icons2 = require("@kopexa/icons");
2196
- var import_react12 = require("@tiptap/react");
2197
- var import_react13 = require("react");
997
+ var import_editor_utils2 = require("@kopexa/editor-utils");
998
+ var import_icons = require("@kopexa/icons");
999
+ var import_react11 = require("@tiptap/react");
1000
+ var import_react12 = require("react");
2198
1001
  function canToggle(editor) {
2199
1002
  if (!editor || !editor.isEditable) return false;
2200
- if (!isNodeInSchema("table", editor) || isNodeTypeSelected(editor, ["image"])) {
1003
+ if (!(0, import_editor_utils2.isNodeInSchema)("table", editor) || (0, import_editor_utils2.isNodeTypeSelected)(editor, ["image"])) {
2201
1004
  return false;
2202
1005
  }
2203
1006
  try {
@@ -2223,9 +1026,9 @@ function toggleTable(editor, config) {
2223
1026
  function shouldShowButton(props) {
2224
1027
  const { editor, hideWhenUnavailable } = props;
2225
1028
  if (!editor || !editor.isEditable) return false;
2226
- if (!isNodeInSchema("table", editor)) return false;
1029
+ if (!(0, import_editor_utils2.isNodeInSchema)("table", editor)) return false;
2227
1030
  if (hideWhenUnavailable) {
2228
- if ((0, import_react12.isNodeSelection)(editor.state.selection) || !canToggle) {
1031
+ if ((0, import_react11.isNodeSelection)(editor.state.selection) || !canToggle) {
2229
1032
  return false;
2230
1033
  }
2231
1034
  }
@@ -2238,10 +1041,10 @@ function useTableBlock(config) {
2238
1041
  onToggled
2239
1042
  } = config || {};
2240
1043
  const { editor } = useTiptapEditor(providedEditor);
2241
- const [isVisible, setIsVisible] = (0, import_react13.useState)(true);
1044
+ const [isVisible, setIsVisible] = (0, import_react12.useState)(true);
2242
1045
  const canToggleState = canToggle(editor);
2243
1046
  const isActive = (editor == null ? void 0 : editor.isActive("table")) || false;
2244
- (0, import_react13.useEffect)(() => {
1047
+ (0, import_react12.useEffect)(() => {
2245
1048
  if (!editor) return;
2246
1049
  const handleSelectionUpdate = () => {
2247
1050
  setIsVisible(shouldShowButton({ editor, hideWhenUnavailable }));
@@ -2252,7 +1055,7 @@ function useTableBlock(config) {
2252
1055
  editor.off("selectionUpdate", handleSelectionUpdate);
2253
1056
  };
2254
1057
  }, [editor, hideWhenUnavailable]);
2255
- const handleToggle = (0, import_react13.useCallback)(() => {
1058
+ const handleToggle = (0, import_react12.useCallback)(() => {
2256
1059
  if (!editor) return false;
2257
1060
  const success = toggleTable(editor);
2258
1061
  if (success) {
@@ -2267,7 +1070,7 @@ function useTableBlock(config) {
2267
1070
  canToggle: canToggleState,
2268
1071
  label: "Table",
2269
1072
  // shortcutKeys: CODE_BLOCK_SHORTCUT_KEY,
2270
- Icon: import_icons2.TableIcon
1073
+ Icon: import_icons.TableIcon
2271
1074
  };
2272
1075
  }
2273
1076
 
@@ -2278,14 +1081,14 @@ var texts = {
2278
1081
  title: "Continue Writing",
2279
1082
  subtext: "Continue writing from the current position",
2280
1083
  keywords: ["continue", "write", "continue writing", "ai"],
2281
- badge: import_icons3.AiSparklesIcon,
1084
+ badge: import_icons2.AiSparklesIcon,
2282
1085
  group: "AI"
2283
1086
  },
2284
1087
  ai_ask_button: {
2285
1088
  title: "Ask AI",
2286
1089
  subtext: "Ask AI to generate content",
2287
1090
  keywords: ["ai", "ask", "generate"],
2288
- badge: import_icons3.AiSparklesIcon,
1091
+ badge: import_icons2.AiSparklesIcon,
2289
1092
  group: "AI"
2290
1093
  },
2291
1094
  // Style
@@ -2293,63 +1096,63 @@ var texts = {
2293
1096
  title: "Text",
2294
1097
  subtext: "Regular text paragraph",
2295
1098
  keywords: ["p", "paragraph", "text"],
2296
- badge: import_icons3.TypeIcon,
1099
+ badge: import_icons2.TypeIcon,
2297
1100
  group: "Style"
2298
1101
  },
2299
1102
  heading_1: {
2300
1103
  title: "Heading 1",
2301
1104
  subtext: "Top-level heading",
2302
1105
  keywords: ["h", "heading1", "h1"],
2303
- badge: import_icons3.HeadingOneIcon,
1106
+ badge: import_icons2.HeadingOneIcon,
2304
1107
  group: "Style"
2305
1108
  },
2306
1109
  heading_2: {
2307
1110
  title: "Heading 2",
2308
1111
  subtext: "Key section heading",
2309
1112
  keywords: ["h2", "heading2", "subheading"],
2310
- badge: import_icons3.HeadingTwoIcon,
1113
+ badge: import_icons2.HeadingTwoIcon,
2311
1114
  group: "Style"
2312
1115
  },
2313
1116
  heading_3: {
2314
1117
  title: "Heading 3",
2315
1118
  subtext: "Subsection and group heading",
2316
1119
  keywords: ["h3", "heading3", "subheading"],
2317
- badge: import_icons3.HeadingThreeIcon,
1120
+ badge: import_icons2.HeadingThreeIcon,
2318
1121
  group: "Style"
2319
1122
  },
2320
1123
  bullet_list: {
2321
1124
  title: "Bullet List",
2322
1125
  subtext: "List with unordered items",
2323
1126
  keywords: ["ul", "li", "list", "bulletlist", "bullet list"],
2324
- badge: import_icons3.ListIcon,
1127
+ badge: import_icons2.ListIcon,
2325
1128
  group: "Style"
2326
1129
  },
2327
1130
  ordered_list: {
2328
1131
  title: "Numbered List",
2329
1132
  subtext: "List with ordered items",
2330
1133
  keywords: ["ol", "li", "list", "numberedlist", "numbered list"],
2331
- badge: import_icons3.ListOrderedIcon,
1134
+ badge: import_icons2.ListOrderedIcon,
2332
1135
  group: "Style"
2333
1136
  },
2334
1137
  task_list: {
2335
1138
  title: "To-do list",
2336
1139
  subtext: "List with tasks",
2337
1140
  keywords: ["tasklist", "task list", "todo", "checklist"],
2338
- badge: import_icons3.ListTodoIcon,
1141
+ badge: import_icons2.ListTodoIcon,
2339
1142
  group: "Style"
2340
1143
  },
2341
1144
  quote: {
2342
1145
  title: "Blockquote",
2343
1146
  subtext: "Blockquote block",
2344
1147
  keywords: ["quote", "blockquote"],
2345
- badge: import_icons3.BlockquoteIcon,
1148
+ badge: import_icons2.BlockquoteIcon,
2346
1149
  group: "Style"
2347
1150
  },
2348
1151
  code_block: {
2349
1152
  title: "Code Block",
2350
1153
  subtext: "Code block with syntax highlighting",
2351
1154
  keywords: ["code", "pre"],
2352
- badge: import_icons3.CodeBlockIcon,
1155
+ badge: import_icons2.CodeBlockIcon,
2353
1156
  group: "Style"
2354
1157
  },
2355
1158
  // Insert
@@ -2371,21 +1174,21 @@ var texts = {
2371
1174
  title: "Control",
2372
1175
  subtext: "Insert a control block",
2373
1176
  keywords: ["control"],
2374
- badge: import_icons3.ControlsIcon,
1177
+ badge: import_icons2.ControlsIcon,
2375
1178
  group: "Insert"
2376
1179
  },
2377
1180
  divider: {
2378
1181
  title: "Separator",
2379
1182
  subtext: "Horizontal line to separate content",
2380
1183
  keywords: ["hr", "horizontalRule", "line", "separator"],
2381
- badge: import_icons3.MinusIcon,
1184
+ badge: import_icons2.MinusIcon,
2382
1185
  group: "Insert"
2383
1186
  },
2384
1187
  table: {
2385
1188
  title: "Table",
2386
1189
  subtext: "Insert a table",
2387
1190
  keywords: ["table", "grid", "spreadsheet"],
2388
- badge: import_icons3.TableIcon,
1191
+ badge: import_icons2.TableIcon,
2389
1192
  group: "Insert"
2390
1193
  },
2391
1194
  // Upload
@@ -2401,7 +1204,7 @@ var texts = {
2401
1204
  "media",
2402
1205
  "url"
2403
1206
  ],
2404
- badge: import_icons3.ImageIcon,
1207
+ badge: import_icons2.ImageIcon,
2405
1208
  group: "Upload"
2406
1209
  }
2407
1210
  };
@@ -2410,8 +1213,8 @@ var getItemImplementations = () => {
2410
1213
  // AI
2411
1214
  continue_writing: {
2412
1215
  check: (editor) => {
2413
- const { hasContent } = hasContentAbove(editor);
2414
- const extensionsReady = isExtensionAvailable(editor, [
1216
+ const { hasContent } = (0, import_editor_utils3.hasContentAbove)(editor);
1217
+ const extensionsReady = (0, import_editor_utils3.isExtensionAvailable)(editor, [
2415
1218
  "ai",
2416
1219
  "aiAdvanced"
2417
1220
  ]);
@@ -2419,14 +1222,14 @@ var getItemImplementations = () => {
2419
1222
  },
2420
1223
  action: ({ editor }) => {
2421
1224
  const editorChain = editor.chain().focus();
2422
- const nodeSelectionPosition = findSelectionPosition({ editor });
1225
+ const nodeSelectionPosition = (0, import_editor_utils3.findSelectionPosition)({ editor });
2423
1226
  if (nodeSelectionPosition !== null) {
2424
1227
  editorChain.setNodeSelection(nodeSelectionPosition);
2425
1228
  }
2426
1229
  editorChain.run();
2427
1230
  editor.chain().focus().aiGenerationShow().run();
2428
1231
  requestAnimationFrame(() => {
2429
- const { hasContent, content } = hasContentAbove(editor);
1232
+ const { hasContent, content } = (0, import_editor_utils3.hasContentAbove)(editor);
2430
1233
  const snippet = content.length > 500 ? `...${content.slice(-500)}` : content;
2431
1234
  const prompt = hasContent ? `Context: ${snippet}
2432
1235
 
@@ -2440,10 +1243,10 @@ Continue writing from where the text above ends. Write ONLY ONE SENTENCE. DONT R
2440
1243
  }
2441
1244
  },
2442
1245
  ai_ask_button: {
2443
- check: (editor) => isExtensionAvailable(editor, ["ai", "aiAdvanced"]),
1246
+ check: (editor) => (0, import_editor_utils3.isExtensionAvailable)(editor, ["ai", "aiAdvanced"]),
2444
1247
  action: ({ editor }) => {
2445
1248
  const editorChain = editor.chain().focus();
2446
- const nodeSelectionPosition = findSelectionPosition({ editor });
1249
+ const nodeSelectionPosition = (0, import_editor_utils3.findSelectionPosition)({ editor });
2447
1250
  if (nodeSelectionPosition !== null) {
2448
1251
  editorChain.setNodeSelection(nodeSelectionPosition);
2449
1252
  }
@@ -2453,55 +1256,55 @@ Continue writing from where the text above ends. Write ONLY ONE SENTENCE. DONT R
2453
1256
  },
2454
1257
  // Style
2455
1258
  text: {
2456
- check: (editor) => isNodeInSchema("paragraph", editor),
1259
+ check: (editor) => (0, import_editor_utils3.isNodeInSchema)("paragraph", editor),
2457
1260
  action: ({ editor }) => {
2458
1261
  editor.chain().focus().setParagraph().run();
2459
1262
  }
2460
1263
  },
2461
1264
  heading_1: {
2462
- check: (editor) => isNodeInSchema("heading", editor),
1265
+ check: (editor) => (0, import_editor_utils3.isNodeInSchema)("heading", editor),
2463
1266
  action: ({ editor }) => {
2464
1267
  editor.chain().focus().toggleHeading({ level: 1 }).run();
2465
1268
  }
2466
1269
  },
2467
1270
  heading_2: {
2468
- check: (editor) => isNodeInSchema("heading", editor),
1271
+ check: (editor) => (0, import_editor_utils3.isNodeInSchema)("heading", editor),
2469
1272
  action: ({ editor }) => {
2470
1273
  editor.chain().focus().toggleHeading({ level: 2 }).run();
2471
1274
  }
2472
1275
  },
2473
1276
  heading_3: {
2474
- check: (editor) => isNodeInSchema("heading", editor),
1277
+ check: (editor) => (0, import_editor_utils3.isNodeInSchema)("heading", editor),
2475
1278
  action: ({ editor }) => {
2476
1279
  editor.chain().focus().toggleHeading({ level: 3 }).run();
2477
1280
  }
2478
1281
  },
2479
1282
  bullet_list: {
2480
- check: (editor) => isNodeInSchema("bulletList", editor),
1283
+ check: (editor) => (0, import_editor_utils3.isNodeInSchema)("bulletList", editor),
2481
1284
  action: ({ editor }) => {
2482
1285
  editor.chain().focus().toggleBulletList().run();
2483
1286
  }
2484
1287
  },
2485
1288
  ordered_list: {
2486
- check: (editor) => isNodeInSchema("orderedList", editor),
1289
+ check: (editor) => (0, import_editor_utils3.isNodeInSchema)("orderedList", editor),
2487
1290
  action: ({ editor }) => {
2488
1291
  editor.chain().focus().toggleOrderedList().run();
2489
1292
  }
2490
1293
  },
2491
1294
  task_list: {
2492
- check: (editor) => isNodeInSchema("taskList", editor),
1295
+ check: (editor) => (0, import_editor_utils3.isNodeInSchema)("taskList", editor),
2493
1296
  action: ({ editor }) => {
2494
1297
  editor.chain().focus().toggleTaskList().run();
2495
1298
  }
2496
1299
  },
2497
1300
  quote: {
2498
- check: (editor) => isNodeInSchema("blockquote", editor),
1301
+ check: (editor) => (0, import_editor_utils3.isNodeInSchema)("blockquote", editor),
2499
1302
  action: ({ editor }) => {
2500
1303
  editor.chain().focus().toggleBlockquote().run();
2501
1304
  }
2502
1305
  },
2503
1306
  code_block: {
2504
- check: (editor) => isNodeInSchema("codeBlock", editor),
1307
+ check: (editor) => (0, import_editor_utils3.isNodeInSchema)("codeBlock", editor),
2505
1308
  action: ({ editor }) => {
2506
1309
  editor.chain().focus().toggleNode("codeBlock", "paragraph").run();
2507
1310
  }
@@ -2518,21 +1321,20 @@ Continue writing from where the text above ends. Write ONLY ONE SENTENCE. DONT R
2518
1321
  // action: ({ editor }: { editor: Editor }) => addEmojiTrigger(editor),
2519
1322
  // },
2520
1323
  divider: {
2521
- check: (editor) => isNodeInSchema("horizontalRule", editor),
1324
+ check: (editor) => (0, import_editor_utils3.isNodeInSchema)("horizontalRule", editor),
2522
1325
  action: ({ editor }) => {
2523
1326
  editor.chain().focus().setHorizontalRule().run();
2524
1327
  }
2525
1328
  },
2526
1329
  table: {
2527
- check: (editor) => isNodeInSchema("table", editor),
1330
+ check: (editor) => (0, import_editor_utils3.isNodeInSchema)("table", editor),
2528
1331
  action: ({ editor }) => toggleTable(editor, { rows: 3, cols: 3, withHeaderRow: true })
2529
1332
  },
2530
1333
  control: {
2531
- check: (editor) => isNodeInSchema("controlRef", editor),
1334
+ check: (editor) => (0, import_editor_utils3.isNodeInSchema)("controlBlock", editor),
2532
1335
  action: ({ editor }) => {
2533
- console.log("hoho");
2534
1336
  try {
2535
- return editor.chain().focus().insertControlRef().run();
1337
+ return editor.chain().focus().insertControlBlock().run();
2536
1338
  } catch (e) {
2537
1339
  console.error(e);
2538
1340
  }
@@ -2540,7 +1342,7 @@ Continue writing from where the text above ends. Write ONLY ONE SENTENCE. DONT R
2540
1342
  },
2541
1343
  // Upload
2542
1344
  image: {
2543
- check: (editor) => isNodeInSchema("image", editor),
1345
+ check: (editor) => (0, import_editor_utils3.isNodeInSchema)("image", editor),
2544
1346
  action: ({ editor }) => {
2545
1347
  editor.chain().focus().insertContent({
2546
1348
  type: "imageUpload"
@@ -2631,7 +1433,7 @@ var Item = (props) => {
2631
1433
  '[data-selector="tiptap-slash-dropdown-menu"]'
2632
1434
  );
2633
1435
  if (!itemRef.current || !isSelected || !selector) return;
2634
- const overflow = getElementOverflowPosition(itemRef.current, selector);
1436
+ const overflow = (0, import_editor_utils4.getElementOverflowPosition)(itemRef.current, selector);
2635
1437
  if (overflow === "top") {
2636
1438
  itemRef.current.scrollIntoView(true);
2637
1439
  } else if (overflow === "bottom") {
@@ -2749,11 +1551,11 @@ var List = ({
2749
1551
  };
2750
1552
 
2751
1553
  // src/presets/basic/editor-header.tsx
2752
- var import_icons18 = require("@kopexa/icons");
1554
+ var import_icons17 = require("@kopexa/icons");
2753
1555
  var import_popover3 = require("@kopexa/popover");
2754
1556
  var import_toolbar9 = require("@kopexa/toolbar");
2755
1557
  var import_use_is_mobile2 = require("@kopexa/use-is-mobile");
2756
- var import_react31 = require("react");
1558
+ var import_react30 = require("react");
2757
1559
 
2758
1560
  // src/hooks/use-cursor-visibility.ts
2759
1561
  var React9 = __toESM(require("react"));
@@ -2862,14 +1664,15 @@ var import_toolbar = require("@kopexa/toolbar");
2862
1664
  var React11 = __toESM(require("react"));
2863
1665
 
2864
1666
  // src/ui/blockquote-button/use-blockquote.ts
2865
- var import_icons4 = require("@kopexa/icons");
2866
- var import_state8 = require("@tiptap/pm/state");
1667
+ var import_editor_utils5 = require("@kopexa/editor-utils");
1668
+ var import_icons3 = require("@kopexa/icons");
1669
+ var import_state6 = require("@tiptap/pm/state");
2867
1670
  var React10 = __toESM(require("react"));
2868
1671
  var BLOCKQUOTE_SHORTCUT_KEY = "mod+shift+b";
2869
1672
  function canToggleBlockquote(editor, turnInto = true) {
2870
1673
  var _a;
2871
1674
  if (!editor || !editor.isEditable) return false;
2872
- if (!isNodeInSchema("blockquote", editor) || isNodeTypeSelected(editor, ["image"]))
1675
+ if (!(0, import_editor_utils5.isNodeInSchema)("blockquote", editor) || (0, import_editor_utils5.isNodeTypeSelected)(editor, ["image"]))
2873
1676
  return false;
2874
1677
  if (!turnInto) {
2875
1678
  return editor.can().toggleWrap("blockquote");
@@ -2878,12 +1681,12 @@ function canToggleBlockquote(editor, turnInto = true) {
2878
1681
  const view = editor.view;
2879
1682
  const state = view.state;
2880
1683
  const selection = state.selection;
2881
- if (selection.empty || selection instanceof import_state8.TextSelection) {
2882
- const pos = (_a = findNodePosition({
1684
+ if (selection.empty || selection instanceof import_state6.TextSelection) {
1685
+ const pos = (_a = (0, import_editor_utils5.findNodePosition)({
2883
1686
  editor,
2884
1687
  node: state.selection.$anchor.node(1)
2885
1688
  })) == null ? void 0 : _a.pos;
2886
- if (!isValidPosition(pos)) return false;
1689
+ if (!(0, import_editor_utils5.isValidPosition)(pos)) return false;
2887
1690
  }
2888
1691
  return true;
2889
1692
  } catch {
@@ -2898,19 +1701,19 @@ function toggleBlockquote(editor) {
2898
1701
  const view = editor.view;
2899
1702
  let state = view.state;
2900
1703
  let tr = state.tr;
2901
- if (state.selection.empty || state.selection instanceof import_state8.TextSelection) {
2902
- const pos = (_a = findNodePosition({
1704
+ if (state.selection.empty || state.selection instanceof import_state6.TextSelection) {
1705
+ const pos = (_a = (0, import_editor_utils5.findNodePosition)({
2903
1706
  editor,
2904
1707
  node: state.selection.$anchor.node(1)
2905
1708
  })) == null ? void 0 : _a.pos;
2906
- if (!isValidPosition(pos)) return false;
2907
- tr = tr.setSelection(import_state8.NodeSelection.create(state.doc, pos));
1709
+ if (!(0, import_editor_utils5.isValidPosition)(pos)) return false;
1710
+ tr = tr.setSelection(import_state6.NodeSelection.create(state.doc, pos));
2908
1711
  view.dispatch(tr);
2909
1712
  state = view.state;
2910
1713
  }
2911
1714
  const selection = state.selection;
2912
1715
  let chain = editor.chain().focus();
2913
- if (selection instanceof import_state8.NodeSelection) {
1716
+ if (selection instanceof import_state6.NodeSelection) {
2914
1717
  const firstChild = (_b = selection.node.firstChild) == null ? void 0 : _b.firstChild;
2915
1718
  const lastChild = (_c = selection.node.lastChild) == null ? void 0 : _c.lastChild;
2916
1719
  const from = firstChild ? selection.from + firstChild.nodeSize : selection.from + 1;
@@ -2928,7 +1731,7 @@ function toggleBlockquote(editor) {
2928
1731
  function shouldShowButton2(props) {
2929
1732
  const { editor, hideWhenUnavailable } = props;
2930
1733
  if (!editor || !editor.isEditable) return false;
2931
- if (!isNodeInSchema("blockquote", editor)) return false;
1734
+ if (!(0, import_editor_utils5.isNodeInSchema)("blockquote", editor)) return false;
2932
1735
  if (hideWhenUnavailable && !editor.isActive("code")) {
2933
1736
  return canToggleBlockquote(editor);
2934
1737
  }
@@ -2970,7 +1773,7 @@ function useBlockquote(config) {
2970
1773
  canToggle: canToggle3,
2971
1774
  label: "Blockquote",
2972
1775
  shortcutKeys: BLOCKQUOTE_SHORTCUT_KEY,
2973
- Icon: import_icons4.BlockquoteIcon
1776
+ Icon: import_icons3.BlockquoteIcon
2974
1777
  };
2975
1778
  }
2976
1779
 
@@ -3037,19 +1840,20 @@ var BlockquoteButton = ({
3037
1840
  };
3038
1841
 
3039
1842
  // src/ui/codeblock-button/code-block-button.tsx
3040
- var import_icons6 = require("@kopexa/icons");
1843
+ var import_icons5 = require("@kopexa/icons");
3041
1844
  var import_toolbar2 = require("@kopexa/toolbar");
3042
- var import_react14 = require("react");
1845
+ var import_react13 = require("react");
3043
1846
 
3044
1847
  // src/ui/codeblock-button/use-code-block.ts
3045
- var import_icons5 = require("@kopexa/icons");
3046
- var import_state9 = require("@tiptap/pm/state");
1848
+ var import_editor_utils6 = require("@kopexa/editor-utils");
1849
+ var import_icons4 = require("@kopexa/icons");
1850
+ var import_state7 = require("@tiptap/pm/state");
3047
1851
  var React12 = __toESM(require("react"));
3048
1852
  var CODE_BLOCK_SHORTCUT_KEY = "mod+alt+c";
3049
1853
  function canToggle2(editor, turnInto = true) {
3050
1854
  var _a;
3051
1855
  if (!editor || !editor.isEditable) return false;
3052
- if (!isNodeInSchema("codeBlock", editor) || isNodeTypeSelected(editor, ["image"]))
1856
+ if (!(0, import_editor_utils6.isNodeInSchema)("codeBlock", editor) || (0, import_editor_utils6.isNodeTypeSelected)(editor, ["image"]))
3053
1857
  return false;
3054
1858
  if (!turnInto) {
3055
1859
  return editor.can().toggleNode("codeBlock", "paragraph");
@@ -3058,12 +1862,12 @@ function canToggle2(editor, turnInto = true) {
3058
1862
  const view = editor.view;
3059
1863
  const state = view.state;
3060
1864
  const selection = state.selection;
3061
- if (selection.empty || selection instanceof import_state9.TextSelection) {
3062
- const pos = (_a = findNodePosition({
1865
+ if (selection.empty || selection instanceof import_state7.TextSelection) {
1866
+ const pos = (_a = (0, import_editor_utils6.findNodePosition)({
3063
1867
  editor,
3064
1868
  node: state.selection.$anchor.node(1)
3065
1869
  })) == null ? void 0 : _a.pos;
3066
- if (!isValidPosition(pos)) return false;
1870
+ if (!(0, import_editor_utils6.isValidPosition)(pos)) return false;
3067
1871
  }
3068
1872
  return true;
3069
1873
  } catch {
@@ -3078,19 +1882,19 @@ function toggleCodeBlock(editor) {
3078
1882
  const view = editor.view;
3079
1883
  let state = view.state;
3080
1884
  let tr = state.tr;
3081
- if (state.selection.empty || state.selection instanceof import_state9.TextSelection) {
3082
- const pos = (_a = findNodePosition({
1885
+ if (state.selection.empty || state.selection instanceof import_state7.TextSelection) {
1886
+ const pos = (_a = (0, import_editor_utils6.findNodePosition)({
3083
1887
  editor,
3084
1888
  node: state.selection.$anchor.node(1)
3085
1889
  })) == null ? void 0 : _a.pos;
3086
- if (!isValidPosition(pos)) return false;
3087
- tr = tr.setSelection(import_state9.NodeSelection.create(state.doc, pos));
1890
+ if (!(0, import_editor_utils6.isValidPosition)(pos)) return false;
1891
+ tr = tr.setSelection(import_state7.NodeSelection.create(state.doc, pos));
3088
1892
  view.dispatch(tr);
3089
1893
  state = view.state;
3090
1894
  }
3091
1895
  const selection = state.selection;
3092
1896
  let chain = editor.chain().focus();
3093
- if (selection instanceof import_state9.NodeSelection) {
1897
+ if (selection instanceof import_state7.NodeSelection) {
3094
1898
  const firstChild = (_b = selection.node.firstChild) == null ? void 0 : _b.firstChild;
3095
1899
  const lastChild = (_c = selection.node.lastChild) == null ? void 0 : _c.lastChild;
3096
1900
  const from = firstChild ? selection.from + firstChild.nodeSize : selection.from + 1;
@@ -3108,7 +1912,7 @@ function toggleCodeBlock(editor) {
3108
1912
  function shouldShowButton3(props) {
3109
1913
  const { editor, hideWhenUnavailable } = props;
3110
1914
  if (!editor || !editor.isEditable) return false;
3111
- if (!isNodeInSchema("codeBlock", editor)) return false;
1915
+ if (!(0, import_editor_utils6.isNodeInSchema)("codeBlock", editor)) return false;
3112
1916
  if (hideWhenUnavailable && !editor.isActive("code")) {
3113
1917
  return canToggle2(editor);
3114
1918
  }
@@ -3150,7 +1954,7 @@ function useCodeBlock(config) {
3150
1954
  canToggle: canToggleState,
3151
1955
  label: "Code Block",
3152
1956
  shortcutKeys: CODE_BLOCK_SHORTCUT_KEY,
3153
- Icon: import_icons5.CodeblockIcon
1957
+ Icon: import_icons4.CodeblockIcon
3154
1958
  };
3155
1959
  }
3156
1960
 
@@ -3167,20 +1971,12 @@ var CodeBlockButton = ({
3167
1971
  ...buttonProps
3168
1972
  }) => {
3169
1973
  const { editor } = useTiptapEditor(providedEditor);
3170
- const {
3171
- isVisible,
3172
- canToggle: canToggle3,
3173
- isActive,
3174
- handleToggle,
3175
- label,
3176
- shortcutKeys,
3177
- Icon
3178
- } = useCodeBlock({
1974
+ const { isVisible, canToggle: canToggle3, isActive, handleToggle, label, shortcutKeys } = useCodeBlock({
3179
1975
  editor,
3180
1976
  hideWhenUnavailable,
3181
1977
  onToggled
3182
1978
  });
3183
- const handleClick = (0, import_react14.useCallback)(
1979
+ const handleClick = (0, import_react13.useCallback)(
3184
1980
  (event) => {
3185
1981
  onClick == null ? void 0 : onClick(event);
3186
1982
  if (event.defaultPrevented) return;
@@ -3208,25 +2004,26 @@ var CodeBlockButton = ({
3208
2004
  onClick: handleClick,
3209
2005
  isIconOnly: true,
3210
2006
  ...buttonProps,
3211
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons6.CodeblockIcon, {})
2007
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons5.CodeblockIcon, {})
3212
2008
  }
3213
2009
  );
3214
2010
  };
3215
2011
 
3216
2012
  // src/ui/color-highlight-popover/color-highlight-popover.tsx
3217
2013
  var import_button2 = require("@kopexa/button");
3218
- var import_icons8 = require("@kopexa/icons");
2014
+ var import_icons7 = require("@kopexa/icons");
3219
2015
  var import_popover = require("@kopexa/popover");
3220
2016
  var import_toolbar4 = require("@kopexa/toolbar");
3221
- var import_react16 = require("react");
2017
+ var import_react15 = require("react");
3222
2018
 
3223
2019
  // src/ui/color-highlight-button/color-highlight-button.tsx
3224
2020
  var import_theme2 = require("@kopexa/theme");
3225
2021
  var import_toolbar3 = require("@kopexa/toolbar");
3226
- var import_react15 = require("react");
2022
+ var import_react14 = require("react");
3227
2023
 
3228
2024
  // src/ui/color-highlight-button/use-color-highlight.ts
3229
- var import_icons7 = require("@kopexa/icons");
2025
+ var import_editor_utils7 = require("@kopexa/editor-utils");
2026
+ var import_icons6 = require("@kopexa/icons");
3230
2027
  var import_use_is_mobile = require("@kopexa/use-is-mobile");
3231
2028
  var React13 = __toESM(require("react"));
3232
2029
  var import_react_hotkeys_hook = require("react-hotkeys-hook");
@@ -3291,7 +2088,7 @@ function pickHighlightColorsByValue(values) {
3291
2088
  }
3292
2089
  function canColorHighlight(editor) {
3293
2090
  if (!editor || !editor.isEditable) return false;
3294
- if (!isMarkInSchema("highlight", editor) || isNodeTypeSelected(editor, ["image"]))
2091
+ if (!(0, import_editor_utils7.isMarkInSchema)("highlight", editor) || (0, import_editor_utils7.isNodeTypeSelected)(editor, ["image"]))
3295
2092
  return false;
3296
2093
  return editor.can().setMark("highlight");
3297
2094
  }
@@ -3307,7 +2104,7 @@ function removeHighlight(editor) {
3307
2104
  function shouldShowButton4(props) {
3308
2105
  const { editor, hideWhenUnavailable } = props;
3309
2106
  if (!editor || !editor.isEditable) return false;
3310
- if (!isMarkInSchema("highlight", editor)) return false;
2107
+ if (!(0, import_editor_utils7.isMarkInSchema)("highlight", editor)) return false;
3311
2108
  if (hideWhenUnavailable && !editor.isActive("code")) {
3312
2109
  return canColorHighlight(editor);
3313
2110
  }
@@ -3383,7 +2180,7 @@ function useColorHighlight(config) {
3383
2180
  canColorHighlight: canColorHighlightState,
3384
2181
  label: label || `Highlight`,
3385
2182
  shortcutKeys: COLOR_HIGHLIGHT_SHORTCUT_KEY,
3386
- Icon: import_icons7.HighlighterIcon
2183
+ Icon: import_icons6.HighlighterIcon
3387
2184
  };
3388
2185
  }
3389
2186
 
@@ -3417,7 +2214,7 @@ var ColorHighlightButton = ({
3417
2214
  hideWhenUnavailable,
3418
2215
  onApplied
3419
2216
  });
3420
- const handleClick = (0, import_react15.useCallback)(
2217
+ const handleClick = (0, import_react14.useCallback)(
3421
2218
  (event) => {
3422
2219
  onClick == null ? void 0 : onClick(event);
3423
2220
  if (event.defaultPrevented) return;
@@ -3425,7 +2222,7 @@ var ColorHighlightButton = ({
3425
2222
  },
3426
2223
  [handleColorHighlight, onClick]
3427
2224
  );
3428
- const buttonStyle = (0, import_react15.useMemo)(
2225
+ const buttonStyle = (0, import_react14.useMemo)(
3429
2226
  () => ({
3430
2227
  ...style,
3431
2228
  "--highlight-color": highlightColor
@@ -3494,7 +2291,7 @@ var ColorHighlightPopoverButton = ({
3494
2291
  tooltip: "Highlight",
3495
2292
  isIconOnly: !children,
3496
2293
  ...props,
3497
- children: children != null ? children : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_icons8.HighlighterIcon, {})
2294
+ children: children != null ? children : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_icons7.HighlighterIcon, {})
3498
2295
  }
3499
2296
  );
3500
2297
  function ColorHighlightPopoverContent({
@@ -3508,8 +2305,8 @@ function ColorHighlightPopoverContent({
3508
2305
  ])
3509
2306
  }) {
3510
2307
  const { handleRemoveHighlight } = useColorHighlight({ editor });
3511
- const containerRef = (0, import_react16.useRef)(null);
3512
- const menuItems = (0, import_react16.useMemo)(
2308
+ const containerRef = (0, import_react15.useRef)(null);
2309
+ const menuItems = (0, import_react15.useMemo)(
3513
2310
  () => [...colors, { label: "Remove highlight", value: "none" }],
3514
2311
  [colors]
3515
2312
  );
@@ -3558,7 +2355,7 @@ function ColorHighlightPopoverContent({
3558
2355
  variant: "ghost",
3559
2356
  color: "default",
3560
2357
  "data-highlighted": selectedIndex === colors.length,
3561
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_icons8.BanIcon, {})
2358
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_icons7.BanIcon, {})
3562
2359
  }
3563
2360
  ) })
3564
2361
  ] });
@@ -3577,8 +2374,8 @@ function ColorHighlightPopover({
3577
2374
  ...props
3578
2375
  }) {
3579
2376
  const { editor } = useTiptapEditor(providedEditor);
3580
- const [isOpen, setIsOpen] = (0, import_react16.useState)(false);
3581
- const { isVisible, canColorHighlight: canColorHighlight2, isActive, label, Icon } = useColorHighlight({
2377
+ const [isOpen, setIsOpen] = (0, import_react15.useState)(false);
2378
+ const { isVisible, canColorHighlight: canColorHighlight2, isActive, label } = useColorHighlight({
3582
2379
  editor,
3583
2380
  hideWhenUnavailable,
3584
2381
  onApplied
@@ -3609,17 +2406,19 @@ function ColorHighlightPopover({
3609
2406
  // src/ui/heading-dropdown-menu/index.tsx
3610
2407
  var import_button4 = require("@kopexa/button");
3611
2408
  var import_dropdown_menu = require("@kopexa/dropdown-menu");
3612
- var import_icons10 = require("@kopexa/icons");
3613
- var import_react18 = require("@tiptap/react");
2409
+ var import_editor_utils9 = require("@kopexa/editor-utils");
2410
+ var import_icons9 = require("@kopexa/icons");
2411
+ var import_react17 = require("@tiptap/react");
3614
2412
  var React15 = __toESM(require("react"));
3615
2413
 
3616
2414
  // src/ui/heading-button/index.tsx
3617
2415
  var import_button3 = require("@kopexa/button");
3618
- var import_icons9 = require("@kopexa/icons");
2416
+ var import_editor_utils8 = require("@kopexa/editor-utils");
2417
+ var import_icons8 = require("@kopexa/icons");
3619
2418
  var React14 = __toESM(require("react"));
3620
2419
 
3621
2420
  // src/ui/heading-button/utils.ts
3622
- var import_react17 = require("@tiptap/react");
2421
+ var import_react16 = require("@tiptap/react");
3623
2422
  var headingShortcutKeys = {
3624
2423
  1: "Ctrl-Alt-1",
3625
2424
  2: "Ctrl-Alt-2",
@@ -3660,7 +2459,7 @@ function shouldShowHeadingButton(params) {
3660
2459
  return false;
3661
2460
  }
3662
2461
  if (hideWhenUnavailable) {
3663
- if ((0, import_react17.isNodeSelection)(editor.state.selection)) {
2462
+ if ((0, import_react16.isNodeSelection)(editor.state.selection)) {
3664
2463
  return false;
3665
2464
  }
3666
2465
  }
@@ -3673,15 +2472,15 @@ function getFormattedHeadingName(level) {
3673
2472
  // src/ui/heading-button/index.tsx
3674
2473
  var import_jsx_runtime7 = require("react/jsx-runtime");
3675
2474
  var headingIcons = {
3676
- 1: import_icons9.HeadingOneIcon,
3677
- 2: import_icons9.HeadingTwoIcon,
3678
- 3: import_icons9.HeadingThreeIcon,
3679
- 4: import_icons9.HeadingFourIcon,
3680
- 5: import_icons9.HeadingFiveIcon,
3681
- 6: import_icons9.HeadingSixIcon
2475
+ 1: import_icons8.HeadingOneIcon,
2476
+ 2: import_icons8.HeadingTwoIcon,
2477
+ 3: import_icons8.HeadingThreeIcon,
2478
+ 4: import_icons8.HeadingFourIcon,
2479
+ 5: import_icons8.HeadingFiveIcon,
2480
+ 6: import_icons8.HeadingSixIcon
3682
2481
  };
3683
2482
  function useHeadingState(editor, level, disabled = false) {
3684
- const headingInSchema = isNodeInSchema("heading", editor);
2483
+ const headingInSchema = (0, import_editor_utils8.isNodeInSchema)("heading", editor);
3685
2484
  const isDisabled = isHeadingButtonDisabled(editor, level, disabled);
3686
2485
  const isActive = isHeadingActive(editor, level);
3687
2486
  const Icon = headingIcons[level];
@@ -3773,7 +2572,7 @@ function HeadingDropdownMenu({
3773
2572
  var _a;
3774
2573
  const [isOpen, setIsOpen] = React15.useState(false);
3775
2574
  const { editor } = useTiptapEditor(providedEditor);
3776
- const headingInSchema = isNodeInSchema("heading", editor);
2575
+ const headingInSchema = (0, import_editor_utils9.isNodeInSchema)("heading", editor);
3777
2576
  const handleOnOpenChange = React15.useCallback(
3778
2577
  (open) => {
3779
2578
  setIsOpen(open);
@@ -3782,11 +2581,11 @@ function HeadingDropdownMenu({
3782
2581
  [onOpenChange]
3783
2582
  );
3784
2583
  const getActiveIcon = React15.useCallback(() => {
3785
- if (!editor) return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_icons10.HeadingIcon, {});
2584
+ if (!editor) return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_icons9.HeadingIcon, {});
3786
2585
  const activeLevel = levels.find(
3787
2586
  (level) => editor.isActive("heading", { level })
3788
2587
  );
3789
- if (!activeLevel) return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_icons10.HeadingIcon, {});
2588
+ if (!activeLevel) return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_icons9.HeadingIcon, {});
3790
2589
  const ActiveIcon = headingIcons[activeLevel];
3791
2590
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ActiveIcon, {});
3792
2591
  }, [editor, levels]);
@@ -3803,7 +2602,7 @@ function HeadingDropdownMenu({
3803
2602
  return false;
3804
2603
  }
3805
2604
  if (hideWhenUnavailable) {
3806
- if ((0, import_react18.isNodeSelection)(editor.state.selection) || !canToggleAnyHeading()) {
2605
+ if ((0, import_react17.isNodeSelection)(editor.state.selection) || !canToggleAnyHeading()) {
3807
2606
  return false;
3808
2607
  }
3809
2608
  }
@@ -3826,7 +2625,7 @@ function HeadingDropdownMenu({
3826
2625
  "aria-label": "Format text as heading",
3827
2626
  "aria-pressed": isAnyHeadingActive,
3828
2627
  tooltip: "Heading",
3829
- endContent: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_icons10.ChevronDownIcon, {}),
2628
+ endContent: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_icons9.ChevronDownIcon, {}),
3830
2629
  ...props,
3831
2630
  children: getActiveIcon()
3832
2631
  }
@@ -3847,16 +2646,111 @@ function HeadingDropdownMenu({
3847
2646
 
3848
2647
  // src/ui/link-popover/link-popover.tsx
3849
2648
  var import_button5 = require("@kopexa/button");
3850
- var import_icons12 = require("@kopexa/icons");
2649
+ var import_icons11 = require("@kopexa/icons");
3851
2650
  var import_input = require("@kopexa/input");
3852
2651
  var import_popover2 = require("@kopexa/popover");
3853
2652
  var import_separator2 = require("@kopexa/separator");
3854
2653
  var import_toolbar5 = require("@kopexa/toolbar");
3855
- var import_react19 = require("react");
2654
+ var import_react18 = require("react");
3856
2655
 
3857
2656
  // src/ui/link-popover/use-link-popover.ts
3858
- var import_icons11 = require("@kopexa/icons");
2657
+ var import_editor_utils10 = require("@kopexa/editor-utils");
2658
+ var import_icons10 = require("@kopexa/icons");
3859
2659
  var React16 = __toESM(require("react"));
2660
+
2661
+ // src/utils/index.ts
2662
+ var MAX_FILE_SIZE = 5 * 1024 * 1024;
2663
+ var handleImageUpload = async (file, onProgress, abortSignal) => {
2664
+ if (!file) {
2665
+ throw new Error("No file provided");
2666
+ }
2667
+ if (file.size > MAX_FILE_SIZE) {
2668
+ throw new Error(
2669
+ `File size exceeds maximum allowed (${MAX_FILE_SIZE / (1024 * 1024)}MB)`
2670
+ );
2671
+ }
2672
+ for (let progress = 0; progress <= 100; progress += 10) {
2673
+ if (abortSignal == null ? void 0 : abortSignal.aborted) {
2674
+ throw new Error("Upload cancelled");
2675
+ }
2676
+ await new Promise((resolve) => setTimeout(resolve, 500));
2677
+ onProgress == null ? void 0 : onProgress({ progress });
2678
+ }
2679
+ return "/images/placeholder-image.png";
2680
+ };
2681
+ var convertFileToBase64 = (file, abortSignal) => {
2682
+ if (!file) {
2683
+ return Promise.reject(new Error("No file provided"));
2684
+ }
2685
+ return new Promise((resolve, reject) => {
2686
+ const reader = new FileReader();
2687
+ const abortHandler = () => {
2688
+ reader.abort();
2689
+ reject(new Error("Upload cancelled"));
2690
+ };
2691
+ if (abortSignal) {
2692
+ abortSignal.addEventListener("abort", abortHandler);
2693
+ }
2694
+ reader.onloadend = () => {
2695
+ if (abortSignal) {
2696
+ abortSignal.removeEventListener("abort", abortHandler);
2697
+ }
2698
+ if (typeof reader.result === "string") {
2699
+ resolve(reader.result);
2700
+ } else {
2701
+ reject(new Error("Failed to convert File to base64"));
2702
+ }
2703
+ };
2704
+ reader.onerror = (error) => reject(new Error(`File reading error: ${error}`));
2705
+ reader.readAsDataURL(file);
2706
+ });
2707
+ };
2708
+ var ATTR_WHITESPACE = (
2709
+ // eslint-disable-next-line no-control-regex
2710
+ // biome-ignore lint/suspicious/noControlCharactersInRegex: we can do this yay
2711
+ /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g
2712
+ );
2713
+ function isAllowedUri(uri, protocols) {
2714
+ const allowedProtocols = [
2715
+ "http",
2716
+ "https",
2717
+ "ftp",
2718
+ "ftps",
2719
+ "mailto",
2720
+ "tel",
2721
+ "callto",
2722
+ "sms",
2723
+ "cid",
2724
+ "xmpp"
2725
+ ];
2726
+ if (protocols) {
2727
+ for (const protocol of protocols) {
2728
+ const nextProtocol = typeof protocol === "string" ? protocol : protocol.scheme;
2729
+ if (nextProtocol) {
2730
+ allowedProtocols.push(nextProtocol);
2731
+ }
2732
+ }
2733
+ }
2734
+ return !uri || uri.replace(ATTR_WHITESPACE, "").match(
2735
+ new RegExp(
2736
+ // eslint-disable-next-line no-useless-escape
2737
+ `^(?:(?:${allowedProtocols.join("|")}):|[^a-z]|[a-z0-9+.-]+(?:[^a-z+.-:]|$))`,
2738
+ "i"
2739
+ )
2740
+ );
2741
+ }
2742
+ function sanitizeUrl(inputUrl, baseUrl, protocols) {
2743
+ try {
2744
+ const url = new URL(inputUrl, baseUrl);
2745
+ if (isAllowedUri(url.href, protocols)) {
2746
+ return url.href;
2747
+ }
2748
+ } catch {
2749
+ }
2750
+ return "#";
2751
+ }
2752
+
2753
+ // src/ui/link-popover/use-link-popover.ts
3860
2754
  function canSetLink(editor) {
3861
2755
  if (!editor || !editor.isEditable) return false;
3862
2756
  return editor.can().setMark("link");
@@ -3867,7 +2761,7 @@ function isLinkActive(editor) {
3867
2761
  }
3868
2762
  function shouldShowLinkButton(props) {
3869
2763
  const { editor, hideWhenUnavailable } = props;
3870
- const linkInSchema = isMarkInSchema("link", editor);
2764
+ const linkInSchema = (0, import_editor_utils10.isMarkInSchema)("link", editor);
3871
2765
  if (!linkInSchema || !editor) {
3872
2766
  return false;
3873
2767
  }
@@ -3980,7 +2874,7 @@ function useLinkPopover(config) {
3980
2874
  canSet,
3981
2875
  isActive,
3982
2876
  label: "Link",
3983
- Icon: import_icons11.LinkIcon,
2877
+ Icon: import_icons10.LinkIcon,
3984
2878
  ...linkHandler
3985
2879
  };
3986
2880
  }
@@ -4000,7 +2894,7 @@ var LinkButton = ({ className, children, ...props }) => {
4000
2894
  title: "Link",
4001
2895
  isIconOnly: !children,
4002
2896
  ...props,
4003
- children: children || /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_icons12.LinkIcon, {})
2897
+ children: children || /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_icons11.LinkIcon, {})
4004
2898
  }
4005
2899
  );
4006
2900
  };
@@ -4043,7 +2937,7 @@ var LinkMain = ({
4043
2937
  disabled: !url && !isActive,
4044
2938
  variant: "ghost",
4045
2939
  color: "default",
4046
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_icons12.CornerDownLeftIcon, {})
2940
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_icons11.CornerDownLeftIcon, {})
4047
2941
  }
4048
2942
  )
4049
2943
  ] }),
@@ -4058,7 +2952,7 @@ var LinkMain = ({
4058
2952
  disabled: !url && !isActive,
4059
2953
  variant: "ghost",
4060
2954
  color: "default",
4061
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_icons12.ExternalLinkIcon, {})
2955
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_icons11.ExternalLinkIcon, {})
4062
2956
  }
4063
2957
  ),
4064
2958
  /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
@@ -4070,7 +2964,7 @@ var LinkMain = ({
4070
2964
  disabled: !url && !isActive,
4071
2965
  variant: "ghost",
4072
2966
  color: "default",
4073
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_icons12.TrashIcon, {})
2967
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_icons11.TrashIcon, {})
4074
2968
  }
4075
2969
  )
4076
2970
  ] })
@@ -4087,7 +2981,7 @@ function LinkPopover({
4087
2981
  ...buttonProps
4088
2982
  }) {
4089
2983
  const { editor } = useTiptapEditor(providedEditor);
4090
- const [isOpen, setIsOpen] = (0, import_react19.useState)(false);
2984
+ const [isOpen, setIsOpen] = (0, import_react18.useState)(false);
4091
2985
  const {
4092
2986
  isVisible,
4093
2987
  canSet,
@@ -4103,18 +2997,18 @@ function LinkPopover({
4103
2997
  hideWhenUnavailable,
4104
2998
  onSetLink
4105
2999
  });
4106
- const handleOnOpenChange = (0, import_react19.useCallback)(
3000
+ const handleOnOpenChange = (0, import_react18.useCallback)(
4107
3001
  (nextIsOpen) => {
4108
3002
  setIsOpen(nextIsOpen);
4109
3003
  onOpenChange == null ? void 0 : onOpenChange(nextIsOpen);
4110
3004
  },
4111
3005
  [onOpenChange]
4112
3006
  );
4113
- const handleSetLink = (0, import_react19.useCallback)(() => {
3007
+ const handleSetLink = (0, import_react18.useCallback)(() => {
4114
3008
  setLink();
4115
3009
  setIsOpen(false);
4116
3010
  }, [setLink]);
4117
- const handleClick = (0, import_react19.useCallback)(
3011
+ const handleClick = (0, import_react18.useCallback)(
4118
3012
  (event) => {
4119
3013
  onClick == null ? void 0 : onClick(event);
4120
3014
  if (event.defaultPrevented) return;
@@ -4122,7 +3016,7 @@ function LinkPopover({
4122
3016
  },
4123
3017
  [onClick, isOpen]
4124
3018
  );
4125
- (0, import_react19.useEffect)(() => {
3019
+ (0, import_react18.useEffect)(() => {
4126
3020
  if (autoOpenOnLinkActive && isActive) {
4127
3021
  setIsOpen(true);
4128
3022
  }
@@ -4174,31 +3068,33 @@ LinkButton.displayName = "LinkButton";
4174
3068
  // src/ui/list-dropdown-menu/index.tsx
4175
3069
  var import_button7 = require("@kopexa/button");
4176
3070
  var import_dropdown_menu2 = require("@kopexa/dropdown-menu");
4177
- var import_icons14 = require("@kopexa/icons");
4178
- var import_react22 = require("@tiptap/react");
4179
- var import_react23 = require("react");
3071
+ var import_editor_utils12 = require("@kopexa/editor-utils");
3072
+ var import_icons13 = require("@kopexa/icons");
3073
+ var import_react21 = require("@tiptap/react");
3074
+ var import_react22 = require("react");
4180
3075
 
4181
3076
  // src/ui/list-button/index.tsx
4182
3077
  var import_button6 = require("@kopexa/button");
4183
- var import_icons13 = require("@kopexa/icons");
4184
- var import_react20 = require("@tiptap/react");
4185
- var import_react21 = require("react");
3078
+ var import_editor_utils11 = require("@kopexa/editor-utils");
3079
+ var import_icons12 = require("@kopexa/icons");
3080
+ var import_react19 = require("@tiptap/react");
3081
+ var import_react20 = require("react");
4186
3082
  var import_jsx_runtime10 = require("react/jsx-runtime");
4187
3083
  var listOptions = [
4188
3084
  {
4189
3085
  label: "Bullet List",
4190
3086
  type: "bulletList",
4191
- icon: import_icons13.ListIcon
3087
+ icon: import_icons12.ListIcon
4192
3088
  },
4193
3089
  {
4194
3090
  label: "Ordered List",
4195
3091
  type: "orderedList",
4196
- icon: import_icons13.ListOrderedIcon
3092
+ icon: import_icons12.ListOrderedIcon
4197
3093
  },
4198
3094
  {
4199
3095
  label: "Task List",
4200
3096
  type: "taskList",
4201
- icon: import_icons13.ListTodoIcon
3097
+ icon: import_icons12.ListTodoIcon
4202
3098
  }
4203
3099
  ];
4204
3100
  var listShortcutKeys = {
@@ -4257,14 +3153,14 @@ function shouldShowListButton(params) {
4257
3153
  return false;
4258
3154
  }
4259
3155
  if (hideWhenUnavailable) {
4260
- if ((0, import_react20.isNodeSelection)(editor.state.selection) || !canToggleList(editor, type)) {
3156
+ if ((0, import_react19.isNodeSelection)(editor.state.selection) || !canToggleList(editor, type)) {
4261
3157
  return false;
4262
3158
  }
4263
3159
  }
4264
3160
  return true;
4265
3161
  }
4266
3162
  function useListState(editor, type) {
4267
- const listInSchema = isNodeInSchema(type, editor);
3163
+ const listInSchema = (0, import_editor_utils11.isNodeInSchema)(type, editor);
4268
3164
  const listOption = getListOption(type);
4269
3165
  const isActive = isListActive(editor, type);
4270
3166
  const shortcutKey = listShortcutKeys[type];
@@ -4291,8 +3187,8 @@ var ListButton = ({
4291
3187
  editor,
4292
3188
  type
4293
3189
  );
4294
- const Icon = (listOption == null ? void 0 : listOption.icon) || import_icons13.ListIcon;
4295
- const handleClick = (0, import_react21.useCallback)(
3190
+ const Icon = (listOption == null ? void 0 : listOption.icon) || import_icons12.ListIcon;
3191
+ const handleClick = (0, import_react20.useCallback)(
4296
3192
  (e) => {
4297
3193
  onClick == null ? void 0 : onClick(e);
4298
3194
  if (!e.defaultPrevented && editor) {
@@ -4301,7 +3197,7 @@ var ListButton = ({
4301
3197
  },
4302
3198
  [onClick, editor, type]
4303
3199
  );
4304
- const show = (0, import_react21.useMemo)(() => {
3200
+ const show = (0, import_react20.useMemo)(() => {
4305
3201
  return shouldShowListButton({
4306
3202
  editor,
4307
3203
  type,
@@ -4355,24 +3251,24 @@ function shouldShowListDropdown(params) {
4355
3251
  return false;
4356
3252
  }
4357
3253
  if (hideWhenUnavailable) {
4358
- if ((0, import_react22.isNodeSelection)(editor.state.selection) || !canToggleAny) {
3254
+ if ((0, import_react21.isNodeSelection)(editor.state.selection) || !canToggleAny) {
4359
3255
  return false;
4360
3256
  }
4361
3257
  }
4362
3258
  return true;
4363
3259
  }
4364
3260
  function useListDropdownState(editor, availableTypes) {
4365
- const [isOpen, setIsOpen] = (0, import_react23.useState)(false);
3261
+ const [isOpen, setIsOpen] = (0, import_react22.useState)(false);
4366
3262
  const listInSchema = availableTypes.some(
4367
- (type) => isNodeInSchema(type, editor)
3263
+ (type) => (0, import_editor_utils12.isNodeInSchema)(type, editor)
4368
3264
  );
4369
- const filteredLists = (0, import_react23.useMemo)(
3265
+ const filteredLists = (0, import_react22.useMemo)(
4370
3266
  () => getFilteredListOptions(availableTypes),
4371
3267
  [availableTypes]
4372
3268
  );
4373
3269
  const canToggleAny = canToggleAnyList(editor, availableTypes);
4374
3270
  const isAnyActive = isAnyListActive(editor, availableTypes);
4375
- const handleOpenChange = (0, import_react23.useCallback)(
3271
+ const handleOpenChange = (0, import_react22.useCallback)(
4376
3272
  (open, callback) => {
4377
3273
  setIsOpen(open);
4378
3274
  callback == null ? void 0 : callback(open);
@@ -4390,11 +3286,11 @@ function useListDropdownState(editor, availableTypes) {
4390
3286
  };
4391
3287
  }
4392
3288
  function useActiveListIcon(editor, filteredLists) {
4393
- return (0, import_react23.useCallback)(() => {
3289
+ return (0, import_react22.useCallback)(() => {
4394
3290
  const activeOption = filteredLists.find(
4395
3291
  (option) => isListActive(editor, option.type)
4396
3292
  );
4397
- return activeOption ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(activeOption.icon, {}) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_icons14.ListIcon, {});
3293
+ return activeOption ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(activeOption.icon, {}) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_icons13.ListIcon, {});
4398
3294
  }, [editor, filteredLists]);
4399
3295
  }
4400
3296
  function ListDropdownMenu({
@@ -4414,7 +3310,7 @@ function ListDropdownMenu({
4414
3310
  handleOpenChange
4415
3311
  } = useListDropdownState(editor, types);
4416
3312
  const getActiveIcon = useActiveListIcon(editor, filteredLists);
4417
- const show = (0, import_react23.useMemo)(() => {
3313
+ const show = (0, import_react22.useMemo)(() => {
4418
3314
  return shouldShowListDropdown({
4419
3315
  editor,
4420
3316
  listTypes: types,
@@ -4423,7 +3319,7 @@ function ListDropdownMenu({
4423
3319
  canToggleAny
4424
3320
  });
4425
3321
  }, [editor, types, hideWhenUnavailable, listInSchema, canToggleAny]);
4426
- const handleOnOpenChange = (0, import_react23.useCallback)(
3322
+ const handleOnOpenChange = (0, import_react22.useCallback)(
4427
3323
  (open) => handleOpenChange(open, onOpenChange),
4428
3324
  [handleOpenChange, onOpenChange]
4429
3325
  );
@@ -4441,7 +3337,7 @@ function ListDropdownMenu({
4441
3337
  tabIndex: -1,
4442
3338
  "aria-label": "List options",
4443
3339
  tooltip: "List",
4444
- endContent: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_icons14.ChevronDownIcon, {}),
3340
+ endContent: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_icons13.ChevronDownIcon, {}),
4445
3341
  ...props,
4446
3342
  children: getActiveIcon()
4447
3343
  }
@@ -4462,19 +3358,20 @@ function ListDropdownMenu({
4462
3358
  }
4463
3359
 
4464
3360
  // src/ui/mark-button/index.tsx
4465
- var import_icons15 = require("@kopexa/icons");
3361
+ var import_editor_utils13 = require("@kopexa/editor-utils");
3362
+ var import_icons14 = require("@kopexa/icons");
4466
3363
  var import_toolbar6 = require("@kopexa/toolbar");
4467
- var import_react24 = require("@tiptap/react");
4468
- var import_react25 = require("react");
3364
+ var import_react23 = require("@tiptap/react");
3365
+ var import_react24 = require("react");
4469
3366
  var import_jsx_runtime12 = require("react/jsx-runtime");
4470
3367
  var markIcons = {
4471
- bold: import_icons15.BoldIcon,
4472
- italic: import_icons15.ItalicIcon,
4473
- underline: import_icons15.UnderlineIcon,
4474
- strike: import_icons15.StrikeIcon,
4475
- code: import_icons15.CodeIcon,
4476
- superscript: import_icons15.SuperscriptIcon,
4477
- subscript: import_icons15.SubscriptIcon
3368
+ bold: import_icons14.BoldIcon,
3369
+ italic: import_icons14.ItalicIcon,
3370
+ underline: import_icons14.UnderlineIcon,
3371
+ strike: import_icons14.StrikeIcon,
3372
+ code: import_icons14.CodeIcon,
3373
+ superscript: import_icons14.SuperscriptIcon,
3374
+ subscript: import_icons14.SubscriptIcon
4478
3375
  };
4479
3376
  var markShortcutKeys = {
4480
3377
  bold: "mod+b",
@@ -4487,7 +3384,7 @@ var markShortcutKeys = {
4487
3384
  };
4488
3385
  function canToggleMark(editor, type) {
4489
3386
  if (!editor || !editor.isEditable) return false;
4490
- if (!isMarkInSchema(type, editor) || isNodeTypeSelected(editor, ["image"]))
3387
+ if (!(0, import_editor_utils13.isMarkInSchema)(type, editor) || (0, import_editor_utils13.isNodeTypeSelected)(editor, ["image"]))
4491
3388
  return false;
4492
3389
  return editor.can().toggleMark(type);
4493
3390
  }
@@ -4512,7 +3409,7 @@ function shouldShowMarkButton(params) {
4512
3409
  return false;
4513
3410
  }
4514
3411
  if (hideWhenUnavailable) {
4515
- if ((0, import_react24.isNodeSelection)(editor.state.selection) || !canToggleMark(editor, type)) {
3412
+ if ((0, import_react23.isNodeSelection)(editor.state.selection) || !canToggleMark(editor, type)) {
4516
3413
  return false;
4517
3414
  }
4518
3415
  }
@@ -4522,7 +3419,7 @@ function getFormattedMarkName(type) {
4522
3419
  return type.charAt(0).toUpperCase() + type.slice(1);
4523
3420
  }
4524
3421
  function useMarkState(editor, type, disabled = false) {
4525
- const markInSchema = isMarkInSchema(type, editor);
3422
+ const markInSchema = (0, import_editor_utils13.isMarkInSchema)(type, editor);
4526
3423
  const isDisabled = isMarkButtonDisabled(editor, type, disabled);
4527
3424
  const isActive = isMarkActive(editor, type);
4528
3425
  const Icon = markIcons[type];
@@ -4557,7 +3454,7 @@ var MarkButton = ({
4557
3454
  shortcutKey,
4558
3455
  formattedName
4559
3456
  } = useMarkState(editor, type, disabled);
4560
- const handleClick = (0, import_react25.useCallback)(
3457
+ const handleClick = (0, import_react24.useCallback)(
4561
3458
  (e) => {
4562
3459
  onClick == null ? void 0 : onClick(e);
4563
3460
  if (!e.defaultPrevented && !isDisabled && editor) {
@@ -4566,7 +3463,7 @@ var MarkButton = ({
4566
3463
  },
4567
3464
  [onClick, isDisabled, editor, type]
4568
3465
  );
4569
- const show = (0, import_react25.useMemo)(() => {
3466
+ const show = (0, import_react24.useMemo)(() => {
4570
3467
  return shouldShowMarkButton({
4571
3468
  editor,
4572
3469
  type,
@@ -4602,7 +3499,7 @@ var MarkButton = ({
4602
3499
 
4603
3500
  // src/ui/table-button/index.tsx
4604
3501
  var import_toolbar7 = require("@kopexa/toolbar");
4605
- var import_react26 = require("react");
3502
+ var import_react25 = require("react");
4606
3503
  var import_jsx_runtime13 = require("react/jsx-runtime");
4607
3504
  var TableButton = ({
4608
3505
  editor: providedEditor,
@@ -4627,7 +3524,7 @@ var TableButton = ({
4627
3524
  hideWhenUnavailable,
4628
3525
  onToggled
4629
3526
  });
4630
- const handleClick = (0, import_react26.useCallback)(
3527
+ const handleClick = (0, import_react25.useCallback)(
4631
3528
  (event) => {
4632
3529
  onClick == null ? void 0 : onClick(event);
4633
3530
  if (event.defaultPrevented) return;
@@ -4650,7 +3547,7 @@ var TableButton = ({
4650
3547
  tabIndex: -1,
4651
3548
  "aria-label": label,
4652
3549
  "aria-pressed": isActive,
4653
- tooltip: label,
3550
+ title: label,
4654
3551
  onClick: handleClick,
4655
3552
  isIconOnly: !text && !children,
4656
3553
  ...buttonProps,
@@ -4664,11 +3561,12 @@ var TableButton = ({
4664
3561
 
4665
3562
  // src/ui/text-align-button/text-align-button.tsx
4666
3563
  var import_button8 = require("@kopexa/button");
4667
- var import_react28 = require("react");
3564
+ var import_react27 = require("react");
4668
3565
 
4669
3566
  // src/ui/text-align-button/use-text-align.ts
4670
- var import_icons16 = require("@kopexa/icons");
4671
- var import_react27 = require("react");
3567
+ var import_editor_utils14 = require("@kopexa/editor-utils");
3568
+ var import_icons15 = require("@kopexa/icons");
3569
+ var import_react26 = require("react");
4672
3570
  var TEXT_ALIGN_SHORTCUT_KEYS = {
4673
3571
  left: "mod+shift+l",
4674
3572
  center: "mod+shift+e",
@@ -4676,10 +3574,10 @@ var TEXT_ALIGN_SHORTCUT_KEYS = {
4676
3574
  justify: "mod+shift+j"
4677
3575
  };
4678
3576
  var textAlignIcons = {
4679
- left: import_icons16.AlignLeftIcon,
4680
- center: import_icons16.AlignCenterIcon,
4681
- right: import_icons16.AlignRightIcon,
4682
- justify: import_icons16.AlignJustifyIcon
3577
+ left: import_icons15.AlignLeftIcon,
3578
+ center: import_icons15.AlignCenterIcon,
3579
+ right: import_icons15.AlignRightIcon,
3580
+ justify: import_icons15.AlignJustifyIcon
4683
3581
  };
4684
3582
  var textAlignLabels = {
4685
3583
  left: "Align left",
@@ -4689,7 +3587,7 @@ var textAlignLabels = {
4689
3587
  };
4690
3588
  function canSetTextAlign(editor, align) {
4691
3589
  if (!editor || !editor.isEditable) return false;
4692
- if (!isExtensionAvailable(editor, "textAlign") || isNodeTypeSelected(editor, ["image"]))
3590
+ if (!(0, import_editor_utils14.isExtensionAvailable)(editor, "textAlign") || (0, import_editor_utils14.isNodeTypeSelected)(editor, ["image"]))
4693
3591
  return false;
4694
3592
  return editor.can().setTextAlign(align);
4695
3593
  }
@@ -4712,7 +3610,7 @@ function setTextAlign(editor, align) {
4712
3610
  function shouldShowButton5(props) {
4713
3611
  const { editor, hideWhenUnavailable, align } = props;
4714
3612
  if (!editor || !editor.isEditable) return false;
4715
- if (!isExtensionAvailable(editor, "textAlign")) return false;
3613
+ if (!(0, import_editor_utils14.isExtensionAvailable)(editor, "textAlign")) return false;
4716
3614
  if (hideWhenUnavailable && !editor.isActive("code")) {
4717
3615
  return canSetTextAlign(editor, align);
4718
3616
  }
@@ -4726,10 +3624,10 @@ function useTextAlign(config) {
4726
3624
  onAligned
4727
3625
  } = config;
4728
3626
  const { editor } = useTiptapEditor(providedEditor);
4729
- const [isVisible, setIsVisible] = (0, import_react27.useState)(true);
3627
+ const [isVisible, setIsVisible] = (0, import_react26.useState)(true);
4730
3628
  const canAlign = canSetTextAlign(editor, align);
4731
3629
  const isActive = isTextAlignActive(editor, align);
4732
- (0, import_react27.useEffect)(() => {
3630
+ (0, import_react26.useEffect)(() => {
4733
3631
  if (!editor) return;
4734
3632
  const handleSelectionUpdate = () => {
4735
3633
  setIsVisible(shouldShowButton5({ editor, align, hideWhenUnavailable }));
@@ -4740,7 +3638,7 @@ function useTextAlign(config) {
4740
3638
  editor.off("selectionUpdate", handleSelectionUpdate);
4741
3639
  };
4742
3640
  }, [editor, hideWhenUnavailable, align]);
4743
- const handleTextAlign = (0, import_react27.useCallback)(() => {
3641
+ const handleTextAlign = (0, import_react26.useCallback)(() => {
4744
3642
  if (!editor) return false;
4745
3643
  const success = setTextAlign(editor, align);
4746
3644
  if (success) {
@@ -4787,7 +3685,7 @@ var TextAlignButton = ({
4787
3685
  hideWhenUnavailable,
4788
3686
  onAligned
4789
3687
  });
4790
- const handleClick = (0, import_react28.useCallback)(
3688
+ const handleClick = (0, import_react27.useCallback)(
4791
3689
  (e) => {
4792
3690
  onClick == null ? void 0 : onClick(e);
4793
3691
  if (e.defaultPrevented) return;
@@ -4821,11 +3719,12 @@ var TextAlignButton = ({
4821
3719
 
4822
3720
  // src/ui/undo-redo-button/undo-redo-button.tsx
4823
3721
  var import_toolbar8 = require("@kopexa/toolbar");
4824
- var import_react30 = require("react");
3722
+ var import_react29 = require("react");
4825
3723
 
4826
3724
  // src/ui/undo-redo-button/use-undo-redo.ts
4827
- var import_icons17 = require("@kopexa/icons");
4828
- var import_react29 = require("react");
3725
+ var import_editor_utils15 = require("@kopexa/editor-utils");
3726
+ var import_icons16 = require("@kopexa/icons");
3727
+ var import_react28 = require("react");
4829
3728
  var UNDO_REDO_SHORTCUT_KEYS = {
4830
3729
  undo: "mod+z",
4831
3730
  redo: "mod+shift+z"
@@ -4835,12 +3734,12 @@ var historyActionLabels = {
4835
3734
  redo: "Redo"
4836
3735
  };
4837
3736
  var historyIcons = {
4838
- undo: import_icons17.UndoIcon,
4839
- redo: import_icons17.RedoIcon
3737
+ undo: import_icons16.UndoIcon,
3738
+ redo: import_icons16.RedoIcon
4840
3739
  };
4841
3740
  function canExecuteUndoRedoAction(editor, action) {
4842
3741
  if (!editor || !editor.isEditable) return false;
4843
- if (isNodeTypeSelected(editor, ["image"])) return false;
3742
+ if ((0, import_editor_utils15.isNodeTypeSelected)(editor, ["image"])) return false;
4844
3743
  return action === "undo" ? editor.can().undo() : editor.can().redo();
4845
3744
  }
4846
3745
  function executeUndoRedoAction(editor, action) {
@@ -4865,9 +3764,9 @@ function useUndoRedo(config) {
4865
3764
  onExecuted
4866
3765
  } = config;
4867
3766
  const { editor } = useTiptapEditor(providedEditor);
4868
- const [isVisible, setIsVisible] = (0, import_react29.useState)(true);
3767
+ const [isVisible, setIsVisible] = (0, import_react28.useState)(true);
4869
3768
  const canExecute = canExecuteUndoRedoAction(editor, action);
4870
- (0, import_react29.useEffect)(() => {
3769
+ (0, import_react28.useEffect)(() => {
4871
3770
  if (!editor) return;
4872
3771
  const handleUpdate = () => {
4873
3772
  setIsVisible(shouldShowButton6({ editor, hideWhenUnavailable, action }));
@@ -4878,7 +3777,7 @@ function useUndoRedo(config) {
4878
3777
  editor.off("transaction", handleUpdate);
4879
3778
  };
4880
3779
  }, [editor, hideWhenUnavailable, action]);
4881
- const handleAction = (0, import_react29.useCallback)(() => {
3780
+ const handleAction = (0, import_react28.useCallback)(() => {
4882
3781
  if (!editor) return false;
4883
3782
  const success = executeUndoRedoAction(editor, action);
4884
3783
  if (success) {
@@ -4916,7 +3815,7 @@ var UndoRedoButton = ({
4916
3815
  hideWhenUnavailable,
4917
3816
  onExecuted
4918
3817
  });
4919
- const handleClick = (0, import_react30.useCallback)(
3818
+ const handleClick = (0, import_react29.useCallback)(
4920
3819
  (event) => {
4921
3820
  onClick == null ? void 0 : onClick(event);
4922
3821
  if (event.defaultPrevented) return;
@@ -4954,7 +3853,8 @@ var EditorHeader = ({ editor: providedEditor }) => {
4954
3853
  const { editor } = useTiptapEditor(providedEditor);
4955
3854
  const isMobile = (0, import_use_is_mobile2.useIsMobile)();
4956
3855
  const windowSize = useWindowSize();
4957
- const toolbarRef = (0, import_react31.useRef)(null);
3856
+ const { styles } = useEditorUIContext();
3857
+ const toolbarRef = (0, import_react30.useRef)(null);
4958
3858
  const bodyRect = useCursorVisibility({
4959
3859
  editor,
4960
3860
  overlayHeight: (_b = (_a = toolbarRef.current) == null ? void 0 : _a.getBoundingClientRect().height) != null ? _b : 0
@@ -4962,15 +3862,18 @@ var EditorHeader = ({ editor: providedEditor }) => {
4962
3862
  if (!(editor == null ? void 0 : editor.isEditable)) {
4963
3863
  return null;
4964
3864
  }
4965
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3865
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: styles.toolbar(), "data-slot": "editor-toolbar", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
4966
3866
  import_toolbar9.Toolbar,
4967
3867
  {
3868
+ sticky: true,
3869
+ radius: "none",
3870
+ border: "none",
4968
3871
  style: isMobile ? {
4969
3872
  bottom: `calc(100% - ${windowSize.height - bodyRect.y}px)`
4970
3873
  } : {},
4971
3874
  children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(MainToolbarContent, {})
4972
3875
  }
4973
- );
3876
+ ) });
4974
3877
  };
4975
3878
  var MainToolbarContent = () => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
4976
3879
  /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_toolbar9.ToolbarGroup, { children: [
@@ -5004,8 +3907,8 @@ function MoreOptions({
5004
3907
  ...props
5005
3908
  }) {
5006
3909
  const { editor } = useTiptapEditor(providedEditor);
5007
- const [show, setShow] = (0, import_react31.useState)(false);
5008
- (0, import_react31.useEffect)(() => {
3910
+ const [show, setShow] = (0, import_react30.useState)(false);
3911
+ (0, import_react30.useEffect)(() => {
5009
3912
  if (!editor) return;
5010
3913
  const handleSelectionUpdate = () => {
5011
3914
  setShow(
@@ -5037,11 +3940,12 @@ function MoreOptions({
5037
3940
  variant: "ghost",
5038
3941
  color: "default",
5039
3942
  tabIndex: -1,
3943
+ size: "md",
5040
3944
  "aria-label": "More options",
5041
3945
  title: "More options",
5042
3946
  isIconOnly: true,
5043
3947
  ...props,
5044
- children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_icons18.MoreVerticalIcon, {})
3948
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_icons17.MoreVerticalIcon, {})
5045
3949
  }
5046
3950
  )
5047
3951
  }
@@ -5053,7 +3957,7 @@ function MoreOptions({
5053
3957
  align: "end",
5054
3958
  alignOffset: 4,
5055
3959
  sideOffset: 4,
5056
- children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_toolbar9.Toolbar, { tabIndex: 0, children: [
3960
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_toolbar9.Toolbar, { children: [
5057
3961
  /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_toolbar9.ToolbarGroup, { children: [
5058
3962
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(MarkButton, { type: "superscript" }),
5059
3963
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(MarkButton, { type: "subscript" })
@@ -5097,31 +4001,30 @@ function shouldShowMoreOptions(params) {
5097
4001
  // src/presets/basic/index.tsx
5098
4002
  var import_jsx_runtime17 = require("react/jsx-runtime");
5099
4003
  var BasicEditor = ({
4004
+ variant,
5100
4005
  content,
5101
- editable,
5102
- onChange,
5103
- locale
4006
+ ...options
5104
4007
  }) => {
5105
- const styles = (0, import_theme3.editorBasic)();
5106
- const editor = useCreateEditor({ content, editable, onChange });
4008
+ const editor = useCreateEditor({ content, ...options });
4009
+ const styles = (0, import_theme3.editorBasic)({ variant });
5107
4010
  if (!editor) {
5108
4011
  return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(LoadingSpinner, {});
5109
4012
  }
5110
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(EditorWrapperProvider, { value: { styles }, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react32.EditorContext.Provider, { value: { editor }, children: [
4013
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(EditorUIProvider, { value: { styles }, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: styles.root(), "data-slot": "editor", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react31.EditorContext.Provider, { value: { editor }, children: [
5111
4014
  /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(EditorHeader, { editor }),
5112
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(EditorContentArea, {})
5113
- ] }) });
4015
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(EditorContentArea, { variant })
4016
+ ] }) }) });
5114
4017
  };
5115
- var EditorContentArea = () => {
5116
- const { styles } = useEditorWrapper();
5117
- const { editor } = (0, import_react33.useContext)(import_react32.EditorContext);
4018
+ var EditorContentArea = ({ variant }) => {
4019
+ const styles = (0, import_theme3.editorBasic)({ variant });
4020
+ const { editor } = (0, import_react32.useContext)(import_react31.EditorContext);
5118
4021
  const { isDragging } = useUiEditorState(editor);
5119
4022
  useScrollToHash();
5120
4023
  if (!editor) {
5121
4024
  return null;
5122
4025
  }
5123
4026
  return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: styles.wrapper(), children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5124
- import_react32.EditorContent,
4027
+ import_react31.EditorContent,
5125
4028
  {
5126
4029
  editor,
5127
4030
  role: "presentation",
@@ -5161,14 +4064,10 @@ function LoadingSpinner({ text = "Connecting..." }) {
5161
4064
  }
5162
4065
  // Annotate the CommonJS export names for ESM import in node:
5163
4066
  0 && (module.exports = {
5164
- BasicEditor,
4067
+ Editor,
5165
4068
  convertFileToBase64,
5166
- findNodePosition,
5167
- getActiveMarkAttrs,
4069
+ getExtensions,
5168
4070
  handleImageUpload,
5169
4071
  isAllowedUri,
5170
- isEmptyNode,
5171
- isMarkInSchema,
5172
- isNodeInSchema,
5173
4072
  sanitizeUrl
5174
4073
  });