@ctzhian/tiptap 1.13.9 → 2.1.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 (83) hide show
  1. package/dist/Editor/demo.js +133 -123
  2. package/dist/Editor/index.js +17 -0
  3. package/dist/EditorToolbar/index.js +11 -9
  4. package/dist/asset/css/index.css +5 -7
  5. package/dist/component/ActionDropdown/index.d.ts +5 -0
  6. package/dist/component/ActionDropdown/index.js +8 -3
  7. package/dist/component/CustomBubbleMenu/index.js +1 -1
  8. package/dist/component/CustomDragHandle/index.js +3 -59
  9. package/dist/component/FloatingPopover/index.d.ts +2 -2
  10. package/dist/component/HoverPopover/index.d.ts +2 -0
  11. package/dist/component/HoverPopover/index.js +22 -3
  12. package/dist/component/Icons/delete-back-2-line-icon.d.ts +6 -0
  13. package/dist/component/Icons/delete-back-2-line-icon.js +13 -0
  14. package/dist/component/Icons/{expand-horizontal-line.js → expand-horizontal-line-icon.js} +1 -1
  15. package/dist/component/Icons/index.d.ts +3 -2
  16. package/dist/component/Icons/index.js +4 -3
  17. package/dist/component/Menu/index.js +5 -1
  18. package/dist/contants/enums.d.ts +9 -0
  19. package/dist/contants/enums.js +61 -1
  20. package/dist/extension/component/Alert/index.js +141 -137
  21. package/dist/extension/component/Flow/Edit.d.ts +1 -1
  22. package/dist/extension/component/Flow/Edit.js +3 -31
  23. package/dist/extension/component/Flow/index.js +20 -19
  24. package/dist/extension/component/Image/index.d.ts +1 -0
  25. package/dist/extension/component/Image/index.js +16 -2
  26. package/dist/extension/component/Link/index.js +1 -1
  27. package/dist/extension/component/TableCellHandleMenu/index.d.ts +9 -0
  28. package/dist/extension/component/TableCellHandleMenu/index.js +500 -0
  29. package/dist/extension/component/TableExtendButton/TableExtendButton.css +30 -0
  30. package/dist/extension/component/TableExtendButton/index.d.ts +23 -0
  31. package/dist/extension/component/TableExtendButton/index.js +201 -0
  32. package/dist/extension/component/TableExtendButton/use-table-extend-row-column.d.ts +15 -0
  33. package/dist/extension/component/TableExtendButton/use-table-extend-row-column.js +87 -0
  34. package/dist/extension/component/TableHandle/TableHandleMenu.css +36 -0
  35. package/dist/extension/component/TableHandle/TableHandleMenu.d.ts +17 -0
  36. package/dist/extension/component/TableHandle/TableHandleMenu.js +685 -0
  37. package/dist/extension/component/TableHandle/index.d.ts +28 -0
  38. package/dist/extension/component/TableHandle/index.js +93 -0
  39. package/dist/extension/component/TableHandle/use-table-handle-positioning.d.ts +40 -0
  40. package/dist/extension/component/TableHandle/use-table-handle-positioning.js +193 -0
  41. package/dist/extension/component/TableHandle/use-table-handle-state.d.ts +22 -0
  42. package/dist/extension/component/TableHandle/use-table-handle-state.js +45 -0
  43. package/dist/extension/component/TableSelectionOverlay/index.d.ts +16 -0
  44. package/dist/extension/component/TableSelectionOverlay/index.js +452 -0
  45. package/dist/extension/component/Video/Insert.js +4 -2
  46. package/dist/extension/component/Video/Readonly.js +4 -11
  47. package/dist/extension/component/Video/index.d.ts +2 -1
  48. package/dist/extension/component/Video/index.js +447 -65
  49. package/dist/extension/extension/ImeComposition.d.ts +2 -0
  50. package/dist/extension/extension/ImeComposition.js +145 -0
  51. package/dist/extension/extension/index.d.ts +1 -0
  52. package/dist/extension/extension/index.js +1 -0
  53. package/dist/extension/index.js +2 -2
  54. package/dist/extension/node/FileHandler.d.ts +1 -1
  55. package/dist/extension/node/Flow/index.d.ts +0 -3
  56. package/dist/extension/node/Flow/index.js +7 -4
  57. package/dist/extension/node/Link/index.js +4 -3
  58. package/dist/extension/node/Table.js +236 -117
  59. package/dist/extension/node/TableHandler/create-image.d.ts +9 -0
  60. package/dist/extension/node/TableHandler/create-image.js +235 -0
  61. package/dist/extension/node/TableHandler/index.d.ts +15 -0
  62. package/dist/extension/node/TableHandler/index.js +33 -0
  63. package/dist/extension/node/TableHandler/plugin.d.ts +49 -0
  64. package/dist/extension/node/TableHandler/plugin.js +1030 -0
  65. package/dist/extension/node/TableOfContents/index.d.ts +5 -3
  66. package/dist/extension/node/TableOfContents/index.js +22 -2
  67. package/dist/extension/node/Video.d.ts +1 -0
  68. package/dist/extension/node/Video.js +38 -6
  69. package/dist/hook/index.js +1 -1
  70. package/dist/index.css +45 -29
  71. package/dist/type/index.d.ts +2 -0
  72. package/dist/util/index.d.ts +9 -0
  73. package/dist/util/index.js +26 -0
  74. package/dist/util/table-utils.d.ts +161 -0
  75. package/dist/util/table-utils.js +605 -0
  76. package/package.json +2 -1
  77. package/dist/extension/component/Table/ContextMenu.d.ts +0 -11
  78. package/dist/extension/component/Table/ContextMenu.js +0 -186
  79. package/dist/extension/component/Table/TableContextMenuPlugin.d.ts +0 -9
  80. package/dist/extension/component/Table/TableContextMenuPlugin.js +0 -336
  81. package/dist/extension/component/Table/index.d.ts +0 -2
  82. package/dist/extension/component/Table/index.js +0 -2
  83. /package/dist/component/Icons/{expand-horizontal-line.d.ts → expand-horizontal-line-icon.d.ts} +0 -0
