@kopexa/extension-table 17.0.45 → 17.0.46

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 (87) hide show
  1. package/dist/{chunk-SNJF4UW6.mjs → chunk-2L3HZWWG.mjs} +4 -4
  2. package/dist/{chunk-BAQU2YT5.mjs → chunk-3XEOCAHB.mjs} +1 -1
  3. package/dist/{chunk-FKOIW52J.mjs → chunk-5W5ARI64.mjs} +1 -1
  4. package/dist/{chunk-IMRHHVEF.mjs → chunk-BTJ3DCGC.mjs} +2 -2
  5. package/dist/chunk-DR2GZJH6.mjs +70 -0
  6. package/dist/chunk-GHOJLOCF.mjs +247 -0
  7. package/dist/chunk-HWVA6DOK.mjs +20 -0
  8. package/dist/{chunk-DF6ZMJLL.mjs → chunk-KLUH6EZS.mjs} +1 -1
  9. package/dist/chunk-KNOMCS6F.mjs +57 -0
  10. package/dist/{chunk-OPDSKEZR.mjs → chunk-LPHCE6EI.mjs} +16 -17
  11. package/dist/chunk-POJFNXG7.mjs +44 -0
  12. package/dist/chunk-QHD3QTD2.mjs +61 -0
  13. package/dist/index.d.mts +2 -0
  14. package/dist/index.d.ts +2 -0
  15. package/dist/index.js +456 -714
  16. package/dist/index.mjs +15 -12
  17. package/dist/kit.js +454 -714
  18. package/dist/kit.mjs +12 -12
  19. package/dist/table/index.d.mts +3 -0
  20. package/dist/table/index.d.ts +3 -0
  21. package/dist/table/index.js +411 -595
  22. package/dist/table/index.mjs +12 -9
  23. package/dist/table/{utilities → lib}/col-style.js +1 -1
  24. package/dist/{chunk-NTWXQSW6.mjs → table/lib/col-style.mjs} +2 -2
  25. package/dist/table/{utilities → lib}/delete-table-when-all-cells-selected.js +3 -3
  26. package/dist/table/{utilities → lib}/delete-table-when-all-cells-selected.mjs +2 -2
  27. package/dist/table/{utilities → lib}/get-table-node-types.js +1 -1
  28. package/dist/table/{utilities → lib}/get-table-node-types.mjs +1 -1
  29. package/dist/table/{icons.js → lib/icons.js} +1 -1
  30. package/dist/{chunk-7NEAULTF.mjs → table/lib/icons.mjs} +2 -2
  31. package/dist/table/{utilities → lib}/insert-line-above-table-action.js +1 -1
  32. package/dist/table/{utilities → lib}/insert-line-above-table-action.mjs +1 -1
  33. package/dist/table/{utilities → lib}/insert-line-below-table-action.js +1 -1
  34. package/dist/table/{utilities → lib}/insert-line-below-table-action.mjs +1 -1
  35. package/dist/table/{utilities → lib}/is-cell-selection.js +1 -1
  36. package/dist/table/{utilities → lib}/is-cell-selection.mjs +1 -1
  37. package/dist/table/{table-controls.js → lib/table-controls.js} +2 -2
  38. package/dist/table/lib/table-controls.mjs +8 -0
  39. package/dist/table/table.js +407 -593
  40. package/dist/table/table.mjs +7 -7
  41. package/dist/table/views/table-column-menu.d.mts +11 -0
  42. package/dist/table/views/table-column-menu.d.ts +11 -0
  43. package/dist/table/views/table-column-menu.js +84 -0
  44. package/dist/table/views/table-column-menu.mjs +8 -0
  45. package/dist/table/views/table-node-view.d.mts +25 -0
  46. package/dist/table/views/table-node-view.d.ts +25 -0
  47. package/dist/table/views/table-node-view.js +370 -0
  48. package/dist/table/views/table-node-view.mjs +10 -0
  49. package/dist/table/views/table-row-menu.d.mts +11 -0
  50. package/dist/table/views/table-row-menu.d.ts +11 -0
  51. package/dist/table/views/table-row-menu.js +80 -0
  52. package/dist/table/views/table-row-menu.mjs +8 -0
  53. package/dist/table-cell.js +18 -64
  54. package/dist/table-cell.mjs +1 -1
  55. package/dist/table-header.js +17 -54
  56. package/dist/table-header.mjs +1 -1
  57. package/dist/table-row.js +10 -1
  58. package/dist/table-row.mjs +1 -1
  59. package/package.json +10 -11
  60. package/dist/chunk-6NY5XWR7.mjs +0 -11
  61. package/dist/chunk-74O2ORPO.mjs +0 -81
  62. package/dist/chunk-ARSGMUXM.mjs +0 -116
  63. package/dist/chunk-GMNNSVR3.mjs +0 -540
  64. package/dist/table/icons.mjs +0 -8
  65. package/dist/table/table-controls.mjs +0 -8
  66. package/dist/table/table-view.d.mts +0 -43
  67. package/dist/table/table-view.d.ts +0 -43
  68. package/dist/table/table-view.js +0 -610
  69. package/dist/table/table-view.mjs +0 -12
  70. package/dist/table/utilities/col-style.mjs +0 -8
  71. /package/dist/{chunk-YSUOVRY4.mjs → chunk-RPPUD4R5.mjs} +0 -0
  72. /package/dist/table/{utilities → lib}/col-style.d.mts +0 -0
  73. /package/dist/table/{utilities → lib}/col-style.d.ts +0 -0
  74. /package/dist/table/{utilities → lib}/delete-table-when-all-cells-selected.d.mts +0 -0
  75. /package/dist/table/{utilities → lib}/delete-table-when-all-cells-selected.d.ts +0 -0
  76. /package/dist/table/{utilities → lib}/get-table-node-types.d.mts +0 -0
  77. /package/dist/table/{utilities → lib}/get-table-node-types.d.ts +0 -0
  78. /package/dist/table/{icons.d.mts → lib/icons.d.mts} +0 -0
  79. /package/dist/table/{icons.d.ts → lib/icons.d.ts} +0 -0
  80. /package/dist/table/{utilities → lib}/insert-line-above-table-action.d.mts +0 -0
  81. /package/dist/table/{utilities → lib}/insert-line-above-table-action.d.ts +0 -0
  82. /package/dist/table/{utilities → lib}/insert-line-below-table-action.d.mts +0 -0
  83. /package/dist/table/{utilities → lib}/insert-line-below-table-action.d.ts +0 -0
  84. /package/dist/table/{utilities → lib}/is-cell-selection.d.mts +0 -0
  85. /package/dist/table/{utilities → lib}/is-cell-selection.d.ts +0 -0
  86. /package/dist/table/{table-controls.d.mts → lib/table-controls.d.mts} +0 -0
  87. /package/dist/table/{table-controls.d.ts → lib/table-controls.d.ts} +0 -0
package/dist/kit.js CHANGED
@@ -26,13 +26,85 @@ __export(kit_exports, {
26
26
  TableKit: () => TableKit
27
27
  });
28
28
  module.exports = __toCommonJS(kit_exports);
29
- var import_react = require("@tiptap/react");
29
+ var import_react6 = require("@tiptap/react");
30
30
 
31
31
  // src/table/table.ts
32
32
  var import_extension_table = require("@tiptap/extension-table");
