quill-table-up 2.4.2 → 3.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 (66) hide show
  1. package/README.md +96 -40
  2. package/dist/index.css +1 -1
  3. package/dist/index.d.ts +172 -110
  4. package/dist/index.js +29 -28
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.umd.js +29 -28
  7. package/dist/index.umd.js.map +1 -1
  8. package/dist/table-creator.css +1 -1
  9. package/package.json +1 -1
  10. package/src/__tests__/e2e/table-align.test.ts +1 -2
  11. package/src/__tests__/e2e/table-blots.test.ts +45 -35
  12. package/src/__tests__/e2e/table-clipboard.test.ts +20 -0
  13. package/src/__tests__/e2e/table-hack.test.ts +5 -5
  14. package/src/__tests__/e2e/table-keyboard-handler.test.ts +6 -6
  15. package/src/__tests__/e2e/table-menu.test.ts +23 -0
  16. package/src/__tests__/e2e/table-selection.test.ts +3 -3
  17. package/src/__tests__/unit/table-blots.test.ts +26 -26
  18. package/src/__tests__/unit/table-caption.test.ts +33 -36
  19. package/src/__tests__/unit/table-cell-merge.test.ts +114 -114
  20. package/src/__tests__/unit/table-clipboard.test.ts +383 -19
  21. package/src/__tests__/unit/table-hack.test.ts +202 -144
  22. package/src/__tests__/unit/table-insert.test.ts +79 -79
  23. package/src/__tests__/unit/table-redo-undo.test.ts +495 -64
  24. package/src/__tests__/unit/table-remove.test.ts +8 -11
  25. package/src/__tests__/unit/utils.test.ts +4 -4
  26. package/src/__tests__/unit/utils.ts +4 -3
  27. package/src/formats/container-format.ts +25 -2
  28. package/src/formats/index.ts +54 -8
  29. package/src/formats/overrides/block.ts +35 -30
  30. package/src/formats/table-body-format.ts +18 -58
  31. package/src/formats/table-cell-format.ts +296 -286
  32. package/src/formats/table-cell-inner-format.ts +384 -358
  33. package/src/formats/table-foot-format.ts +7 -0
  34. package/src/formats/table-head-format.ts +7 -0
  35. package/src/formats/table-main-format.ts +84 -5
  36. package/src/formats/table-row-format.ts +44 -14
  37. package/src/modules/index.ts +1 -0
  38. package/src/modules/table-align.ts +59 -53
  39. package/src/modules/table-clipboard.ts +60 -39
  40. package/src/modules/table-dom-selector.ts +33 -0
  41. package/src/modules/table-menu/constants.ts +21 -31
  42. package/src/modules/table-menu/table-menu-common.ts +72 -51
  43. package/src/modules/table-menu/table-menu-contextmenu.ts +22 -6
  44. package/src/modules/table-menu/table-menu-select.ts +75 -12
  45. package/src/modules/table-resize/table-resize-box.ts +148 -128
  46. package/src/modules/table-resize/table-resize-common.ts +37 -32
  47. package/src/modules/table-resize/table-resize-line.ts +53 -36
  48. package/src/modules/table-resize/table-resize-scale.ts +32 -27
  49. package/src/modules/table-scrollbar.ts +58 -32
  50. package/src/modules/table-selection.ts +102 -79
  51. package/src/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  52. package/src/style/index.less +0 -1
  53. package/src/style/select-box.less +1 -0
  54. package/src/style/table-menu.less +4 -4
  55. package/src/style/table-resize.less +1 -0
  56. package/src/style/table-scrollbar.less +2 -2
  57. package/src/table-up.ts +161 -194
  58. package/src/utils/components/table/creator.ts +4 -1
  59. package/src/utils/components/tooltip.ts +6 -1
  60. package/src/utils/constants.ts +8 -2
  61. package/src/utils/index.ts +2 -1
  62. package/src/utils/scroll.ts +47 -0
  63. package/src/utils/style-helper.ts +47 -0
  64. package/src/utils/transformer.ts +0 -25
  65. package/src/utils/types.ts +15 -15
  66. package/src/utils/scroll-event-helper.ts +0 -22