@@ -1,4 +1,6 @@
1
1
  import { TocList } from "../../../type";
2
- export declare const TableOfContentsExtension: ({ onTocUpdate }: {
3
- onTocUpdate?: ((toc: TocList) => void) | undefined;
4
- }) => import("@tiptap/core").Extension<import("@tiptap/extension-table-of-contents").TableOfContentsOptions, import("@tiptap/extension-table-of-contents").TableOfContentsStorage>;
2
+ interface TableOfContentsOptions {
3
+ onTocUpdate?: (toc: TocList) => void;
4
+ }
5
+ export declare const TableOfContentsExtension: ({ onTocUpdate }: TableOfContentsOptions) => import("@tiptap/core").Extension<import("@tiptap/extension-table-of-contents").TableOfContentsOptions, import("@tiptap/extension-table-of-contents").TableOfContentsStorage>;
6
+ export {};
@@ -1,7 +1,27 @@
1
1
  import { getHierarchicalIndexes, TableOfContents } from '@tiptap/extension-table-of-contents';
2
+ import { Plugin, PluginKey } from '@tiptap/pm/state';
2
3
  export var TableOfContentsExtension = function TableOfContentsExtension(_ref) {
3
4
  var onTocUpdate = _ref.onTocUpdate;
4
- return TableOfContents.configure({
5
+ return TableOfContents.extend({
6
+ addProseMirrorPlugins: function addProseMirrorPlugins() {
7
+ var imeCompositionPluginKey = new PluginKey('imeComposition');
8
+ return [new Plugin({
9
+ key: new PluginKey('tableOfContentImeFix'),
10
+ appendTransaction: function appendTransaction(transactions, _oldState, newState) {
11
+ if (transactions.some(function (tr) {
12
+ return tr.getMeta('composition');
13
+ })) {
14
+ return null;
15
+ }
16
+ var imePluginState = imeCompositionPluginKey.getState(newState);
17
+ if (imePluginState !== null && imePluginState !== void 0 && imePluginState.isComposing) {
18
+ return null;
19
+ }
20
+ return null;
21
+ }
22
+ })];
23
+ }
24
+ }).configure({
5
25
  getIndex: getHierarchicalIndexes,
6
26
  onUpdate: function onUpdate(data) {
7
27
  setTimeout(function () {
@@ -17,7 +37,7 @@ export var TableOfContentsExtension = function TableOfContentsExtension(_ref) {
17
37
  textContent: content.textContent
18
38
  };
19
39
  }));
20
- }, 0);
40
+ }, 60);
21
41
  }