33
- var import_tables2 = require("@tiptap/pm/tables");
33
+ var import_tables4 = require("@tiptap/pm/tables");
34
+ var import_react5 = require("@tiptap/react");
35
+
36
+ // src/table/lib/insert-line-above-table-action.ts
37
+ var import_editor_utils = require("@kopexa/editor-utils");
38
+ var insertLineAboveTableAction = ({
39
+ editor
40
+ }) => {
41
+ if (!editor.isActive("table")) return false;
42
+ try {
43
+ const { selection } = editor.state;
44
+ const tableNode = (0, import_editor_utils.findParentNodeOfType)(selection, "table");
45
+ if (!tableNode) return false;
46
+ const tablePos = tableNode.pos;
47
+ const firstRow = tableNode.node.child(0);
48
+ const selectionPath = selection.$anchor.path;
49
+ const selectionInFirstRow = selectionPath.includes(firstRow);
50
+ if (!selectionInFirstRow) return false;
51
+ if (tablePos === 0) {
52
+ editor.chain().insertContentAt(tablePos, { type: "paragraph" }).run();
53
+ editor.chain().setTextSelection(tablePos + 1).run();
54
+ } else {
55
+ const prevNodePos = tablePos - 1;
56
+ if (prevNodePos <= 0) return false;
57
+ const prevNode = editor.state.doc.nodeAt(prevNodePos - 1);
58
+ if (prevNode && prevNode.type.name === "paragraph") {
59
+ const endOfParagraphPos = tablePos - prevNode.nodeSize;
60
+ editor.chain().setTextSelection(endOfParagraphPos).run();
61
+ } else {
62
+ return false;
63
+ }
64
+ }
65
+ return true;
66
+ } catch (e) {
67
+ console.error("failed to insert line above table", e);
68
+ return false;
69
+ }
70
+ };
71
+
72
+ // src/table/lib/insert-line-below-table-action.ts
73
+ var import_editor_utils2 = require("@kopexa/editor-utils");
74
+ var insertLineBelowTableAction = ({
75
+ editor
76
+ }) => {
77
+ if (!editor.isActive("table")) return false;
78
+ try {
79
+ const { selection } = editor.state;
80
+ const tableNode = (0, import_editor_utils2.findParentNodeOfType)(selection, "table");
81
+ if (!tableNode) return false;
82
+ const tablePos = tableNode.pos;
83
+ const table = tableNode.node;
84
+ const rowCount = table.childCount;
85
+ const lastRow = table.child(rowCount - 1);
86
+ const selectionPath = selection.$anchor.path;
87
+ const selectionInLastRow = selectionPath.includes(lastRow);
88
+ if (!selectionInLastRow) return false;
89
+ const nextNodePos = tablePos + table.nodeSize;
90
+ const nextNode = editor.state.doc.nodeAt(nextNodePos);
91
+ if (nextNode && nextNode.type.name === "paragraph") {
92
+ const endOfParagraphPos = nextNodePos + nextNode.nodeSize - 1;
93
+ editor.chain().setTextSelection(endOfParagraphPos).run();
94
+ } else if (!nextNode) {
95
+ editor.chain().insertContentAt(nextNodePos, { type: "paragraph" }).run();
96
+ editor.chain().setTextSelection(nextNodePos + 1).run();
97
+ } else {
98
+ return false;
99
+ }
100
+ return true;
101
+ } catch (e) {
102
+ console.error("failed to insert line above table", e);
103
+ return false;
104
+ }
105
+ };
34
106
 
35
- // src/table/table-controls.ts
107
+ // src/table/lib/table-controls.ts
36
108
  var import_core = require("@tiptap/core");
37
109
  var import_state = require("@tiptap/pm/state");
38
110
  var import_view = require("@tiptap/pm/view");