@@ -28,7 +28,7 @@ export const tableMenuTools: Record<string, Tool> = {
28
28
  name: 'CopyCell',
29
29
  tip: 'Copy cell',
30
30
  icon: Copy,
31
- handle: (tableModule, selectedTds) => {
31
+ handle(tableModule, selectedTds) {
32
32
  const text = tableModule.getTextByCell(selectedTds);
33
33
  const html = tableModule.getHTMLByCell(selectedTds);
34
34
 
@@ -37,14 +37,13 @@ export const tableMenuTools: Record<string, Tool> = {
37
37
  'text/html': new Blob([html], { type: 'text/html' }),
38
38
  });
39
39
  navigator.clipboard.write([clipboardItem]);
40
- tableModule.hideTableTools();
41
40
  },
42
41
  },
43
42
  CutCell: {
44
43
  name: 'CutCell',
45
44
  tip: 'Cut cell',
46
45
  icon: Cut,
47
- handle: (tableModule, selectedTds) => {
46
+ handle(tableModule, selectedTds) {
48
47
  const text = tableModule.getTextByCell(selectedTds);
49
48
  const html = tableModule.getHTMLByCell(selectedTds, true);
50
49
 
@@ -53,86 +52,77 @@ export const tableMenuTools: Record<string, Tool> = {
53
52
  'text/html': new Blob([html], { type: 'text/html' }),
54
53
  });
55
54
  navigator.clipboard.write([clipboardItem]);
56
- tableModule.hideTableTools();
57
55
  },
58
56
  },