22
42
  });
23
43
  };
@@ -9,6 +9,7 @@ declare module '@tiptap/core' {
9
9
  setVideo: (options: {
10
10
  src: string;
11
11
  width?: number;
12
+ align?: 'left' | 'center' | 'right';
12
13
  controls?: boolean;
13
14
  autoplay?: boolean;
14
15
  loop?: boolean;
@@ -107,16 +107,33 @@ export var VideoExtension = function VideoExtension(props) {
107
107
  }
108
108
  },
109
109
  width: {
110
- default: 760,
110
+ default: null,
111
111
  parseHTML: function parseHTML(element) {
112
112
  var width = element.getAttribute('width');
113
- return width ? parseInt(width, 10) : 760;
113
+ if (width) {
114
+ if (width.endsWith('%')) return width;
115
+ var numWidth = parseInt(width, 10);
116
+ return isNaN(numWidth) ? null : numWidth;
117
+ }
118
+ return null;
114
119
  },
115
120
  renderHTML: function renderHTML(attributes) {
116
121
  return {
117
122
  width: attributes.width
118
123
  };
119
124
  }
125
+ },
126
+ align: {
127
+ default: null,
128
+ parseHTML: function parseHTML(element) {
129
+ return element.getAttribute('data-align');
130
+ },
131
+ renderHTML: function renderHTML(attributes) {
132
+ if (!attributes.align) return {};
133
+ return {
134
+ 'data-align': attributes.align
135
+ };
136
+ }
120
137
  }
121
138
  };
122
139
  },
@@ -127,6 +144,18 @@ export var VideoExtension = function VideoExtension(props) {
127
144
  if (!(dom instanceof HTMLElement)) return false;
128
145
  var src = dom.getAttribute('src');
129
146
  if (!src) return false;
147
+ var widthAttr = dom.getAttribute('width');
148
+ var width = 760;
149
+ if (widthAttr) {
150
+ // 如果是百分比,保留字符串格式
151
+ if (widthAttr.endsWith('%')) {
152
+ width = widthAttr;
153
+ } else {
154
+ // 否则解析为数字
155
+ var numWidth = parseInt(widthAttr, 10);
156
+ width = isNaN(numWidth) ? 760 : numWidth;
157
+ }
158
+ }
130
159
  return {
131
160
  src: src,
132
161
  controls: dom.hasAttribute('controls'),
@@ -134,7 +163,8 @@ export var VideoExtension = function VideoExtension(props) {
134
163
  loop: dom.hasAttribute('loop'),
135
164
  muted: dom.hasAttribute('muted'),
136
165
  poster: dom.getAttribute('poster'),
137
- width: dom.getAttribute('width') ? parseInt(dom.getAttribute('width'), 10) : 760
166
+ width: width,
167
+ align: dom.getAttribute('data-align') || dom.getAttribute('align')
138
168
  };
139
169
  }
140
170
  }];