@@ -53,7 +125,7 @@ function tableControls() {
53
125
  mousemove: (view, event) => {
54
126
  var _a;
55
127
  const pluginState = key.getState(view.state);
56
- if (!event.target.closest(".table-wrapper") && pluginState.values.hoveredTable) {
128
+ if (!event.target.closest(".table-node-view") && pluginState.values.hoveredTable) {
57
129
  return view.dispatch(
58
130
  view.state.tr.setMeta(key, {
59
131
  setHoveredTable: null,
@@ -133,603 +205,347 @@ var TableControlsState = class {
133
205
  }
134
206
  };
135
207
 
136
- // src/table/table-view.tsx
137
- var import_dom = require("@floating-ui/dom");
138
- var import_tables = require("@tiptap/pm/tables");
139
- var import_jsx_dom_cjs = require("jsx-dom-cjs");
208
+ // src/table/views/table-node-view.tsx
209
+ var import_tables3 = require("@tiptap/pm/tables");
210
+ var import_react3 = require("@tiptap/react");
211
+ var import_react4 = require("react");
140
212
 
141
- // src/table/icons.ts
142
- var icons = {
143
- 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>`,
144
- 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>`,
145
- 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>`,
146
- insertLeftTableIcon: `<svg
147
- xmlns="http://www.w3.org/2000/svg"
148
- length={12}
149
- viewBox="0 -960 960 960"
150
- >
151
- <path
152
- 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"
153
- fill="rgb(var(--color-text-300))"
154
- />
155
- </svg>
156
- `,
157
- insertRightTableIcon: `<svg
158
- xmlns="http://www.w3.org/2000/svg"
159
- length={12}
160
- viewBox="0 -960 960 960"
161
- >
162
- <path
163
- 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"
164
- fill="rgb(var(--color-text-300))"
165
- />
166
- </svg>
167
- `,
168
- insertTopTableIcon: `<svg
169
- xmlns="http://www.w3.org/2000/svg"
170
- length={24}
171
- viewBox="0 -960 960 960"
172
- >
173
- <path
174
- 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"
175
- fill="rgb(var(--color-text-300))"
176
- />
177
- </svg>
178
- `,
179
- 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>`,
180
- 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>`,
181
- insertBottomTableIcon: `<svg
182
- xmlns="http://www.w3.org/2000/svg"
183
- length={24}
184
- viewBox="0 -960 960 960"
185
- >
186
- <path
187
- 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"
188
- fill="rgb(var(--color-text-300))"
189
- />
190
- </svg>
191
- `
192
- };
193
-
194
- // src/table/table-view.tsx
195
- var Popover = class {
196
- constructor(content, opts) {
197
- __publicField(this, "reference");
198
- __publicField(this, "floating");
199
- __publicField(this, "cleanupAutoUpdate", null);
200
- __publicField(this, "onDocClick", (e) => {
201
- if (!this.floating.contains(e.target) && !this.reference.contains(e.target)) {
202
- this.hide();
213
+ // src/table/views/table-column-menu.tsx
214
+ var import_dropdown_menu = require("@kopexa/dropdown-menu");
215
+ var import_tables = require("@tiptap/pm/tables");
216
+ var import_react = require("react");
217
+ var import_jsx_runtime = require("react/jsx-runtime");
218
+ function TableColumnMenu({
219
+ editor,
220
+ cellPos,
221
+ style
222
+ }) {
223
+ const [open, setOpen] = (0, import_react.useState)(false);
224
+ const chainAtCell = (0, import_react.useCallback)(() => {
225
+ const chain = editor.chain().focus();
226
+ if (cellPos != null) {
227
+ return chain.setTextSelection(cellPos + 1);
228
+ }
229
+ return chain;
230
+ }, [editor, cellPos]);
231
+ const handleToggleHeader = (0, import_react.useCallback)(() => {
232
+ chainAtCell().command(({ state, dispatch }) => (0, import_tables.toggleHeaderColumn)(state, dispatch)).run();
233
+ setOpen(false);
234
+ }, [chainAtCell]);
235
+ const handleAddBefore = (0, import_react.useCallback)(() => {
236
+ chainAtCell().addColumnBefore().run();
237
+ setOpen(false);
238
+ }, [chainAtCell]);
239
+ const handleAddAfter = (0, import_react.useCallback)(() => {
240
+ chainAtCell().addColumnAfter().run();
241
+ setOpen(false);
242
+ }, [chainAtCell]);
243
+ const handleDelete = (0, import_react.useCallback)(() => {
244
+ chainAtCell().deleteColumn().run();
245
+ setOpen(false);
246
+ }, [chainAtCell]);
247
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_dropdown_menu.DropdownMenu.Root, { open, onOpenChange: setOpen, children: [
248
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dropdown_menu.DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
249
+ "button",
250
+ {
251
+ type: "button",
252
+ className: "columns-control-div",
253
+ "aria-label": "Column actions",
254
+ style
203
255
  }
204
- });
205
- __publicField(this, "onEsc", (e) => {
206
- if (e.key === "Escape") this.hide();
207
- });
208
- __publicField(this, "_placement");
209
- __publicField(this, "_offsetPx");
210
- // biome-ignore lint/correctness/noUnusedPrivateClassMembers: backwards. will be used later
211
- __publicField(this, "_interactive");
212
- var _a, _b, _c, _d;
213
- this.reference = opts.reference;
214
- this.floating = document.createElement("div");
215
- this.floating.setAttribute("role", "dialog");
216
- this.floating.setAttribute("aria-modal", "false");
217
- this.floating.style.position = "fixed";
218
- this.floating.style.zIndex = "9999";
219
- this.floating.style.display = "none";
220
- this.floating.className = "rounded-md border bg-background px-2 py-2.5 text-xs shadow-sm min-w-[12rem] whitespace-nowrap";
221
- this.floating.appendChild(content);
222
- const host = (_a = opts.container) != null ? _a : document.body;
223
- host.appendChild(this.floating);
224
- this._placement = (_b = opts.placement) != null ? _b : "right";
225
- this._offsetPx = (_c = opts.offsetPx) != null ? _c : 6;
226
- this._interactive = (_d = opts.interactive) != null ? _d : true;
227
- }
228
- async _updatePosition() {
229
- const { x, y } = await (0, import_dom.computePosition)(this.reference, this.floating, {
230
- placement: this._placement,
231
- middleware: [(0, import_dom.offset)(this._offsetPx), (0, import_dom.flip)(), (0, import_dom.shift)({ padding: 8 })]
232
- });
233
- Object.assign(this.floating.style, { left: `${x}px`, top: `${y}px` });
234
- }
235
- show() {
236
- if (this.floating.style.display !== "none") return;
237
- this.floating.style.display = "block";
238
- this.cleanupAutoUpdate = (0, import_dom.autoUpdate)(
239
- this.reference,
240
- this.floating,
241
- () => this._updatePosition()
242
- );
243
- document.addEventListener("keydown", this.onEsc, { passive: true });
244
- document.addEventListener("mousedown", this.onDocClick, { capture: true });
245
- requestAnimationFrame(() => this._updatePosition());
246
- }
247
- hide() {
248
- var _a;
249
- if (this.floating.style.display === "none") return;
250
- this.floating.style.display = "none";
251
- (_a = this.cleanupAutoUpdate) == null ? void 0 : _a.call(this);
252
- this.cleanupAutoUpdate = null;
253
- document.removeEventListener("keydown", this.onEsc);
254
- document.removeEventListener("mousedown", this.onDocClick, {
255
- capture: true
256
- });
257
- }
258
- toggle() {
259
- if (this.floating.style.display === "none") this.show();
260
- else this.hide();
261
- }
262
- destroy() {
263
- this.hide();
264
- this.floating.remove();
265
- }
266
- get el() {
267
- return this.floating;
268
- }
269
- };
270
- function setCellsBackgroundColor(editor, color) {
271
- return editor.chain().focus().updateAttributes("tableCell", {
272
- background: color.backgroundColor,
273
- textColor: color.textColor
274
- }).run();
256
+ ) }),
257
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_dropdown_menu.DropdownMenu.Content, { children: [
258
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_dropdown_menu.DropdownMenu.Group, { children: [
259
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dropdown_menu.DropdownMenu.Item, { onSelect: handleToggleHeader, children: "Toggle header column" }),
260
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dropdown_menu.DropdownMenu.Item, { onSelect: handleAddBefore, children: "Insert column before" }),
261
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dropdown_menu.DropdownMenu.Item, { onSelect: handleAddAfter, children: "Insert column after" })
262
+ ] }),
263
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dropdown_menu.DropdownMenu.Separator, {}),
264
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dropdown_menu.DropdownMenu.Item, { variant: "destructive", onSelect: handleDelete, children: "Delete column" })
265
+ ] })
266
+ ] });
275
267
  }
276
- function setTableRowBackgroundColor(editor, color) {
277
- const { state, dispatch } = editor.view;
278
- const { selection } = state;
279
- if (!(selection instanceof import_tables.CellSelection)) return false;
280
- const hoveredCell = selection.$headCell || selection.$anchorCell;
281
- let rowDepth = hoveredCell.depth;
282
- while (rowDepth > 0 && hoveredCell.node(rowDepth).type.name !== "tableRow") {
283
- rowDepth--;
284
- }
285
- if (hoveredCell.node(rowDepth).type.name !== "tableRow") return false;
286
- const rowStartPos = hoveredCell.start(rowDepth);
287
- const tr = state.tr.setNodeMarkup(rowStartPos - 1, null, {
288
- ...hoveredCell.node(rowDepth).attrs,
289
- background: color.backgroundColor,
290
- textColor: color.textColor
291
- });
292
- dispatch(tr);
293
- return true;
268
+
269
+ // src/table/views/table-row-menu.tsx
270
+ var import_dropdown_menu2 = require("@kopexa/dropdown-menu");
271
+ var import_tables2 = require("@tiptap/pm/tables");
272
+ var import_react2 = require("react");
273
+ var import_jsx_runtime2 = require("react/jsx-runtime");
274
+ function TableRowMenu({ editor, cellPos, style }) {
275
+ const [open, setOpen] = (0, import_react2.useState)(false);
276
+ const chainAtCell = (0, import_react2.useCallback)(() => {
277
+ const chain = editor.chain().focus();
278
+ if (cellPos != null) {
279
+ return chain.setTextSelection(cellPos + 1);
280
+ }
281
+ return chain;
282
+ }, [editor, cellPos]);
283
+ const handleToggleHeader = (0, import_react2.useCallback)(() => {
284
+ chainAtCell().command(({ state, dispatch }) => (0, import_tables2.toggleHeaderRow)(state, dispatch)).run();
285
+ setOpen(false);
286
+ }, [chainAtCell]);
287
+ const handleAddAbove = (0, import_react2.useCallback)(() => {
288
+ chainAtCell().addRowBefore().run();
289
+ setOpen(false);
290
+ }, [chainAtCell]);
291
+ const handleAddBelow = (0, import_react2.useCallback)(() => {
292
+ chainAtCell().addRowAfter().run();
293
+ setOpen(false);
294
+ }, [chainAtCell]);
295
+ const handleDelete = (0, import_react2.useCallback)(() => {
296
+ chainAtCell().deleteRow().run();
297
+ setOpen(false);
298
+ }, [chainAtCell]);
299
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_dropdown_menu2.DropdownMenu.Root, { open, onOpenChange: setOpen, children: [
300
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dropdown_menu2.DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
301
+ "button",
302
+ {
303
+ type: "button",
304
+ className: "rows-control-div",
305
+ "aria-label": "Row actions",
306
+ style
307
+ }
308
+ ) }),
309
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_dropdown_menu2.DropdownMenu.Content, { children: [
310
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_dropdown_menu2.DropdownMenu.Group, { children: [
311
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dropdown_menu2.DropdownMenu.Item, { onSelect: handleToggleHeader, children: "Toggle header row" }),
312
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dropdown_menu2.DropdownMenu.Item, { onSelect: handleAddAbove, children: "Insert row above" }),
313
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dropdown_menu2.DropdownMenu.Item, { onSelect: handleAddBelow, children: "Insert row below" })
314
+ ] }),
315
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dropdown_menu2.DropdownMenu.Separator, {}),
316
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dropdown_menu2.DropdownMenu.Item, { variant: "destructive", onSelect: handleDelete, children: "Delete row" })
317
+ ] })
318
+ ] });
294
319
  }
295
- var columnsToolboxItems = [
296
- {
297
- label: "Toggle column header",
298
- icon: icons.toggleColumnHeader,
299
- action: ({ editor }) => editor.chain().focus().toggleHeaderColumn().run()
300
- },
301
- {
302
- label: "Add column before",
303
- icon: icons.insertLeftTableIcon,
304
- action: ({ editor }) => editor.chain().focus().addColumnBefore().run()
305
- },
306
- {
307
- label: "Add column after",
308
- icon: icons.insertRightTableIcon,
309
- action: ({ editor }) => editor.chain().focus().addColumnAfter().run()
310
- },
311
- { label: "Pick color", icon: "", action: () => {
312
- } },
313
- {
314
- label: "Delete column",
315
- icon: icons.deleteColumn,
316
- action: ({ editor }) => editor.chain().focus().deleteColumn().run()
317
- }
318
- ];
319
- var rowsToolboxItems = [
320
- {
321
- label: "Toggle row header",
322
- icon: icons.toggleRowHeader,
323
- action: ({ editor }) => editor.chain().focus().toggleHeaderRow().run()
324
- },
325
- {
326
- label: "Add row above",
327
- icon: icons.insertTopTableIcon,
328
- action: ({ editor }) => editor.chain().focus().addRowBefore().run()
329
- },
330
- {
331
- label: "Add row below",
332
- icon: icons.insertBottomTableIcon,
333
- action: ({ editor }) => editor.chain().focus().addRowAfter().run()
334
- },
335
- { label: "Pick color", icon: "", action: () => {
336
- } },
337
- {
338
- label: "Delete row",
339
- icon: icons.deleteRow,
340
- action: ({ editor }) => editor.chain().focus().deleteRow().run()
320
+
321
+ // src/table/views/table-node-view.tsx
322
+ var import_jsx_runtime3 = require("react/jsx-runtime");
323
+ function extractHoverInfo(decorations) {
324
+ const info = {};
325
+ for (const dec of decorations) {
326
+ const spec = dec.spec;
327
+ if ((spec == null ? void 0 : spec.hoveredCell) !== void 0)
328
+ info.hoveredCell = spec.hoveredCell;
329
+ if ((spec == null ? void 0 : spec.hoveredTable) !== void 0)
330
+ info.hoveredTable = spec.hoveredTable;
341
331
  }
342
- ];
343
- function buildToolboxContent({
344
- items,
345
- onClickItem,
346
- onSelectColor,
347
- colors
348
- }) {
349
- return (0, import_jsx_dom_cjs.h)(
350
- "div",
351
- { className: "space-y-2" },
352
- items.map((item) => {
353
- if (item.label === "Pick color") {
354
- return (0, import_jsx_dom_cjs.h)("div", { className: "flex flex-col" }, [
355
- (0, import_jsx_dom_cjs.h)("hr", { className: "!my-2 border" }),
356
- (0, import_jsx_dom_cjs.h)("div", { className: "text-foreground text-sm" }, item.label),
357
- (0, import_jsx_dom_cjs.h)(
358
- "div",
359
- { className: "grid grid-cols-6 gap-x-1 gap-y-2.5 mt-2" },
360
- Object.entries(colors).map(
361
- ([_, colorValue]) => {
362
- var _a;
363
- return (0, import_jsx_dom_cjs.h)("button", {
364
- // @ts-expect-error JSX
365
- type: "button",
366
- className: "grid place-items-center size-6 rounded outline-none ring-offset-2 focus-visible:ring",
367
- style: `background-color:${colorValue.backgroundColor};color:${colorValue.textColor || "inherit"};`,
368
- innerHTML: (_a = colorValue.icon) != null ? _a : `<span class="text-md" style="color:${colorValue.textColor || "inherit"}">A</span>`,
369
- onClick: (e) => {
370
- e.stopPropagation();
371
- onSelectColor(colorValue);
372
- }
373
- });
374
- }
375
- )
376
- ),
377
- (0, import_jsx_dom_cjs.h)("hr", { className: "!my-2 border" })
378
- ]);
379
- }
380
- return (0, import_jsx_dom_cjs.h)(
381
- "button",
382
- {
383
- // @ts-expect-error JSX
384
- type: "button",
385
- className: "w-full flex items-center gap-2 px-1 py-1.5 bg-background hover:bg-muted text-sm text-foreground rounded",
386
- onClick: (e) => {
387
- e.stopPropagation();
388
- onClickItem(item);
389
- }
390
- },
391
- [
392
- (0, import_jsx_dom_cjs.h)("span", { className: "h-3 w-3 shrink-0", innerHTML: item.icon }),
393
- (0, import_jsx_dom_cjs.h)("div", { className: "label" }, item.label)
394
- ]
395
- );
396
- })
397
- );
332
+ return info;
398
333
  }
399
- function createToolbox({
400
- triggerButton,
401
- items,
402
- onSelectColor,
403
- onClickItem,
404
- colors,
405
- appendTo
334
+ function TableNodeView({
335
+ editor,
336
+ node,
337
+ decorations,
338
+ getPos
406
339
  }) {
407
- if (!triggerButton) {
408
- return null;
409
- }
410
- const content = buildToolboxContent({
411
- items,
412
- onClickItem,
413
- onSelectColor,
414
- colors
415
- });
416
- const pop = new Popover(content, {
417
- reference: triggerButton,
418
- container: appendTo != null ? appendTo : void 0,
419
- placement: "right",
420
- offsetPx: 6,
421
- interactive: true
340
+ const wrapperRef = (0, import_react4.useRef)(null);
341
+ const scrollRef = (0, import_react4.useRef)(null);
342
+ const isEditable = (0, import_react3.useEditorState)({
343
+ editor,
344
+ selector: ({ editor: e }) => {
345
+ var _a;
346
+ return (_a = e == null ? void 0 : e.isEditable) != null ? _a : false;
347
+ }
422
348
  });
423
- const onTrigger = (e) => {
424
- e.stopPropagation();
425
- pop.toggle();
426
- };
427
- triggerButton.addEventListener("click", onTrigger);
428
- return {
429
- show: () => pop.show(),
430
- hide: () => pop.hide(),
431
- destroy: () => {
432
- pop.destroy();
433
- triggerButton.removeEventListener("click", onTrigger);
349
+ const cellMinWidth = (0, import_react4.useMemo)(() => {
350
+ var _a, _b, _c;
351
+ return (_c = (_b = (_a = editor.extensionManager.extensions.find((ext) => ext.name === "table")) == null ? void 0 : _a.options) == null ? void 0 : _b.cellMinWidth) != null ? _c : 100;
352
+ }, [editor]);
353
+ const map = (0, import_react4.useMemo)(() => import_tables3.TableMap.get(node), [node]);
354
+ const [isSideHovered, setIsSideHovered] = (0, import_react4.useState)(false);
355
+ const [isBottomHovered, setIsBottomHovered] = (0, import_react4.useState)(false);
356
+ const { hoveredTable, hoveredCell } = (0, import_react4.useMemo)(
357
+ () => extractHoverInfo(decorations),
358
+ [decorations]
359
+ );
360
+ const controlsDisabled = !hoveredTable || !hoveredCell;
361
+ (0, import_react4.useEffect)(() => {
362
+ var _a;
363
+ const table = (_a = scrollRef.current) == null ? void 0 : _a.querySelector("table");
364
+ if (!table) return;
365
+ let colgroup = table.querySelector("colgroup");
366
+ if (!colgroup) {
367
+ colgroup = document.createElement("colgroup");
368
+ table.insertBefore(colgroup, table.firstChild);
434
369
  }
435
- };
436
- }
437
- var TableView = class {
438
- constructor(node, cellMinWidth, decorations, editor, getPos) {
439
- __publicField(this, "node");
440
- __publicField(this, "cellMinWidth");
441
- __publicField(this, "decorations");
442
- __publicField(this, "editor");
443
- __publicField(this, "getPos");
444
- __publicField(this, "hoveredCell", null);
445
- __publicField(this, "map");
446
- __publicField(this, "root");
447
- __publicField(this, "table");
448
- __publicField(this, "colgroup");
449
- __publicField(this, "tbody");
450
- __publicField(this, "rowsControl");
451
- __publicField(this, "columnsControl");
452
- __publicField(this, "columnsToolbox");
453
- __publicField(this, "rowsToolbox");
454
- __publicField(this, "controls");
455
- var _a, _b, _c, _d;
456
- this.node = node;
457
- this.cellMinWidth = cellMinWidth;
458
- this.decorations = decorations.slice();
459
- this.editor = editor;
460
- this.getPos = getPos;
461
- this.hoveredCell = null;
462
- this.map = import_tables.TableMap.get(node);
463
- if (editor.isEditable) {
464
- this.rowsControl = (0, import_jsx_dom_cjs.h)(
465
- "div",
466
- { className: "rows-control" },
467
- (0, import_jsx_dom_cjs.h)("button", {
468
- // @ts-expect-error JSX
469
- type: "button",
470
- className: "rows-control-div",
471
- onClick: () => this.selectRow(),
472
- "aria-label": "Row actions"
473
- })
474
- );
475
- this.columnsControl = (0, import_jsx_dom_cjs.h)(
476
- "div",
477
- { className: "columns-control" },
478
- (0, import_jsx_dom_cjs.h)("button", {
479
- // @ts-expect-error JSX
480
- type: "button",
481
- className: "columns-control-div",
482
- onClick: () => this.selectColumn(),
483
- "aria-label": "Column actions"
484
- })
485
- );
486
- this.controls = (0, import_jsx_dom_cjs.h)(
487
- "div",
488
- { className: "table-controls", contentEditable: "false" },
489
- this.rowsControl,
490
- this.columnsControl
491
- );
492
- const palette = {
493
- Blue: { backgroundColor: "#D9E4FF", textColor: "#171717" },
494
- Orange: { backgroundColor: "#FFEDD5", textColor: "#171717" },
495
- Grey: { backgroundColor: "#F1F1F1", textColor: "#171717" },
496
- Yellow: { backgroundColor: "#FEF3C7", textColor: "#171717" },
497
- Green: { backgroundColor: "#DCFCE7", textColor: "#171717" },
498
- Red: { backgroundColor: "#FFDDDD", textColor: "#171717" },
499
- Pink: { backgroundColor: "#FFE8FA", textColor: "#171717" },
500
- Purple: { backgroundColor: "#E8DAFB", textColor: "#171717" },
501
- None: {
502
- backgroundColor: "transparent",
503
- textColor: "inherit",
504
- 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>`
505
- }
506
- };
507
- this.columnsToolbox = createToolbox({
508
- triggerButton: (_a = this.columnsControl) == null ? void 0 : _a.querySelector(
509
- ".columns-control-div"
510
- ),
511
- items: columnsToolboxItems,
512
- colors: palette,
513
- appendTo: (_b = this.controls) != null ? _b : null,
514
- onSelectColor: (color) => setCellsBackgroundColor(this.editor, color),
515
- onClickItem: (item) => {
516
- var _a2, _b2;
517
- item.action({
518
- editor: this.editor,
519
- triggerButton: (_a2 = this.columnsControl) == null ? void 0 : _a2.firstElementChild,
520
- controlsContainer: this.controls
521
- });
522
- (_b2 = this.columnsToolbox) == null ? void 0 : _b2.hide();
523
- }
524
- });
525
- this.rowsToolbox = createToolbox({
526
- triggerButton: (_c = this.rowsControl) == null ? void 0 : _c.querySelector(
527
- ".rows-control-div"
528
- ),
529
- items: rowsToolboxItems,
530
- colors: palette,
531
- appendTo: (_d = this.controls) != null ? _d : null,
532
- onSelectColor: (color) => setTableRowBackgroundColor(editor, color),
533
- onClickItem: (item) => {
534
- var _a2, _b2;
535
- item.action({
536
- editor: this.editor,
537
- triggerButton: (_a2 = this.rowsControl) == null ? void 0 : _a2.firstElementChild,
538
- controlsContainer: this.controls
539
- });
540
- (_b2 = this.rowsToolbox) == null ? void 0 : _b2.hide();
541
- }
542
- });
370
+ const width = map.width;
371
+ while (colgroup.children.length < width) {
372
+ colgroup.appendChild(document.createElement("col"));
543
373
  }
544
- this.colgroup = (0, import_jsx_dom_cjs.h)(
545
- "colgroup",
546
- null,
547
- Array.from({ length: this.map.width }, () => 1).map(() => (0, import_jsx_dom_cjs.h)("col"))
548
- );
549
- this.tbody = (0, import_jsx_dom_cjs.h)("tbody");
550
- this.table = (0, import_jsx_dom_cjs.h)(
551
- "table",
552
- null,
553
- this.colgroup,
554
- this.tbody
555
- );
556
- this.root = (0, import_jsx_dom_cjs.h)(
557
- "div",
558
- {
559
- className: "table-wrapper horizontal-scrollbar scrollbar-md controls--disabled"
560
- },
561
- this.controls,
562
- this.table
563
- );
564
- this.render();
565
- }
566
- get dom() {
567
- return this.root;
568
- }
569
- get contentDOM() {
570
- return this.tbody;
571
- }
572
- update(node, decorations) {
573
- if (node.type !== this.node.type) return false;
574
- this.node = node;
575
- this.decorations = [...decorations];
576
- this.map = import_tables.TableMap.get(this.node);
577
- if (this.editor.isEditable) this.updateControls();
578
- this.render();
579
- return true;
580
- }
581
- render() {
582
- if (this.colgroup.children.length !== this.map.width) {
583
- const cols = Array.from({ length: this.map.width }, () => 1).map(
584
- () => (0, import_jsx_dom_cjs.h)("col")
585
- );
586
- this.colgroup.replaceChildren(...cols);
374
+ while (colgroup.children.length > width) {
375
+ if (colgroup.lastChild) colgroup.removeChild(colgroup.lastChild);
587
376
  }
588
- (0, import_tables.updateColumnsOnResize)(
589
- this.node,
590
- this.colgroup,
591
- this.table,
592
- this.cellMinWidth
593
- );
594
- }
595
- ignoreMutation() {
596
- return true;
597
- }
598
- updateControls() {
599
- var _a;
600
- const { hoveredTable: table, hoveredCell: cell } = Object.values(
601
- this.decorations
602
- ).reduce(
603
- (acc, curr) => {
604
- if (curr.spec.hoveredCell !== void 0)
605
- acc.hoveredCell = curr.spec.hoveredCell;
606
- if (curr.spec.hoveredTable !== void 0)
607
- acc.hoveredTable = curr.spec.hoveredTable;
608
- return acc;
609
- },
610
- {}
611
- );
612
- if (table === void 0 || cell === void 0) {
613
- this.root.classList.add("controls--disabled");
377
+ (0, import_tables3.updateColumnsOnResize)(node, colgroup, table, cellMinWidth);
378
+ }, [node, map.width, cellMinWidth]);
379
+ const [controlPos, setControlPos] = (0, import_react4.useState)(null);
380
+ const updatePositions = (0, import_react4.useCallback)(() => {
381
+ if (!hoveredCell || !wrapperRef.current) {
382
+ setControlPos(null);
383
+ return;
384
+ }
385
+ const cellDom = editor.view.nodeDOM(hoveredCell.pos);
386
+ if (!cellDom) {
387
+ setControlPos(null);
614
388
  return;
615
389
  }
616
- this.root.classList.remove("controls--disabled");
617
- this.hoveredCell = cell;
618
- const cellDom = this.editor.view.nodeDOM(cell.pos);
619
- if (!this.table || !cellDom) return;
620
- const tableRect = this.table.getBoundingClientRect();
390
+ const wrapperRect = wrapperRef.current.getBoundingClientRect();
621
391
  const cellRect = cellDom.getBoundingClientRect();
622
- if (this.columnsControl) {
623
- this.columnsControl.style.left = `${cellRect.left - tableRect.left - (((_a = this.table.parentElement) == null ? void 0 : _a.scrollLeft) || 0)}px`;
624
- this.columnsControl.style.width = `${cellRect.width}px`;
392
+ setControlPos({
393
+ columnLeft: cellRect.left - wrapperRect.left,
394
+ columnWidth: cellRect.width,
395
+ rowTop: cellRect.top - wrapperRect.top,
396
+ rowHeight: cellRect.height
397
+ });
398
+ }, [hoveredCell, editor.view]);
399
+ (0, import_react4.useEffect)(() => {
400
+ updatePositions();
401
+ const scrollEl = scrollRef.current;
402
+ if (!scrollEl) return;
403
+ scrollEl.addEventListener("scroll", updatePositions, { passive: true });
404
+ return () => scrollEl.removeEventListener("scroll", updatePositions);
405
+ }, [updatePositions]);
406
+ const handleMouseMove = (0, import_react4.useCallback)(
407
+ (e) => {
408
+ if (!isEditable) return;
409
+ const rect = e.currentTarget.getBoundingClientRect();
410
+ const x = e.clientX - rect.left;
411
+ const y = e.clientY - rect.top;
412
+ const threshold = 50;
413
+ setIsSideHovered(x >= rect.width - threshold);
414
+ setIsBottomHovered(y >= rect.height - threshold);
415
+ },
416
+ [isEditable]
417
+ );
418
+ const handleMouseLeave = (0, import_react4.useCallback)((e) => {
419
+ const relatedTarget = e.relatedTarget;
420
+ const currentTarget = e.currentTarget;
421
+ if (relatedTarget instanceof Node && currentTarget instanceof Node && currentTarget.contains(relatedTarget)) {
422
+ return;
625
423
  }
626
- if (this.rowsControl) {
627
- this.rowsControl.style.top = `${cellRect.top - tableRect.top}px`;
628
- this.rowsControl.style.height = `${cellRect.height}px`;
424
+ if (wrapperRef.current && relatedTarget instanceof Node && wrapperRef.current.contains(relatedTarget)) {
425
+ return;
629
426
  }
630
- }
631
- selectColumn() {
632
- if (!this.hoveredCell) return;
633
- const colIndex = this.map.colCount(
634
- this.hoveredCell.pos - (this.getPos() + 1)
635
- );
636
- const anchorCellPos = this.hoveredCell.pos;
637
- const headCellPos = this.map.map[colIndex + this.map.width * (this.map.height - 1)] + (this.getPos() + 1);
638
- const cellSelection = import_tables.CellSelection.create(
639
- this.editor.view.state.doc,
640
- anchorCellPos,
641
- headCellPos
642
- );
643
- this.editor.view.dispatch(this.editor.state.tr.setSelection(cellSelection));
644
- }
645
- selectRow() {
646
- if (!this.hoveredCell) return;
647
- const anchorCellPos = this.hoveredCell.pos;
648
- const anchorCellIndex = this.map.map.indexOf(
649
- anchorCellPos - (this.getPos() + 1)
650
- );
651
- const headCellPos = this.map.map[anchorCellIndex + (this.map.width - 1)] + (this.getPos() + 1);
652
- const cellSelection = import_tables.CellSelection.create(
653
- this.editor.state.doc,
654
- anchorCellPos,
655
- headCellPos
656
- );
657
- this.editor.view.dispatch(
658
- this.editor.view.state.tr.setSelection(cellSelection)
659
- );
660
- }
661
- };
662
-
663
- // src/table/utilities/insert-line-above-table-action.ts
664
- var import_editor_utils = require("@kopexa/editor-utils");
665
- var insertLineAboveTableAction = ({
666
- editor
667
- }) => {
668
- if (!editor.isActive("table")) return false;
669
- try {
670
- const { selection } = editor.state;
671
- const tableNode = (0, import_editor_utils.findParentNodeOfType)(selection, "table");
672
- if (!tableNode) return false;
673
- const tablePos = tableNode.pos;
674
- const firstRow = tableNode.node.child(0);
675
- const selectionPath = selection.$anchor.path;
676
- const selectionInFirstRow = selectionPath.includes(firstRow);
677
- if (!selectionInFirstRow) return false;
678
- if (tablePos === 0) {
679
- editor.chain().insertContentAt(tablePos, { type: "paragraph" }).run();
680
- editor.chain().setTextSelection(tablePos + 1).run();
681
- } else {
682
- const prevNodePos = tablePos - 1;
683
- if (prevNodePos <= 0) return false;
684
- const prevNode = editor.state.doc.nodeAt(prevNodePos - 1);
685
- if (prevNode && prevNode.type.name === "paragraph") {
686
- const endOfParagraphPos = tablePos - prevNode.nodeSize;
687
- editor.chain().setTextSelection(endOfParagraphPos).run();
688
- } else {
689
- return false;
427
+ setIsSideHovered(false);
428
+ setIsBottomHovered(false);
429
+ }, []);
430
+ const focusTable = (0, import_react4.useCallback)(() => {
431
+ const pos = getPos();
432
+ if (pos === void 0) return false;
433
+ try {
434
+ const resolvedPos = editor.state.doc.resolve(pos + 1);
435
+ const table = resolvedPos.node(1);
436
+ if ((table == null ? void 0 : table.type.name) === "table") {
437
+ let cellPos = pos + 1;
438
+ table.descendants((n, nodePos) => {
439
+ if (n.type.name === "tableCell" || n.type.name === "tableHeader") {
440
+ cellPos = pos + 1 + nodePos + 1;
441
+ return false;
442
+ }
443
+ return true;
444
+ });
445
+ editor.chain().focus().setTextSelection(cellPos).run();
446
+ return true;
690
447
  }
448
+ } catch {
691
449
  }
692
- return true;
693
- } catch (e) {
694
- console.error("failed to insert line above table", e);
695
450
  return false;
696
- }
697
- };
698
-
699
- // src/table/utilities/insert-line-below-table-action.ts
700
- var import_editor_utils2 = require("@kopexa/editor-utils");
701
- var insertLineBelowTableAction = ({
702
- editor
703
- }) => {
704
- if (!editor.isActive("table")) return false;
705
- try {
706
- const { selection } = editor.state;
707
- const tableNode = (0, import_editor_utils2.findParentNodeOfType)(selection, "table");
708
- if (!tableNode) return false;
709
- const tablePos = tableNode.pos;
710
- const table = tableNode.node;
711
- const rowCount = table.childCount;
712
- const lastRow = table.child(rowCount - 1);
713
- const selectionPath = selection.$anchor.path;
714
- const selectionInLastRow = selectionPath.includes(lastRow);
715
- if (!selectionInLastRow) return false;
716
- const nextNodePos = tablePos + table.nodeSize;
717
- const nextNode = editor.state.doc.nodeAt(nextNodePos);
718
- if (nextNode && nextNode.type.name === "paragraph") {
719
- const endOfParagraphPos = nextNodePos + nextNode.nodeSize - 1;
720
- editor.chain().setTextSelection(endOfParagraphPos).run();
721
- } else if (!nextNode) {
722
- editor.chain().insertContentAt(nextNodePos, { type: "paragraph" }).run();
723
- editor.chain().setTextSelection(nextNodePos + 1).run();
451
+ }, [editor, getPos]);
452
+ const handleAddColumn = (0, import_react4.useCallback)(() => {
453
+ if (focusTable()) {
454
+ editor.chain().addColumnAfter().run();
724
455
  } else {
725
- return false;
456
+ editor.chain().focus().addColumnAfter().run();
726
457
  }
727
- return true;
728
- } catch (e) {
729
- console.error("failed to insert line above table", e);
730
- return false;
731
- }
732
- };
458
+ }, [editor, focusTable]);
459
+ const handleAddRow = (0, import_react4.useCallback)(() => {
460
+ if (focusTable()) {
461
+ editor.chain().addRowAfter().run();
462
+ } else {
463
+ editor.chain().focus().addRowAfter().run();
464
+ }
465
+ }, [editor, focusTable]);
466
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
467
+ import_react3.NodeViewWrapper,
468
+ {
469
+ ref: wrapperRef,
470
+ className: [
471
+ "table-node-view pr-6 pb-6",
472
+ controlsDisabled ? "controls--disabled" : ""
473
+ ].join(" "),
474
+ onMouseEnter: handleMouseMove,
475
+ onMouseMove: handleMouseMove,
476
+ onMouseLeave: handleMouseLeave,
477
+ "data-type": "table",
478
+ children: [
479
+ isEditable && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "table-controls", contentEditable: false, children: [
480
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
481
+ "div",
482
+ {
483
+ className: "rows-control",
484
+ style: controlPos ? {
485
+ top: `${controlPos.rowTop}px`,
486
+ height: `${controlPos.rowHeight}px`
487
+ } : void 0,
488
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TableRowMenu, { editor, cellPos: hoveredCell == null ? void 0 : hoveredCell.pos })
489
+ }
490
+ ),
491
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
492
+ "div",
493
+ {
494
+ className: "columns-control",
495
+ style: controlPos ? {
496
+ left: `${controlPos.columnLeft}px`,
497
+ width: `${controlPos.columnWidth}px`
498
+ } : void 0,
499
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TableColumnMenu, { editor, cellPos: hoveredCell == null ? void 0 : hoveredCell.pos })
500
+ }
501
+ )
502
+ ] }),
503
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
504
+ "div",
505
+ {
506
+ ref: scrollRef,
507
+ className: "table-wrapper horizontal-scrollbar scrollbar-md",
508
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react3.NodeViewContent, { as: "table" })
509
+ }
510
+ ),
511
+ isEditable && isSideHovered && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
512
+ "div",
513
+ {
514
+ className: "absolute -right-6 top-0 h-full flex items-center",
515
+ contentEditable: false,
516
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
517
+ "button",
518
+ {
519
+ type: "button",
520
+ className: "w-4 h-full hover:bg-accent cursor-pointer flex items-center justify-center rounded-sm transition-colors text-muted-foreground text-xs",
521
+ onClick: handleAddColumn,
522
+ "aria-label": "Add column",
523
+ children: "+"
524
+ }
525
+ )
526
+ }
527
+ ),
528
+ isEditable && isBottomHovered && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
529
+ "div",
530
+ {
531
+ className: "absolute -bottom-6 left-0 w-full flex justify-center",
532
+ contentEditable: false,
533
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
534
+ "button",
535
+ {
536
+ type: "button",
537
+ className: "h-4 w-full hover:bg-accent cursor-pointer flex items-center justify-center rounded-sm transition-colors text-muted-foreground text-xs",
538
+ onClick: handleAddRow,
539
+ "aria-label": "Add row",
540
+ children: "+"
541
+ }
542
+ )
543
+ }
544
+ )
545
+ ]
546
+ }
547
+ );
548
+ }
733
549
 