59
57
  InsertTop: {
60
58
  name: 'InsertTop',
61
59
  icon: InsertTop,
62
60
  tip: 'Insert row above',
63
- handle: (tableModule, selectedTds) => {
61
+ handle(tableModule, selectedTds) {
64
62
  tableModule.appendRow(selectedTds, false);
65
- tableModule.hideTableTools();
66
63
  },
67
64
  },
68
65
  InsertRight: {
69
66
  name: 'InsertRight',
70
67
  icon: InsertRight,
71
68
  tip: 'Insert column right',
72
- handle: (tableModule, selectedTds) => {
69
+ handle(tableModule, selectedTds) {
73
70
  tableModule.appendCol(selectedTds, true);
74
- tableModule.hideTableTools();
75
71
  },
76
72
  },
77
73
  InsertBottom: {
78
74
  name: 'InsertBottom',
79
75
  icon: InsertBottom,
80
76
  tip: 'Insert row below',
81
- handle: (tableModule, selectedTds) => {
77
+ handle(tableModule, selectedTds) {
82
78
  tableModule.appendRow(selectedTds, true);
83
- tableModule.hideTableTools();
84
79
  },
85
80
  },
86
81
  InsertLeft: {
87
82
  name: 'InsertLeft',
88
83
  icon: InsertLeft,
89
84
  tip: 'Insert column Left',
90
- handle: (tableModule, selectedTds) => {
85
+ handle(tableModule, selectedTds) {
91
86
  tableModule.appendCol(selectedTds, false);
92
- tableModule.hideTableTools();
93
87
  },
94
88
  },
95
89
  MergeCell: {
96
90
  name: 'MergeCell',
97
91
  icon: MergeCell,
98
92
  tip: 'Merge Cell',
99
- handle: (tableModule, selectedTds) => {
93
+ handle(tableModule, selectedTds) {
100
94
  tableModule.mergeCells(selectedTds);
101
- tableModule.hideTableTools();
102
95
  },
103
96
  },
104
97
  SplitCell: {
105
98
  name: 'SplitCell',
106
99
  icon: SplitCell,
107
100
  tip: 'Split Cell',
108
- handle: (tableModule, selectedTds) => {
101
+ handle(tableModule, selectedTds) {
109
102
  tableModule.splitCell(selectedTds);
110
- tableModule.hideTableTools();
111
103
  },
112
104
  },
113
105
  DeleteRow: {
114
106
  name: 'DeleteRow',
115
107
  icon: RemoveRow,
116
108
  tip: 'Delete Row',
117
- handle: (tableModule, selectedTds) => {
109
+ handle(tableModule, selectedTds) {
118
110
  tableModule.removeRow(selectedTds);
119
- tableModule.hideTableTools();
120
111
  },
121
112
  },
122
113
  DeleteColumn: {
123
114
  name: 'DeleteColumn',
124
115
  icon: RemoveColumn,
125
116
  tip: 'Delete Column',
126
- handle: (tableModule, selectedTds) => {
117
+ handle(tableModule, selectedTds) {
127
118
  tableModule.removeCol(selectedTds);
128
- tableModule.hideTableTools();
129
119
  },
130
120
  },
131
121
  DeleteTable: {
132
122
  name: 'DeleteTable',
133
123
  icon: RemoveTable,
134
124
  tip: 'Delete table',
135
- handle: (tableModule, selectedTds) => {
125
+ handle(tableModule, selectedTds) {
136
126
  tableModule.deleteTable(selectedTds);
137
127
  },
138
128
  },
@@ -142,7 +132,7 @@ export const tableMenuTools: Record<string, Tool> = {
142
132
  isColorChoose: true,
143
133
  tip: 'Set background color',
144
134
  key: 'background-color',
145
- handle: (tableModule, selectedTds, color) => {
135
+ handle(tableModule, selectedTds, color) {
146
136
  tableModule.setCellAttrs(selectedTds, 'background-color', color, true);
147
137
  },
148
138
  },
@@ -152,7 +142,7 @@ export const tableMenuTools: Record<string, Tool> = {
152
142
  isColorChoose: true,
153
143
  tip: 'Set border color',
154
144
  key: 'border-color',
155
- handle: (tableModule, selectedTds, color) => {
145
+ handle(tableModule, selectedTds, color) {
156
146
  tableModule.setCellAttrs(selectedTds, 'border-color', color, true);
157
147
  },
158
148
  },
@@ -160,9 +150,9 @@ export const tableMenuTools: Record<string, Tool> = {
160
150
  name: 'SwitchWidth',
161
151
  icon: AutoFull,
162
152
  tip: 'Switch table width',
163
- handle: (tableModule) => {
164
- if (!tableModule.table) return;
165
- const tableMainBlot = Quill.find(tableModule.table) as TableMainFormat;
153
+ handle() {
154
+ if (!this.table) return;
155
+ const tableMainBlot = Quill.find(this.table) as TableMainFormat;
166
156
  if (!tableMainBlot) return;
167
157
 
168
158
  if (tableMainBlot.full) {
@@ -177,12 +167,12 @@ export const tableMenuTools: Record<string, Tool> = {
177
167
  name: 'InsertCaption',
178
168
  icon: TableHead,
179
169
  tip: 'Insert table caption',
180
- handle: (tableModule) => {
181
- if (!tableModule.table) return;
182
- const tableMainBlot = Quill.find(tableModule.table) as TableMainFormat;
170
+ handle() {
171
+ if (!this.table) return;
172
+ const tableMainBlot = Quill.find(this.table) as TableMainFormat;
183
173
  if (!tableMainBlot) return;
184
174
 
185
- const tableCaption = tableModule.quill.scroll.create('text', 'Table Caption').wrap(blotName.tableCaption, {
175
+ const tableCaption = this.quill.scroll.create('text', 'Table Caption').wrap(blotName.tableCaption, {
186
176
  tableId: tableMainBlot.tableId,
187
177
  });
188
178
  tableMainBlot.insertBefore(tableCaption, tableMainBlot.children.head);
@@ -192,7 +182,7 @@ export const tableMenuTools: Record<string, Tool> = {
192
182
  name: 'ToggleTdBetweenTh',
193
183
  icon: ConvertCell,
194
184
  tip: 'Toggle td between th',
195
- handle: (tableModule, selectedTds) => {
185
+ handle(tableModule, selectedTds) {
196
186
  for (const td of selectedTds) {
197
187
  td.convertTableCell();
198
188
  }
@@ -1,20 +1,23 @@
1
1
  import type { TableUp } from '../../table-up';
2
2
  import type { TableMenuOptions, ToolOption, TooltipInstance, ToolTipOptions } from '../../utils';
3
+ import type { TableSelection } from '../table-selection';
3
4
  import Quill from 'quill';
4
- import { createBEM, createColorPicker, createTooltip, debounce, defaultColorMap, isArray, isFunction, randomId } from '../../utils';
5
+ import { createBEM, createColorPicker, createTooltip, debounce, defaultColorMap, isArray, isFunction, randomId, tableUpEvent } from '../../utils';
6
+ import { TableDomSelector } from '../table-dom-selector';
5
7
  import { colorClassName, maxSaveColorCount, menuColorSelectClassName, tableMenuTools } from './constants';
6
8
 
7
9
  export type TableMenuOptionsInput = Partial<Omit<TableMenuOptions, 'texts'>>;
8
10
  export interface MenuTooltipInstance extends TooltipInstance {
9
11
  isColorPick?: boolean;
10
12
  }
11
- export class TableMenuCommon {
13
+ export class TableMenuCommon extends TableDomSelector {
14
+ static moduleName = 'table-menu';
15
+
12
16
  usedColors = new Set<string>();
13
17
  options: TableMenuOptions;
14
18
  menu: HTMLElement | null = null;
15
19
  isMenuDisplay: boolean = false;
16
20
  isColorPicking: boolean = false;
17
- updateUsedColor: (this: any, color?: string) => void;
18
21
  tooltipItem: MenuTooltipInstance[] = [];
19
22
  activeTooltip: MenuTooltipInstance | null = null;
20
23
  bem = createBEM('menu');
@@ -24,8 +27,9 @@ export class TableMenuCommon {
24
27
  };
25
28
 
26
29
  constructor(public tableModule: TableUp, public quill: Quill, options: TableMenuOptionsInput) {
27
- this.options = this.resolveOptions(options);
30
+ super(tableModule, quill);
28
31
 
32
+ this.options = this.resolveOptions(options);
29
33
  try {
30
34
  const storageValue = localStorage.getItem(this.options.localstorageKey) || '[]';
31
35
  let colorValue = JSON.parse(storageValue);
@@ -36,38 +40,44 @@ export class TableMenuCommon {
36
40
  }
37
41
  catch {}
38
42
 
39
- this.updateUsedColor = debounce((color?: string) => {
40
- if (!color) return;
41
- this.usedColors.add(color);
42
- if (this.usedColors.size > maxSaveColorCount) {
43
- const saveColors = Array.from(this.usedColors).slice(-1 * maxSaveColorCount);
44
- this.usedColors.clear();
45
- saveColors.map(v => this.usedColors.add(v));
46
- }
43
+ this.quill.on(Quill.events.EDITOR_CHANGE, this.updateWhenTextChange);
44
+ this.quill.on(tableUpEvent.TABLE_SELECTION_DRAG_START, this.hideWhenSelectionDragStart);
45
+ }
47
46
 
48
- localStorage.setItem(this.options.localstorageKey, JSON.stringify(Array.from(this.usedColors)));
49
- const usedColorWrappers = Array.from(document.querySelectorAll(`.${this.colorItemClass}.${colorClassName.used}`));
50
- for (const usedColorWrapper of usedColorWrappers) {
51
- const newColorItem = document.createElement('div');
52
- newColorItem.classList.add(colorClassName.item);
53
- newColorItem.style.backgroundColor = String(color);
54
- // if already have same color item. doesn't need insert
55
- const sameColorItem = Array.from(usedColorWrapper.querySelectorAll(`.${colorClassName.item}[style*="background-color: ${newColorItem.style.backgroundColor}"]`));
56
- if (sameColorItem.length <= 0) {
57
- usedColorWrapper.appendChild(newColorItem);
58
- }
47
+ updateUsedColor = debounce((color?: string) => {
48
+ if (!color) return;
49
+ this.usedColors.add(color);
50
+ if (this.usedColors.size > maxSaveColorCount) {
51
+ const saveColors = Array.from(this.usedColors).slice(-1 * maxSaveColorCount);
52
+ this.usedColors.clear();
53
+ saveColors.map(v => this.usedColors.add(v));
54
+ }
59
55
 
60
- const colorItem = Array.from(usedColorWrapper.querySelectorAll(`.${colorClassName.item}`)).slice(0, -1 * maxSaveColorCount);
61
- for (const item of colorItem) {
62
- item.remove();
63
- }
56
+ localStorage.setItem(this.options.localstorageKey, JSON.stringify(Array.from(this.usedColors)));
57
+ const usedColorWrappers = Array.from(document.querySelectorAll(`.${this.colorItemClass}.${colorClassName.used}`));
58
+ for (const usedColorWrapper of usedColorWrappers) {
59
+ const newColorItem = document.createElement('div');
60
+ newColorItem.classList.add(colorClassName.item);
61
+ newColorItem.style.backgroundColor = String(color);
62
+ // if already have same color item. doesn't need insert
63
+ const sameColorItem = Array.from(usedColorWrapper.querySelectorAll(`.${colorClassName.item}[style*="background-color: ${newColorItem.style.backgroundColor}"]`));
64
+ if (sameColorItem.length <= 0) {
65
+ usedColorWrapper.appendChild(newColorItem);
64
66
  }
65
- }, 1000);
66
- this.quill.on(Quill.events.TEXT_CHANGE, this.updateWhenTextChange);
67
- }
68
67
 
69
- updateWhenTextChange = () => {
70
- if (this.isMenuDisplay) {
68
+ const colorItem = Array.from(usedColorWrapper.querySelectorAll(`.${colorClassName.item}`)).slice(0, -1 * maxSaveColorCount);
69
+ for (const item of colorItem) {
70
+ item.remove();
71
+ }
72
+ }
73
+ }, 1000);
74
+
75
+ hideWhenSelectionDragStart = () => {
76
+ this.hide();
77
+ };
78
+
79
+ updateWhenTextChange = (eventName: string) => {
80
+ if (eventName === Quill.events.TEXT_CHANGE && this.isMenuDisplay) {
71
81
  this.update();
72
82
  }
73
83
  };
@@ -128,7 +138,7 @@ export class TableMenuCommon {
128
138
  else {
129
139
  isFunction(handle) && item.addEventListener('click', (e) => {
130
140
  this.quill.focus();
131
- handle(this.tableModule, this.getSelectedTds(), e);
141
+ handle.call(this, this.tableModule, this.getSelectedTds(), e);
132
142
  }, false);
133
143
  }
134
144
 
@@ -173,20 +183,20 @@ export class TableMenuCommon {
173
183
  transparentColor.classList.add(colorClassName.btn, 'transparent');
174
184
  transparentColor.textContent = this.tableModule.options.texts.transparent;
175
185
  transparentColor.addEventListener('click', () => {
176
- handle(this.tableModule, this.getSelectedTds(), 'transparent');
186
+ handle.call(this, this.tableModule, this.getSelectedTds(), 'transparent');
177
187
  });
178
188
  const clearColor = document.createElement('div');
179
189
  clearColor.classList.add(colorClassName.btn, 'clear');
180
190
  clearColor.textContent = this.tableModule.options.texts.clear;
181
191
  clearColor.addEventListener('click', () => {
182
- handle(this.tableModule, this.getSelectedTds(), null);
192
+ handle.call(this, this.tableModule, this.getSelectedTds(), null);
183
193
  });
184
194
  const customColor = document.createElement('div');
185
195
  customColor.classList.add(colorClassName.btn, 'custom');
186
196
  customColor.textContent = this.tableModule.options.texts.custom;
187
197
  const colorPicker = createColorPicker({
188
198
  onChange: (color) => {
189
- handle(this.tableModule, this.getSelectedTds(), color);
199
+ handle.call(this, this.tableModule, this.getSelectedTds(), color);
190
200
  this.updateUsedColor(color);
191
201
  },
192
202
  });
@@ -230,16 +240,18 @@ export class TableMenuCommon {
230
240
  type: 'click',
231
241
  content: colorSelectWrapper,
232
242
  onOpen: () => {
233
- if (this.isMenuDisplay && this.tableModule.tableSelection) {
234
- this.tableModule.tableSelection.hideDisplay();
243
+ const tableSelection = this.tableModule.getModule<TableSelection>('table-selection');
244
+ if (this.isMenuDisplay && tableSelection) {
245
+ tableSelection.hideDisplay();
235
246
  }
236
247
  this.setActiveTooltip(tooltip);
237
248
  return false;
238
249
  },
239
250
  onClose: () => {
240
- if (this.isMenuDisplay && this.tableModule.tableSelection) {
241
- this.tableModule.tableSelection.updateWithSelectedTds();
242
- this.tableModule.tableSelection.showDisplay();
251
+ const tableSelection = this.tableModule.getModule<TableSelection>('table-selection');
252
+ if (this.isMenuDisplay && tableSelection) {
253
+ tableSelection.updateWithSelectedTds();
254
+ tableSelection.showDisplay();
243
255
  }
244
256
  const isChild = colorSelectWrapper.contains(colorPicker);
245
257
  if (isChild) {
@@ -270,7 +282,8 @@ export class TableMenuCommon {
270
282
  }
271
283
 
272
284
  getSelectedTds() {
273
- return this.tableModule.tableSelection?.selectedTds || [];
285
+ const tableSelection = this.tableModule.getModule<TableSelection>('table-selection');
286
+ return tableSelection?.selectedTds || [];
274
287
  }
275
288
 
276
289
  createTipText(item: HTMLElement, text: string) {
@@ -279,17 +292,24 @@ export class TableMenuCommon {
279
292
  }
280
293
 
281
294
  show() {
282
- if (!this.menu || !this.tableModule.tableSelection || !this.tableModule.tableSelection.boundary) return;
283
- Object.assign(this.menu.style, { display: 'flex' });
284
- this.isMenuDisplay = true;
285
- this.update();
295
+ if (!this.table) return;
296
+ if (this.menu) {
297
+ this.hide();
298
+ }
299
+ this.menu = this.buildTools();
286
300
  }
287
301
 
288
302
  update() {
303
+ if (this.table && !this.quill.root.contains(this.table)) {
304
+ this.setSelectionTable(undefined);
305
+ }
289
306
  }
290
307
 
291
308
  hide() {
292
- this.menu && Object.assign(this.menu.style, { display: 'none' });
309
+ if (this.menu) {
310
+ this.menu.remove();
311
+ this.menu = null;
312
+ }
293
313
  for (const tooltip of this.tooltipItem) {
294
314
  tooltip.hide(true);
295
315
  }
@@ -298,11 +318,12 @@ export class TableMenuCommon {
298
318
 
299
319
  destroy() {
300
320
  this.quill.off(Quill.events.TEXT_CHANGE, this.updateWhenTextChange);
321
+ this.quill.off(tableUpEvent.TABLE_SELECTION_DRAG_START, this.hideWhenSelectionDragStart);
301
322
  this.activeTooltip = null;
302
- for (const tooltip of this.tooltipItem) tooltip.destroy();
303
- if (!this.menu) return;
323
+ for (const tooltip of this.tooltipItem) {
324
+ tooltip.destroy();
325
+ }
326
+ this.tooltipItem = [];
304
327
  this.hide();
305
- this.menu.remove();
306
- this.menu = null;
307
328
  }
308
329
  }
@@ -1,7 +1,8 @@
1
1
  import type Quill from 'quill';
2
2
  import type { TableUp } from '../../table-up';
3
- import type { TableMenuOptions, ToolTipOptions } from '../../utils';
4
- import { limitDomInViewPort } from '../../utils';
3
+ import type { InternalTableSelectionModule, TableMenuOptions, ToolTipOptions } from '../../utils';
4
+ import type { TableSelection } from '../table-selection';
5
+ import { limitDomInViewPort, tableUpEvent } from '../../utils';
5
6
  import { menuColorSelectClassName } from './constants';
6
7
  import { TableMenuCommon } from './table-menu-common';
7
8
 
@@ -15,8 +16,16 @@ export class TableMenuContextmenu extends TableMenuCommon {
15
16
  super(tableModule, quill, options);
16
17
 
17
18
  this.quill.root.addEventListener('contextmenu', this.listenContextmenu);
19
+ this.quill.on(tableUpEvent.TABLE_SELECTION_CHANGE, this.tableSelectioChange);
20
+ this.quill.on(tableUpEvent.TABLE_SELECTION_DISPLAY_CHANGE, this.tableSelectioChange);
18
21
  }
19
22
 
23
+ tableSelectioChange = (tableSelection: InternalTableSelectionModule) => {
24
+ if (tableSelection.selectedTds.length <= 0) {
25
+ this.hide();
26
+ }
27
+ };
28
+
20
29
  listenContextmenu = (e: MouseEvent) => {
21
30
  e.preventDefault();
22
31
 
@@ -25,7 +34,8 @@ export class TableMenuContextmenu extends TableMenuCommon {
25
34
 
26
35
  const tableNode = path.find(node => node.tagName && node.tagName.toUpperCase() === 'TABLE' && node.classList.contains('ql-table'));
27
36
 
28
- if (tableNode && this.tableModule.tableSelection?.selectedTds?.length) {
37
+ const tableSelection = this.tableModule.getModule<TableSelection>('table-selection');
38
+ if (tableNode && tableSelection?.selectedTds?.length) {
29
39
  if (!this.menu) {
30
40
  this.menu = this.buildTools();
31
41
  }
@@ -64,12 +74,16 @@ export class TableMenuContextmenu extends TableMenuCommon {
64
74
  show() {}
65
75
 
66
76
  update(position?: { x: number; y: number }) {
67
- if (!this.isMenuDisplay || !this.menu || !this.tableModule.tableSelection || !this.tableModule.tableSelection.isDisplaySelection) return;
68
- if (!position) {
77
+ super.update();
78
+ const tableSelection = this.tableModule.getModule<TableSelection>('table-selection');
79
+ if (!this.table || !this.isMenuDisplay || !this.menu) {
80
+ this.hide();
81
+ return;
82
+ }
83
+ if (!position || !tableSelection?.isDisplaySelection) {
69
84
  return;
70
85
  }
71
86
 
72
- super.update();
73
87
  const style: Record<string, any> = {
74
88
  display: 'flex',
75
89
  left: 0,
@@ -98,5 +112,7 @@ export class TableMenuContextmenu extends TableMenuCommon {
98
112
  destroy() {
99
113
  this.quill.root.removeEventListener('contextmenu', this.listenContextmenu);
100
114
  super.destroy();
115
+ this.quill.off(tableUpEvent.TABLE_SELECTION_CHANGE, this.tableSelectioChange);
116
+ this.quill.off(tableUpEvent.TABLE_SELECTION_DISPLAY_CHANGE, this.tableSelectioChange);
101
117
  }
102
118
  }
@@ -1,31 +1,94 @@
1
1
  import type Quill from 'quill';
2
+ import type { TableCellInnerFormat } from '../../formats';
2
3
  import type { TableUp } from '../../table-up';
4
+ import type { InternalTableSelectionModule } from '../../utils';
5
+ import type { TableSelection } from '../table-selection';
3
6
  import type { TableMenuOptionsInput } from './table-menu-common';
4
7
  import { computePosition, flip, limitShift, offset, shift } from '@floating-ui/dom';
8
+ import { tableUpEvent } from '../../utils';
5
9
  import { TableMenuCommon } from './table-menu-common';
6
10
 
7
11
  export class TableMenuSelect extends TableMenuCommon {
8
12
  constructor(public tableModule: TableUp, public quill: Quill, options: TableMenuOptionsInput) {
9
13
  super(tableModule, quill, options);
10
14
 
11
- this.menu = this.buildTools();
12
- this.tableModule.addContainer(this.menu);
13
- this.show();
15
+ this.quill.on(tableUpEvent.TABLE_SELECTION_DRAG_START, this.tableSelectionDragStart);
16
+ this.quill.on(tableUpEvent.TABLE_SELECTION_DRAG_END, this.tableSelectionDragEnd);
17
+ this.quill.on(tableUpEvent.TABLE_SELECTION_CHANGE, this.tableSelectioChange);
18
+ this.quill.on(tableUpEvent.TABLE_SELECTION_DISPLAY_CHANGE, this.tableSelectionDisplayChange);
19
+ }
20
+
21
+ tableSelectionDragStart = () => {
22
+ this.hide();
23
+ };
24
+
25
+ tableSelectionDragEnd = (tableSelection: InternalTableSelectionModule) => {
26
+ if (tableSelection.selectedTds.length > 0) {
27
+ this.show();
28
+ }
29
+ };
30
+
31
+ tableSelectioChange = (tableSelection: InternalTableSelectionModule, selectedTds: TableCellInnerFormat[]) => {
32
+ if (selectedTds.length <= 0) {
33
+ this.hide();
34
+ }
35
+ };
36
+
37
+ tableSelectionDisplayChange = (tableSelection: InternalTableSelectionModule) => {
38
+ if (!tableSelection.dragging) {
39
+ this.update();
40
+ }
41
+ };
42
+
43
+ buildTools(): HTMLElement {
44
+ const menu = super.buildTools();
45
+ this.tableModule.addContainer(menu);
46
+ return menu;
47
+ }
48
+
49
+ show() {
50
+ super.show();
14
51
  this.update();
15
52
  }
16
53
 
17
54
  update() {
18
- if (!this.isMenuDisplay || !this.menu || !this.tableModule.tableSelection || !this.tableModule.tableSelection.isDisplaySelection) return;
19
55
  super.update();
56
+ if (!this.menu && this.table) {
57
+ this.show();
58
+ return;
59
+ }
60
+ const selectedTds = this.getSelectedTds();
61
+ if (!this.menu || !this.table || selectedTds.length === 0) {
62
+ if (this.menu || !this.table) {
63
+ this.isMenuDisplay = false;
64
+ this.menu && this.menu.classList.add(this.bem.is('hidden'));
65
+ this.hide();
66
+ }
67
+ return;
68
+ }
69
+ this.isMenuDisplay = true;
70
+ this.menu.classList.remove(this.bem.is('hidden'));
20
71
 
21
- computePosition(this.tableModule.tableSelection.cellSelect, this.menu, {
22
- placement: 'bottom',
23
- middleware: [flip(), shift({ limiter: limitShift() }), offset(20)],
24
- }).then(({ x, y }) => {
25
- Object.assign(this.menu!.style, {
26
- left: `${x}px`,
27
- top: `${y}px`,
72
+ const tableSelection = this.tableModule.getModule<TableSelection>('table-selection');
73
+ if (tableSelection?.isDisplaySelection) {
74
+ computePosition(tableSelection.cellSelect, this.menu, {
75
+ placement: 'bottom',
76
+ middleware: [flip(), shift({ limiter: limitShift() }), offset(20)],
77
+ }).then(({ x, y }) => {
78
+ if (this.menu) {
79
+ Object.assign(this.menu.style, {
80
+ left: `${x}px`,
81
+ top: `${y}px`,
82
+ });
83
+ }
28
84
  });
29
- });
85
+ }
86
+ }
87
+
88
+ destroy(): void {
89
+ super.destroy();
90
+
91
+ this.quill.off(tableUpEvent.TABLE_SELECTION_DRAG_START, this.tableSelectionDragStart);
92
+ this.quill.off(tableUpEvent.TABLE_SELECTION_DRAG_END, this.tableSelectionDragEnd);
30
93
  }
31
94
  }