@@ -151,9 +181,10 @@ export var VideoExtension = function VideoExtension(props) {
151
181
  autoplay = _ref2.autoplay,
152
182
  loop = _ref2.loop,
153
183
  muted = _ref2.muted,
154
- poster = _ref2.poster;
184
+ poster = _ref2.poster,
185
+ align = _ref2['data-align'];
155
186
  if (!src) return '';
156
- return "<video src=\"".concat(src, "\" ").concat(width ? "width=\"".concat(width, "\"") : '', " ").concat(controls ? 'controls' : '', " ").concat(autoplay ? 'autoplay' : '', " ").concat(loop ? 'loop' : '', " ").concat(muted ? 'muted' : '', " ").concat(poster ? "poster=\"".concat(poster, "\"") : '', "></video>");
187
+ return "<video src=\"".concat(src, "\" ").concat(width ? "width=\"".concat(width, "\"") : '', " ").concat(controls ? 'controls' : '', " ").concat(autoplay ? 'autoplay' : '', " ").concat(loop ? 'loop' : '', " ").concat(muted ? 'muted' : '', " ").concat(poster ? "poster=\"".concat(poster, "\"") : '', " ").concat(align ? "data-align=\"".concat(align, "\"") : '', "></video>");
157
188
  },
158
189
  addCommands: function addCommands() {
159
190
  var _this2 = this;
@@ -170,7 +201,8 @@ export var VideoExtension = function VideoExtension(props) {
170
201
  autoplay: options.autoplay || false,
171
202
  loop: options.loop || false,
172
203
  muted: options.muted || false,
173
- poster: options.poster || null
204
+ poster: options.poster || null,
205
+ align: options.align || null
174
206
  }
175
207
  });
176
208
  };