734
550
  // src/table/table.ts
735
551
  var Table = import_extension_table.Table.extend({
@@ -771,32 +587,30 @@ var Table = import_extension_table.Table.extend({
771
587
  };
772
588
  },
773
589
  addNodeView() {
774
- return ({ editor, getPos, node, decorations }) => {
775
- const { cellMinWidth } = this.options;
776
- return new TableView(
777
- node,
778
- cellMinWidth,
779
- // biome-ignore lint/suspicious/noExplicitAny: prosemirror
780
- decorations,
781
- editor,
782
- getPos
783
- );
784
- };
590
+ return (0, import_react5.ReactNodeViewRenderer)(TableNodeView, {
591
+ contentDOMElementTag: "tbody",
592
+ stopEvent: ({ event }) => {
593
+ const target = event.target;
594
+ if (target.closest("button, [role='button'], input, a")) {
595
+ return true;
596
+ }
597
+ return false;
598
+ }
599
+ });
785
600
  },
786
601
  addProseMirrorPlugins() {
787
602
  const isResizable = this.options.resizable && this.editor.isEditable;
788
603
  const plugins = [
789
- (0, import_tables2.tableEditing)({
604
+ (0, import_tables4.tableEditing)({
790
605
  allowTableNodeSelection: this.options.allowTableNodeSelection
791
606
  }),
792
607
  tableControls()
793
608
  ];
794
609
  if (isResizable) {
795
610
  plugins.unshift(
796
- (0, import_tables2.columnResizing)({
611
+ (0, import_tables4.columnResizing)({
797
612
  handleWidth: this.options.handleWidth,
798
613
  cellMinWidth: this.options.cellMinWidth,
799
- // View: TableView,
800
614
  lastColumnResizable: this.options.lastColumnResizable
801
615
  })
802
616
  );
@@ -810,7 +624,6 @@ var import_core2 = require("@tiptap/core");
810
624
  var TableCell = import_core2.Node.create({
811
625
  name: "tableCell",
812
626
  content: "block+",
813
- // DONT allow table in table.
814
627
  tableRole: "cell",
815
628
  isolating: true,
816
629
  addOptions() {
@@ -822,11 +635,17 @@ var TableCell = import_core2.Node.create({
822
635
  return [{ tag: "td" }];
823
636
  },
824
637
  renderHTML({ node, HTMLAttributes }) {
638
+ const attrs = {};
639
+ if (node.attrs.align) {
640
+ attrs["data-align"] = node.attrs.align;
641
+ attrs.style = `text-align: ${node.attrs.align}`;
642
+ }
643
+ if (node.attrs.backgroundColor) {
644
+ attrs["data-background-color"] = node.attrs.backgroundColor;
645
+ }
825
646
  return [
826
647
  "td",
827
- (0, import_core2.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes, {
828
- style: `background-color: ${node.attrs.background}; color: ${node.attrs.textColor}`
829
- }),
648
+ (0, import_core2.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes, attrs),
830
649
  0
831
650
  ];
832
651
  },
@@ -836,89 +655,51 @@ var TableCell = import_core2.Node.create({
836
655
  default: 1,
837
656
  parseHTML: (element) => {
838
657
  const colspan = element.getAttribute("colspan");
839
- const value = colspan ? Number.parseInt(colspan, 10) : 1;
840
- return value;
658
+ return colspan ? Number.parseInt(colspan, 10) : 1;
841
659
  }
842
660
  },
843
661
  rowspan: {
844
662
  default: 1,
845
663
  parseHTML: (element) => {
846
664
  const rowspan = element.getAttribute("rowspan");
847
- const value = rowspan ? Number.parseInt(rowspan, 10) : 1;
848
- return value;
665
+ return rowspan ? Number.parseInt(rowspan, 10) : 1;
849
666
  }
850
667
  },
851
668
  colwidth: {
852
669
  default: null,
853
670
  parseHTML: (element) => {
854
671
  const colwidth = element.getAttribute("colwidth");
855
- const value = colwidth ? [Number.parseInt(colwidth, 10)] : null;
856
- return value;
672
+ return colwidth ? colwidth.split(",").map((w) => Number.parseInt(w, 10)) : null;
857
673
  }
858
674
  },
859
- background: {
860
- default: null
861
- },
862
- textColor: {
863
- default: null
675
+ align: {
676
+ default: null,
677
+ parseHTML: (element) => element.getAttribute("data-align")
864
678
  },
865
- style: {
866
- default: null
679
+ backgroundColor: {
680
+ default: null,
681
+ parseHTML: (element) => element.getAttribute("data-background-color")
867
682
  }
868
683
  };
869
684
  }
870
- // addProseMirrorPlugins() {
871
- // return [
872
- // new Plugin({
873
- // props: {
874
- // decorations: (state) => {
875
- // const { isEditable } = this.editor;
876
- // if (!isEditable) {
877
- // return DecorationSet.empty;
878
- // }
879
- // const { doc, selection } = state;
880
- // const decorations: Decoration[] = [];
881
- // const cells = getCellsInColumn(0)(selection);
882
- // if (cells) {
883
- // cells.forEach(({ pos }: { pos: number }, index: number) => {
884
- // decorations.push(
885
- // Decoration.widget(pos + 1, () => {
886
- // const rowSelected = isRowSelected(index)(selection);
887
- // let className = "grip-row";
888
- // if (rowSelected) {
889
- // className += " selected";
890
- // }
891
- // if (index === 0) {
892
- // className += " first";
893
- // }
894
- // if (index === cells.length - 1) {
895
- // className += " last";
896
- // }
897
- // const grip = document.createElement("a");
898
- // grip.className = className;
899
- // grip.addEventListener("mousedown", (event) => {
900
- // event.preventDefault();
901
- // event.stopImmediatePropagation();
902
- // this.editor.view.dispatch(
903
- // selectRow(index)(this.editor.state.tr),
904
- // );
905
- // });
906
- // return grip;
907
- // }),
908
- // );
909
- // });
910
- // }
911
- // return DecorationSet.create(doc, decorations);
912
- // },
913
- // },
914
- // }),
915
- // ];
916
- // },
917
685
  });
918
686
 
919
687
  // src/table-header.ts
688
+ var import_core3 = require("@tiptap/core");
920
689
  var import_extension_table2 = require("@tiptap/extension-table");
921
690
  var TableHeader = import_extension_table2.TableHeader.extend({
691
+ renderHTML({ node, HTMLAttributes }) {
692
+ const attrs = {};
693
+ if (node.attrs.align) {
694
+ attrs["data-align"] = node.attrs.align;
695
+ attrs.style = `text-align: ${node.attrs.align}`;
696
+ }
697
+ return [
698
+ "th",
699
+ (0, import_core3.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes, attrs),
700
+ 0
701
+ ];
702
+ },
922
703
  addAttributes() {
923
704
  return {
924
705
  colspan: {
@@ -931,75 +712,34 @@ var TableHeader = import_extension_table2.TableHeader.extend({
931
712
  default: null,
932
713
  parseHTML: (element) => {
933
714
  const colwidth = element.getAttribute("colwidth");
934
- const value = colwidth ? [Number.parseInt(colwidth, 10)] : null;
935
- return value;
715
+ return colwidth ? colwidth.split(",").map((w) => Number.parseInt(w, 10)) : null;
936
716
  }
937
717
  },
938
- background: {
939
- default: "none"
940
- },
941
- style: {
942
- default: null
718
+ align: {
719
+ default: null,
720
+ parseHTML: (element) => element.getAttribute("data-align")
943
721
  }
944
722
  };
945
723
  }
946
- // addProseMirrorPlugins() {
947
- // return [
948
- // new Plugin({
949
- // props: {
950
- // decorations: (state) => {
951
- // const { isEditable } = this.editor;
952
- // if (!isEditable) {
953
- // return DecorationSet.empty;
954
- // }
955
- // const { doc, selection } = state;
956
- // const decorations: Decoration[] = [];
957
- // const cells = getCellsInRow(0)(selection);
958
- // if (cells) {
959
- // cells.forEach(({ pos }, index) => {
960
- // decorations.push(
961
- // Decoration.widget(pos + 1, () => {
962
- // const colSelected = isColumnSelected(index)(selection);
963
- // let className = "grip-column";
964
- // if (colSelected) {
965
- // className += " selected";
966
- // }
967
- // if (index === 0) {
968
- // className += " first";
969
- // }
970
- // if (index === cells.length - 1) {
971
- // className += " last";
972
- // }
973
- // const grip = document.createElement("a");
974
- // grip.className = className;
975
- // grip.addEventListener("mousedown", (event) => {
976
- // event.preventDefault();
977
- // event.stopImmediatePropagation();
978
- // this.editor.view.dispatch(
979
- // selectColumn(index)(this.editor.state.tr),
980
- // );
981
- // });
982
- // return grip;
983
- // }),
984
- // );
985
- // });
986
- // }
987
- // return DecorationSet.create(doc, decorations);
988
- // },
989
- // },
990
- // }),
991
- // ];
992
- // },
993
724
  });
994
725
 
995
726
  // src/table-row.ts
996
727
  var import_extension_table3 = require("@tiptap/extension-table");
997
728
  var TableRow = import_extension_table3.TableRow.extend({
998
- content: "(tableCell | tableHeader)*"
729
+ content: "(tableCell | tableHeader)*",
730
+ addOptions() {
731
+ var _a;
732
+ return {
733
+ ...(_a = this.parent) == null ? void 0 : _a.call(this),
734
+ HTMLAttributes: {
735
+ class: "min-w-full"
736
+ }
737
+ };
738
+ }
999
739
  });
1000
740
 
1001
741
  // src/kit.ts
1002
- var TableKit = import_react.Extension.create({
742
+ var TableKit = import_react6.Extension.create({
1003
743
  name: "tableKit",
1004
744
  addExtensions() {
1005
745
  const extensions = [];