@@ -50,7 +50,7 @@ var useTiptap = function useTiptap(_ref) {
50
50
  editorProps: {
51
51
  handleKeyDown: function handleKeyDown(view, event) {
52
52
  // 编辑模式下保存
53
- if (event.key === 's' && (event.metaKey || event.ctrlKey) && editable) {
53
+ if (event.key === 's' && (event.metaKey || event.ctrlKey) && editable && onSave) {
54
54
  event.preventDefault();
55
55
  onSave === null || onSave === void 0 || onSave(editor);
56
56
  return true;
package/dist/index.css CHANGED
@@ -2,15 +2,16 @@
2
2
 
3
3
  :root {
4
4
  --common-row-font-size: 16px;
5
- --common-row-line-height: 26px;
5
+ --common-row-line-height: 1.625;
6
6
  --udtoken-quote-bar-bg: #bbbfc4;
7
7
  }
8
8
 
9
9
  .tiptap.ProseMirror {
10
10
  overflow-y: auto;
11
11
  outline: none;
12
+ font-size: var(--common-row-font-size);
12
13
  color: var(--mui-palette-text-primary);
13
- line-height: 1.8;
14
+ line-height: var(--common-row-line-height);
14
15
  }
15
16
 
16
17
  /* 节点缩进(依赖 data-indent 属性) */
@@ -59,17 +60,13 @@
59
60
  }
60
61
 
61
62
  .tiptap.ProseMirror p {
62
- line-height: var(--common-row-line-height);
63
- font-size: var(--common-row-font-size);
64
63
  margin: 8px 0;
65
64
  }
66
65
 
67
- /* blockquote */
68
66
  .tiptap.ProseMirror blockquote {
69
67
  position: relative;
70
68
  padding: 8px 16px 8px 24px;
71
69
  margin: 8px 0;
72
- line-height: var(--common-row-line-height);
73
70
  color: var(--mui-palette-text-tertiary);
74
71
  background-color: var(--mui-palette-background-paper3);
75
72
  }
@@ -111,8 +108,6 @@
111
108
  top: 0;
112
109
  left: -24px;
113
110
  content: counter(list-counter) '.' !important;
114
- font-size: 16px;
115
- line-height: 26px;
116
111
  color: var(--mui-palette-primary-main);
117
112
  }
118
113
 
@@ -146,8 +141,6 @@
146
141
  position: absolute;
147
142
  top: 0;
148
143
  left: -24px;
149
- font-size: 16px;
150
- line-height: 26px;
151
144
  font-size: 20px;
152
145
  color: var(--mui-palette-primary-main);
153
146
  }
@@ -223,7 +216,6 @@
223
216
  .tiptap.ProseMirror pre {
224
217
  position: relative;
225
218
  border: 1px solid;
226
- line-height: 22px;
227
219
  border-color: var(--mui-palette-divider);
228
220
  border-radius: var(--mui-shape-borderRadius);
229
221
  color: var(--mui-palette-text-tertiary);
@@ -240,8 +232,6 @@
240
232
  .tiptap.ProseMirror code {
241
233
  padding: 2px 8px;
242
234
  margin: 0 4px;
243
- line-height: 1.625;
244
- font-size: inherit;
245
235
  word-break: break-all;
246
236
  /* font-weight: 500; */
247
237
  border: 1px solid;
@@ -269,7 +259,6 @@
269
259
  .tiptap.ProseMirror .cq-details {
270
260
  display: flex;
271
261
  gap: 0.25rem;
272
- line-height: 1.625;
273
262
  margin: 20px 0;
274
263
  border: 1px solid var(--mui-palette-divider);
275
264
  border-radius: var(--mui-shape-borderRadius);
@@ -355,7 +344,6 @@
355
344
  position: relative;
356
345
  color: inherit;
357
346
  font-style: inherit;
358
- line-height: 1.4;
359
347
  font-weight: 500;
360
348
  }
361
349
 
@@ -410,7 +398,6 @@
410
398
 
411
399
  .tiptap.ProseMirror table p {
412
400
  font-size: 14px;
413
- line-height: 24px;
414
401
  }
415
402
 
416
403
  .tiptap.ProseMirror table th *,
@@ -418,7 +405,6 @@
418
405
  word-break: break-all;
419
406
  }
420
407
 
421
- /* 表格单元格基础样式 */
422
408
  .tiptap.ProseMirror table td,
423
409
  .tiptap.ProseMirror table th {
424
410
  border: none;
@@ -441,12 +427,12 @@
441
427
  margin-bottom: 0;
442
428
  }
443
429
 
444
- /* 表格表头样式 */
445
430
  .tiptap.ProseMirror table th {
446
431
  font-weight: 600;
447
432
  text-transform: uppercase;
448
433
  letter-spacing: 0.5px;
449
434
  text-align: left;
435
+ background-color: var(--mui-palette-background-paper3);
450
436
  }
451
437
 
452
438
  .tiptap.ProseMirror[contenteditable="true"] table .selectedCell * {
@@ -454,9 +440,8 @@
454
440
  user-select: none;
455
441
  }
456
442
 
457
- /* 表格选择状态 */
458
443
  .tiptap.ProseMirror[contenteditable="true"] table .selectedCell:after {
459
- background-color: color-mix(in srgb, var(--mui-palette-primary-main) 12%, transparent);
444
+ background-color: color-mix(in srgb, var(--mui-palette-primary-main) 5%, transparent);
460
445
  content: '';
461
446
  left: 0;
462
447
  right: 0;
@@ -467,7 +452,6 @@
467
452
  z-index: 2;
468
453
  }
469
454
 
470
- /* 表格列调整手柄 */
471
455
  .tiptap.ProseMirror[contenteditable="true"] table .column-resize-handle {
472
456
  border-right: 2px dotted var(--mui-palette-primary-main);
473
457
  bottom: -2px;
@@ -481,18 +465,54 @@
481
465
  transition: all 0.2s ease-in-out;
482
466
  }
483
467
 
468
+ .tiptap-table-dropcursor {
469
+ position: absolute !important;
470
+ z-index: 20;
471
+ pointer-events: none;
472
+ background-color: var(--mui-palette-primary-main, #1976d2);
473
+ }
474
+
484
475
  .tiptap.ProseMirror.resize-cursor {
485
476
  cursor: col-resize;
486
477
  }
487
478
 
488
- /* 表格包装器样式 */
489
479
  .tiptap.ProseMirror .tableWrapper {
490
480
  width: 100%;
491
481
  overflow-x: auto;
482
+ overflow-y: hidden;
483
+ position: relative;
492
484
  margin: 20px 0;
493
485
  }
494
486
 
495
- /* 表格滚动条样式 */
487
+ .tiptap.ProseMirror[contenteditable="true"] .tableWrapper {
488
+ padding-top: 16px;
489
+ padding-left: 16px;
490
+ padding-bottom: 16px;
491
+ padding-right: 16px;
492
+ }
493
+
494
+ .tiptap.ProseMirror .table-controls {
495
+ position: relative;
496
+ overflow: visible;
497
+ pointer-events: none;
498
+ z-index: 10;
499
+ }
500
+
501
+ .tiptap.ProseMirror .table-controls>* {
502
+ pointer-events: auto;
503
+ }
504
+
505
+ .tiptap.ProseMirror .table-selection-overlay-container {
506
+ position: relative;
507
+ overflow: visible;
508
+ pointer-events: none;
509
+ z-index: 10;
510
+ }
511
+
512
+ .tiptap.ProseMirror .table-selection-overlay-container>* {
513
+ pointer-events: auto;
514
+ }
515
+
496
516
  .tiptap.ProseMirror .tableWrapper::-webkit-scrollbar {
497
517
  height: 5px;
498
518
  cursor: pointer;
@@ -510,7 +530,6 @@
510
530
  cursor: pointer;
511
531
  }
512
532
 
513
- /* youtube */
514
533
  .tiptap.ProseMirror div[data-youtube-video] {
515
534
  cursor: move;
516
535
  padding-right: 1.5rem;
@@ -537,21 +556,19 @@
537
556
  }
538
557
  }
539
558
 
540
- .slash-decoration[data-decoration-content].is-empty {
559
+ .tiptap.ProseMirror .slash-decoration[data-decoration-content].is-empty {
541
560
  padding: 4px 8px;
542
561
  background-color: var(--mui-palette-background-paper2);
543
562
  border-radius: var(--mui-shape-borderRadius);
544
563
  }
545
564
 
546
- .slash-decoration[data-decoration-content].is-empty::after {
565
+ .tiptap.ProseMirror .slash-decoration[data-decoration-content].is-empty::after {
547
566
  content: attr(data-decoration-content);
548
567
  color: var(--mui-palette-text-disabled);
549
568
  padding-left: 0.25rem;
550
569
  font-size: 14px;
551
- line-height: 24px;
552
570
  }
553
571
 
554
- /* AI 续写建议样式 */
555
572
  .tiptap.ProseMirror .ai-writing-suggestion {
556
573
  color: color-mix(in srgb, var(--mui-palette-text-primary) 15%, transparent);
557
574
  pointer-events: none;
@@ -559,7 +576,6 @@
559
576
  white-space: pre-wrap;
560
577
  }
561
578
 
562
- /* placeholder */
563
579
  .tiptap.ProseMirror .cq-details[data-placeholder]::before,
564
580
  .tiptap.ProseMirror table *[data-placeholder]::before,
565
581
  .tiptap.ProseMirror li p[data-placeholder]::before {
@@ -37,6 +37,8 @@ export interface MenuProps {
37
37
  transformOrigin?: PopoverOrigin;
38
38
  };
39
39
  zIndex?: number;
40
+ onOpen?: () => void;
41
+ onClose?: () => void;
40
42
  }
41
43
  export type ToolbarItemType = {
42
44
  id: string;
@@ -13,3 +13,12 @@ export declare const hasMarksInBlock: (node: Node | null | undefined) => boolean
13
13
  export declare const hasMarksInSelection: (state: EditorState) => boolean;
14
14
  export declare function addOpacityToColor(color: string, opacity: number): string;
15
15
  export declare const getLinkTitle: (href: string) => string;
16
+ /**
17
+ * 获取当前选中文本并返回链接属性
18
+ * 如果有选中文本,将文本设置为 title
19
+ * @param editor Tiptap 编辑器实例
20
+ * @returns 包含 title 的链接属性对象(如果有选中文本)
21
+ */
22
+ export declare const getLinkAttributesWithSelectedText: (editor: Editor) => {
23
+ title?: string;
24
+ };
@@ -62,4 +62,30 @@ export var getLinkTitle = function getLinkTitle(href) {
62
62
  return it.trim().length > 0;
63
63
  });
64
64
  return paths[paths.length - 1];
65
+ };
66
+
67
+ /**
68
+ * 获取当前选中文本并返回链接属性
69
+ * 如果有选中文本,将文本设置为 title
70
+ * @param editor Tiptap 编辑器实例
71
+ * @returns 包含 title 的链接属性对象(如果有选中文本)
72
+ */
73
+ export var getLinkAttributesWithSelectedText = function getLinkAttributesWithSelectedText(editor) {
74
+ if (!editor) {
75
+ return {};
76
+ }
77
+ var selection = editor.state.selection;
78
+ var from = selection.from,
79
+ to = selection.to;
80
+ if (selection.empty || from === to) {
81
+ return {};
82
+ }
83
+ var selectedText = editor.state.doc.textBetween(from, to, '');
84
+ var trimmedText = selectedText.trim();
85
+ if (trimmedText.length > 0) {
86
+ return {
87
+ title: trimmedText
88
+ };
89
+ }
90
+ return {};
65
91
  };
@@ -0,0 +1,161 @@
1
+ import type { Node } from '@tiptap/pm/model';
2
+ import { type EditorState, type Transaction } from '@tiptap/pm/state';
3
+ import type { FindNodeResult } from '@tiptap/pm/tables';
4
+ import { TableMap } from '@tiptap/pm/tables';
5
+ import type { Editor } from '@tiptap/react';
6
+ export declare const RESIZE_MIN_WIDTH = 35;
7
+ export declare const EMPTY_CELL_WIDTH = 120;
8
+ export declare const EMPTY_CELL_HEIGHT = 40;
9
+ export type Orientation = 'row' | 'column';
10
+ export interface CellInfo extends FindNodeResult {
11
+ row: number;
12
+ column: number;
13
+ }
14
+ export type CellCoordinates = {
15
+ row: number;
16
+ col: number;
17
+ };
18
+ export type SelectionReturnMode = 'state' | 'transaction' | 'dispatch';
19
+ export type BaseSelectionOptions = {
20
+ mode?: SelectionReturnMode;
21
+ };
22
+ export type DispatchSelectionOptions = {
23
+ mode: 'dispatch';
24
+ dispatch: (tr: Transaction) => void;
25
+ };
26
+ export type TransactionSelectionOptions = {
27
+ mode: 'transaction';
28
+ };
29
+ export type StateSelectionOptions = {
30
+ mode?: 'state';
31
+ };
32
+ export type TableInfo = {
33
+ map: TableMap;
34
+ } & FindNodeResult;
35
+ export declare function isHTMLElement(n: unknown): n is HTMLElement;
36
+ export type DomCellAroundResult = {
37
+ type: 'cell';
38
+ domNode: HTMLElement;
39
+ tbodyNode: HTMLTableSectionElement | null;
40
+ } | {
41
+ type: 'wrapper';
42
+ domNode: HTMLElement;
43
+ tbodyNode: HTMLTableSectionElement | null;
44
+ };
45
+ export declare function safeClosest<T extends Element>(start: Element | null, selector: string): T | null;
46
+ /**
47
+ * Walk up from an element until we find a TD/TH or the table wrapper.
48
+ * Returns the found element plus its tbody (if present).
49
+ */
50
+ export declare function domCellAround(target: Element): DomCellAroundResult | undefined;
51
+ /**
52
+ * Clamps a value between min and max bounds
53
+ */
54
+ export declare function clamp(value: number, min: number, max: number): number;
55
+ /**
56
+ * Checks if a cell is merged (has colspan or rowspan > 1)
57
+ */
58
+ export declare function isCellMerged(node: Node | null): boolean;
59
+ /**
60
+ * Get information about the table at the current selection or a specific position.
61
+ */
62
+ export declare function getTable(editor: Editor | null, tablePos?: number): {
63
+ map: TableMap;
64
+ node: Node;
65
+ pos: number;
66
+ start: number;
67
+ depth: number;
68
+ } | null;
69
+ /**
70
+ * Checks if the current text selection is inside a table cell.
71
+ */
72
+ export declare function isSelectionInCell(state: EditorState): boolean;
73
+ /**
74
+ * Runs a function while preserving the editor's selection.
75
+ */
76
+ export declare function runPreservingCursor(editor: Editor, fn: () => void): boolean;
77
+ /**
78
+ * Determines whether a table cell is effectively empty.
79
+ */
80
+ export declare function isCellEmpty(cellNode: Node): boolean;
81
+ /**
82
+ * Counts how many consecutive empty rows exist at the bottom of a given table.
83
+ */
84
+ export declare function countEmptyRowsFromEnd(editor: Editor, tablePos: number): number;
85
+ /**
86
+ * Counts how many consecutive empty columns exist at the right edge of a given table.
87
+ */
88
+ export declare function countEmptyColumnsFromEnd(editor: Editor, tablePos: number): number;
89
+ /**
90
+ * Rounds a number with a symmetric "dead-zone" around integer boundaries.
91
+ */
92
+ export declare function marginRound(num: number, margin?: number): number;
93
+ /**
94
+ * Selects table cells by their (row, col) coordinates.
95
+ */
96
+ export declare function selectCellsByCoords(editor: Editor | null, tablePos: number, coords: {
97
+ row: number;
98
+ col: number;
99
+ }[], options?: BaseSelectionOptions | DispatchSelectionOptions): EditorState | Transaction | void;
100
+ /**
101
+ * Select the cell at (row, col) using `cellAround` to respect merged cells.
102
+ */
103
+ export declare function selectCellAt({ editor, row, col, tablePos, dispatch, }: {
104
+ editor: Editor | null;
105
+ row: number;
106
+ col: number;
107
+ tablePos?: number;
108
+ dispatch?: (tr: Transaction) => void;
109
+ }): boolean;
110
+ /**
111
+ * Selects a boundary cell of the table based on orientation.
112
+ */
113
+ export declare function selectLastCell(editor: Editor, tableNode: Node, tablePos: number, orientation: Orientation): boolean;
114
+ /**
115
+ * Get all (row, col) coordinates for a given row or column index.
116
+ */
117
+ export declare function getIndexCoordinates({ editor, index, orientation, tablePos, }: {
118
+ editor: Editor | null;
119
+ index: number;
120
+ orientation?: Orientation;
121
+ tablePos?: number;
122
+ }): {
123
+ row: number;
124
+ col: number;
125
+ }[] | null;
126
+ /**
127
+ * Given a DOM cell element, find its (row, col) indices within the table.
128
+ */
129
+ export declare function getCellIndicesFromDOM(cell: HTMLTableCellElement, tableNode: Node | null, editor: Editor): {
130
+ rowIndex: number;
131
+ colIndex: number;
132
+ } | null;
133
+ /**
134
+ * Given a DOM element inside a table, find the corresponding table node and its position.
135
+ */
136
+ export declare function getTableFromDOM(tableElement: HTMLElement, editor: Editor): {
137
+ node: Node;
138
+ pos: number;
139
+ } | null;
140
+ /**
141
+ * Checks if a node is a table node
142
+ */
143
+ export declare function isTableNode(node: Node | null | undefined): node is Node;
144
+ /**
145
+ * Get all cells (and unique merged cells) from a specific row.
146
+ */
147
+ export declare function getRowCells(editor: Editor | null, rowIndex?: number, tablePos?: number): {
148
+ cells: CellInfo[];
149
+ mergedCells: CellInfo[];
150
+ };
151
+ /**
152
+ * Collect cells (and unique merged cells) from the current table.
153
+ */
154
+ export declare function getColumnCells(editor: Editor | null, columnIndex?: number, tablePos?: number): {
155
+ cells: CellInfo[];
156
+ mergedCells: CellInfo[];
157
+ };
158
+ /**
159
+ * Compare two DOMRects for equality (within a small tolerance)
160
+ */
161
+ export declare function rectEq(rect1: DOMRect | null, rect2: DOMRect | null): boolean;