quill-table-up 2.1.0 → 2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "quill-table-up",
3
3
  "type": "module",
4
- "version": "2.1.0",
4
+ "version": "2.1.2",
5
5
  "packageManager": "pnpm@9.9.0",
6
6
  "description": "A table module for quill2.x",
7
7
  "author": "zzxming",
@@ -57,7 +57,7 @@
57
57
  "@typescript-eslint/parser": "^8.18.2",
58
58
  "@vitest/coverage-v8": "^2.0.5",
59
59
  "@vitest/ui": "^2.0.5",
60
- "@zzxming/eslint-config": "^0.3.5",
60
+ "@zzxming/eslint-config": "^0.4.0",
61
61
  "autoprefixer": "^10.4.19",
62
62
  "eslint": "^9.17.0",
63
63
  "gulp": "^4.0.0",
@@ -91,7 +91,7 @@ expect.extend({
91
91
  interface TableColDeltaValue extends Omit<TableColValue, 'width' | 'full'> {
92
92
  width: number;
93
93
  full?: 'true';
94
- };
94
+ }
95
95
  interface TableCreatorOptions {
96
96
  isEmpty: boolean;
97
97
  tableId: string;
package/src/index.ts CHANGED
@@ -277,7 +277,7 @@ export class TableUp {
277
277
  false,
278
278
  );
279
279
  this.quill.on(tableUpEvent.AFTER_TABLE_RESIZE, () => {
280
- this.tableSelection && this.tableSelection.hide();
280
+ this.tableSelection && this.tableSelection.updateWithSelectedTds();
281
281
  });
282
282
 
283
283
  this.pasteTableHandler();
@@ -312,7 +312,7 @@ export class TableUp {
312
312
  resizeOptions: {},
313
313
  resizeScaleOptions: {},
314
314
  } as TableUpOptions, options);
315
- };
315
+ }
316
316
 
317
317
  resolveTexts(options: Partial<TableTextOptions>) {
318
318
  return Object.assign({
@@ -327,8 +327,21 @@ export class TableUp {
327
327
  clear: 'Clear',
328
328
  transparent: 'Transparent',
329
329
  perWidthInsufficient: 'The percentage width is insufficient. To complete the operation, the table needs to be converted to a fixed width. Do you want to continue?',
330
+ CopyCell: 'Copy cell',
331
+ CutCell: 'Cut cell',
332
+ InsertTop: 'Insert row above',
333
+ InsertRight: 'Insert column right',
334
+ InsertBottom: 'Insert row below',
335
+ InsertLeft: 'Insert column Left',
336
+ MergeCell: 'Merge Cell',
337
+ SplitCell: 'Split Cell',
338
+ DeleteRow: 'Delete Row',
339
+ DeleteColumn: 'Delete Column',
340
+ DeleteTable: 'Delete table',
341
+ BackgroundColor: 'Set background color',
342
+ BorderColor: 'Set border color',
330
343
  }, options);
331
- };
344
+ }
332
345
 
333
346
  pasteTableHandler() {
334
347
  let tableId = randomId();
@@ -589,8 +602,9 @@ export class TableUp {
589
602
  isFulllLabel.appendChild(isFullCheckboxText);
590
603
  dom.appendChild(isFulllLabel);
591
604
  }
605
+ picker.options.innerHTML = '';
592
606
  picker.options.appendChild(dom);
593
- };
607
+ }
594
608
 
595
609
  setCellAttrs(selectedTds: TableCellInnerFormat[], attr: string, value?: any, isStyle: boolean = false) {
596
610
  if (selectedTds.length === 0) return;
@@ -1248,7 +1262,7 @@ export function updateTableConstants(data: Partial<TableConstantsData>) {
1248
1262
  TableRowFormat.blotName = blotName.tableRow;
1249
1263
  TableCellFormat.blotName = blotName.tableCell;
1250
1264
  TableCellInnerFormat.blotName = blotName.tableCellInner;
1251
- };
1265
+ }
1252
1266
  export function defaultCustomSelect(tableModule: TableUp, picker: QuillThemePicker) {
1253
1267
  return createSelectBox({
1254
1268
  onSelect: (row: number, col: number) => {
@@ -66,7 +66,7 @@ export class TableMenuCommon {
66
66
  defaultColorMap,
67
67
  }, options);
68
68
  return value as TableMenuOptions;
69
- };
69
+ }
70
70
 
71
71
  getUsedColors() {
72
72
  return usedColors;
@@ -116,7 +116,7 @@ export class TableMenuCommon {
116
116
  toolBox.appendChild(item);
117
117
  }
118
118
  return toolBox;
119
- };
119
+ }
120
120
 
121
121
  createColorChoose(item: HTMLElement, { handle, key }: ToolOption) {
122
122
  const colorSelectWrapper = document.createElement('div');
@@ -1,6 +1,7 @@
1
1
  import type { Parchment as TypeParchment } from 'quill';
2
2
  import type TableUp from '../..';
3
3
  import type { TableColFormat, TableMainFormat, TableRowFormat } from '../..';
4
+ import type { sizeChangeValue } from './table-resize-common';
4
5
  import Quill from 'quill';
5
6
  import { TableBodyFormat, TableCellInnerFormat } from '../../formats';
6
7
  import { addScrollEvent, clearScrollEvent, createBEM } from '../../utils';
@@ -10,7 +11,7 @@ import { isTableAlignRight } from './utils';
10
11
  interface Point {
11
12
  x: number;
12
13
  y: number;
13
- };
14
+ }
14
15
  export class TableResizeBox extends TableResizeCommon {
15
16
  root!: HTMLElement;
16
17
  tableMain: TableMainFormat;
@@ -70,15 +71,15 @@ export class TableResizeBox extends TableResizeCommon {
70
71
  tableSelection.selectedTds = tableSelection.computeSelectedTds(...currentBoundary);
71
72
  tableSelection.show();
72
73
  }
73
- };
74
+ }
74
75
 
75
76
  findCurrentColIndex(e: MouseEvent): number {
76
77
  return Array.from(this.root.getElementsByClassName(this.bem.be('col-separator'))).indexOf(e.target as HTMLElement);
77
78
  }
78
79
 
79
- colWidthChange(i: number, w: number, _isFull: boolean) {
80
+ colWidthChange(i: number, w: sizeChangeValue, isFull: boolean) {
80
81
  const tableColHeads = Array.from(this.root.getElementsByClassName(this.bem.be('col-header'))) as HTMLElement[];
81
- tableColHeads[i].style.width = `${w}px`;
82
+ tableColHeads[i].style.width = isFull ? `${w.pre}%` : `${w.px}px`;
82
83
  }
83
84
 
84
85
  handleColMouseDownFunc = function (this: TableResizeBox, e: MouseEvent) {
@@ -4,6 +4,10 @@ import type { TableMainFormat } from '../../formats';
4
4
  import { createBEM, createButton, createDialog, tableUpEvent, tableUpSize } from '../../utils';
5
5
  import { isTableAlignRight } from './utils';
6
6
 
7
+ export interface sizeChangeValue {
8
+ px: number;
9
+ pre: number;
10
+ }
7
11
  export class TableResizeCommon {
8
12
  colIndex: number = -1;
9
13
  tableMain?: TableMainFormat;
@@ -27,7 +31,7 @@ export class TableResizeCommon {
27
31
  return -1;
28
32
  }
29
33
 
30
- colWidthChange(_i: number, _w: number, _isFull: boolean) {}
34
+ colWidthChange(_i: number, _w: sizeChangeValue, _isFull: boolean) {}
31
35
 
32
36
  async createConfirmDialog({ message, confirm, cancel }: {
33
37
  message: string;
@@ -162,12 +166,19 @@ export class TableResizeCommon {
162
166
 
163
167
  for (const { index, width } of updateInfo) {
164
168
  cols[index].width = `${Math.round(width)}${isFull ? '%' : 'px'}`;
165
- this.colWidthChange(index, isFull ? width / 100 * tableWidth : width, isFull);
169
+ this.colWidthChange(
170
+ index,
171
+ {
172
+ px: Math.round(width / 100 * tableWidth),
173
+ pre: Math.round(width),
174
+ },
175
+ isFull,
176
+ );
166
177
  }
167
178
  }
168
179
 
169
180
  this.quill.emitter.emit(tableUpEvent.AFTER_TABLE_RESIZE);
170
- };
181
+ }
171
182
 
172
183
  handleColMouseMove(e: MouseEvent): { left: number; width: number } | undefined {
173
184
  e.preventDefault();
@@ -213,7 +224,7 @@ export class TableResizeCommon {
213
224
  left: resX,
214
225
  width,
215
226
  };
216
- };
227
+ }
217
228
 
218
229
  handleColMouseDown(e: MouseEvent): { top: number; left: number; height: number } | undefined {
219
230
  if (e.button !== 0) return;
@@ -255,7 +266,7 @@ export class TableResizeCommon {
255
266
  this.dragColBreak = divDom;
256
267
 
257
268
  return styleValue;
258
- };
269
+ }
259
270
 
260
271
  findCurrentRowIndex(_e: MouseEvent) {
261
272
  return -1;
@@ -336,7 +347,7 @@ export class TableResizeCommon {
336
347
  this.dragRowBreak = divDom;
337
348
 
338
349
  return styleValue;
339
- };
350
+ }
340
351
 
341
352
  update() {}
342
353
  destroy() {}
@@ -64,35 +64,11 @@ export class TableSelection {
64
64
  });
65
65
  this.resizeObserver.observe(this.quill.root);
66
66
 
67
- this.quill.root.addEventListener('mousedown', this.mouseDownHandler, false);
68
- this.quill.root.addEventListener('keydown', (event) => {
69
- const selectionKey = new Set(['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'End', 'Home', 'PageDown', 'PageUp']);
70
- if (event.shiftKey) {
71
- this.shiftKeyDown = true;
72
- if (selectionKey.has(event.key)) {
73
- this.keySelectionChange = true;
74
- }
75
- }
76
- });
77
- this.quill.root.addEventListener('keyup', (event) => {
78
- if (event.key === 'Shift') {
79
- this.shiftKeyDown = false;
80
- }
81
- });
82
- document.addEventListener('selectionchange', this.selectionChangeHandler);
83
- this.quill.on(Quill.events.SELECTION_CHANGE, (range: TypeRange | null) => {
84
- if (range && this.isDisplaySelection) {
85
- const formats = this.quill.getFormat(range);
86
- const [line] = this.quill.getLine(range.index);
87
- let isInChildren = !!formats[blotName.tableCellInner] && !!line;
88
- if (isInChildren) {
89
- isInChildren &&= this.selectedTds.some(td => td.children.contains(line!));
90
- }
91
- if (!isInChildren) {
92
- this.hide();
93
- }
94
- }
95
- });
67
+ this.quill.root.addEventListener('mousedown', this.mouseDownHandler, { passive: false });
68
+ this.quill.root.addEventListener('keydown', this.keydownHandler, { passive: false });
69
+ this.quill.root.addEventListener('keyup', this.keyupHandler, { passive: false });
70
+ document.addEventListener('selectionchange', this.selectionChangeHandler, { passive: false });
71
+ this.quill.on(Quill.events.SELECTION_CHANGE, this.quillSelectionChangeHandler);
96
72
  if (this.options.tableMenu) {
97
73
  this.tableMenu = new this.options.tableMenu(tableModule, quill, this.options.tableMenuOptions);
98
74
  }
@@ -125,6 +101,36 @@ export class TableSelection {
125
101
  return tempRange.startOffset;
126
102
  }
127
103
 
104
+ quillSelectionChangeHandler = (range: TypeRange | null) => {
105
+ if (range && this.isDisplaySelection) {
106
+ const formats = this.quill.getFormat(range);
107
+ const [line] = this.quill.getLine(range.index);
108
+ let isInChildren = !!formats[blotName.tableCellInner] && !!line;
109
+ if (isInChildren) {
110
+ isInChildren &&= this.selectedTds.some(td => td.children.contains(line!));
111
+ }
112
+ if (!isInChildren) {
113
+ this.hide();
114
+ }
115
+ }
116
+ };
117
+
118
+ keyupHandler = (event: KeyboardEvent) => {
119
+ if (event.key === 'Shift') {
120
+ this.shiftKeyDown = false;
121
+ }
122
+ };
123
+
124
+ keydownHandler = (event: KeyboardEvent) => {
125
+ const selectionKey = new Set(['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'End', 'Home', 'PageDown', 'PageUp']);
126
+ if (event.shiftKey) {
127
+ this.shiftKeyDown = true;
128
+ if (selectionKey.has(event.key)) {
129
+ this.keySelectionChange = true;
130
+ }
131
+ }
132
+ };
133
+
128
134
  setSelectionData(selection: Selection, selectionData: SelectionData) {
129
135
  const { anchorNode, anchorOffset, focusNode, focusOffset } = selectionData;
130
136
  if (!anchorNode || !focusNode) return;
@@ -506,14 +512,14 @@ export class TableSelection {
506
512
  this.selectedTds = this.computeSelectedTds(startPoint, startPoint);
507
513
  this.dragging = true;
508
514
  this.show();
509
- if (this.tableMenu) {
510
- this.tableMenu.hide();
511
- }
512
- if (this.tableModule.tableResize) {
513
- this.tableModule.tableResize.hide();
514
- }
515
515
 
516
516
  const mouseMoveHandler = (mousemoveEvent: MouseEvent) => {
517
+ if (this.tableMenu) {
518
+ this.tableMenu.hide();
519
+ }
520
+ if (this.tableModule.tableResize) {
521
+ this.tableModule.tableResize.hide();
522
+ }
517
523
  const { button, target, clientX, clientY } = mousemoveEvent;
518
524
  const closestTable = (target as HTMLElement).closest('.ql-table') as HTMLElement;
519
525
  if (
@@ -678,7 +684,10 @@ export class TableSelection {
678
684
  }
679
685
  clearScrollEvent.call(this);
680
686
 
681
- this.quill.root.removeEventListener('mousedown', this.mouseDownHandler, false);
687
+ this.quill.root.removeEventListener('mousedown', this.mouseDownHandler);
688
+ this.quill.root.removeEventListener('keydown', this.keydownHandler);
689
+ this.quill.root.removeEventListener('keyup', this.keyupHandler);
682
690
  document.removeEventListener('selectionchange', this.selectionChangeHandler);
691
+ this.quill.off(Quill.events.SELECTION_CHANGE, this.quillSelectionChangeHandler);
683
692
  }
684
693
  }
package/src/svg/copy.svg CHANGED
@@ -1 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 48 48"><defs><mask id="ipTCopy0"><g fill="none" stroke="#fff" stroke-linejoin="round" stroke-width="4"><path stroke-linecap="round" d="M13 12.432v-4.62A2.813 2.813 0 0 1 15.813 5h24.374A2.813 2.813 0 0 1 43 7.813v24.375A2.813 2.813 0 0 1 40.188 35h-4.672"/><path fill="#555" d="M32.188 13H7.811A2.813 2.813 0 0 0 5 15.813v24.374A2.813 2.813 0 0 0 7.813 43h24.375A2.813 2.813 0 0 0 35 40.188V15.811A2.813 2.813 0 0 0 32.188 13Z"/></g></mask></defs><path fill="currentColor" d="M0 0h48v48H0z" mask="url(#ipTCopy0)"/></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 256 256"><g fill="currentColor"><path d="M216 40v128h-48V88H88V40Z" opacity=".2"/><path d="M216 32H88a8 8 0 0 0-8 8v40H40a8 8 0 0 0-8 8v128a8 8 0 0 0 8 8h128a8 8 0 0 0 8-8v-40h40a8 8 0 0 0 8-8V40a8 8 0 0 0-8-8m-56 176H48V96h112Zm48-48h-32V88a8 8 0 0 0-8-8H96V48h112Z"/></g></svg>
package/src/svg/cut.svg CHANGED
@@ -1 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><path fill="currentColor" d="m19 3l-6 6l2 2l7-7V3zm-9 3c0-2.21-1.79-4-4-4S2 3.79 2 6s1.79 4 4 4c.59 0 1.14-.13 1.64-.36L10 12l-2.36 2.36C7.14 14.13 6.59 14 6 14c-2.21 0-4 1.79-4 4s1.79 4 4 4s4-1.79 4-4c0-.59-.13-1.14-.36-1.64L12 14l7 7h3v-1L9.64 7.64c.23-.5.36-1.05.36-1.64M6 8c-1.1 0-2-.89-2-2s.9-2 2-2s2 .89 2 2s-.9 2-2 2m0 12c-1.1 0-2-.89-2-2s.9-2 2-2s2 .89 2 2s-.9 2-2 2m6-8.5c.28 0 .5.22.5.5s-.22.5-.5.5s-.5-.22-.5-.5s.22-.5.5-.5"/></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 32 32"><path fill="currentColor" d="m19.05 13.733l-1-1.733l-10.122 5.846l-.997-.576a3 3 0 0 0 .667-.769A3 3 0 1 0 3.5 17.599L5.928 19L3.5 20.402a3.034 3.034 0 1 0 3.44.323l.988-.57L14.59 24l1-1.73L9.928 19zM4.034 15.26a1 1 0 1 1 .466.607a1 1 0 0 1-.466-.607M5 22a1 1 0 1 1-.865 1.5A1 1 0 0 1 5 22m12 4h4v2h-4zm-7 0h4v2h-4z"/><path fill="currentColor" d="M28 28h-4v-2h4V4H7v4H5V4a2 2 0 0 1 2-2h21a2 2 0 0 1 2 2v22a2 2 0 0 1-2 2"/></svg>
@@ -3,13 +3,13 @@ export interface HSB {
3
3
  s: number;
4
4
  b: number;
5
5
  a: number;
6
- };
6
+ }
7
7
  export interface RGB {
8
8
  r: number;
9
9
  g: number;
10
10
  b: number;
11
11
  a: number;
12
- };
12
+ }
13
13
  const normalizeValue = function (value: number | string, max: number | string) {
14
14
  value = Math.min(max as number, Math.max(0, Number.parseFloat(`${value}`)));
15
15
 
@@ -4,7 +4,7 @@ import { isString } from '../is';
4
4
  interface ButtonOptions {
5
5
  type: 'confirm' | 'default';
6
6
  content: HTMLElement | string;
7
- };
7
+ }
8
8
  export const createButton = (options?: Partial<ButtonOptions>) => {
9
9
  const { type = 'default', content } = options || {};
10
10
  const bem = createBEM('button');
@@ -5,7 +5,7 @@ import { HEXtoRGB, HSBtoHEX, HSBtoRGB, RGBtoHEX, RGBtoHSB, validateHSB } from '.
5
5
  interface ColorPickerOptions {
6
6
  color: string;
7
7
  onChange: (color: string) => void;
8
- };
8
+ }
9
9
  export const createColorPicker = (options: Partial<ColorPickerOptions> = {}) => {
10
10
  const contentWidth = 230;
11
11
  const contentHeight = 150;
@@ -6,7 +6,7 @@ interface InputOptions {
6
6
  max?: number;
7
7
  min?: number;
8
8
  [key: string]: any;
9
- };
9
+ }
10
10
  export const createInputItem = (label: string, options: InputOptions) => {
11
11
  const bem = createBEM('input');
12
12
  options.type || (options.type = 'text');
@@ -38,7 +38,7 @@ export interface TooltipInstance {
38
38
  destroy: () => void;
39
39
  show: (force?: boolean) => void;
40
40
  hide: (force?: boolean) => void;
41
- };
41
+ }
42
42
  export const createTooltip = (target: HTMLElement, options: ToolTipOptions = {}): TooltipInstance | null => {
43
43
  const { msg = '', delay = 150, content, direction = 'bottom', type = 'hover', container, onOpen, onClose, closed, onDestroy } = options;
44
44
  const bem = createBEM('tooltip');
@@ -25,7 +25,7 @@ export interface TableMenuOptions {
25
25
  tools: Tool[];
26
26
  localstorageKey: string;
27
27
  defaultColorMap: string[];
28
- };
28
+ }
29
29
  export interface TableSelectionOptions {
30
30
  selectColor: string;
31
31
  tableMenu?: Constructor<InternalModule, [TableUp, Quill, Partial<TableMenuOptions>]>;
@@ -43,7 +43,7 @@ export interface TableCreatorTextOptions {
43
43
  colText: string;
44
44
  notPositiveNumberError: string;
45
45
  perWidthInsufficient: string;
46
- };
46
+ }
47
47
  export type TableMenuTexts = Record<string, string>;
48
48
  export interface TableTextOptions extends TableCreatorTextOptions, TableMenuTexts {
49
49
  custom: string;
@@ -75,7 +75,7 @@ export interface TableColValue {
75
75
  width: string;
76
76
  full?: boolean;
77
77
  align?: string;
78
- };
78
+ }
79
79
  export interface TableCellValue {
80
80
  tableId: string;
81
81
  rowId: string;
@@ -83,7 +83,7 @@ export interface TableCellValue {
83
83
  rowspan: number;
84
84
  colspan: number;
85
85
  style?: string;
86
- };
86
+ }
87
87
  export interface TableRowValue {
88
88
  tableId: string;
89
89
  rowId: string;
@@ -92,7 +92,7 @@ export interface TableValue {
92
92
  tableId: string;
93
93
  full?: boolean;
94
94
  align?: string;
95
- };
95
+ }
96
96
 
97
97
  export interface RelactiveRect {
98
98
  x: number;
@@ -108,7 +108,7 @@ export interface InternalModule {
108
108
  hide: () => void;
109
109
  update: () => void;
110
110
  destroy: () => void;
111
- };
111
+ }
112
112
  export type Constructor<T = any, U extends Array<any> = any[]> = new (...args: U) => T;
113
113
  export interface InternalTableSelectionModule extends InternalModule {
114
114
  dragging: boolean;
@@ -132,4 +132,4 @@ export interface TableConstantsData {
132
132
  blotName: Record<string, string>;
133
133
  tableUpSize: Record<string, number>;
134
134
  tableUpEvent: Record<string, string>;
135
- };
135
+ }
@@ -25,7 +25,7 @@ interface ParentBlotReturnMap {
25
25
  [blotName.tableRow]: TableRowFormat;
26
26
  [blotName.tableCell]: TableCellFormat;
27
27
  [blotName.tableCellInner]: TableCellInnerFormat;
28
- };
28
+ }
29
29
  type ParentBlotReturn = {
30
30
  [key: string]: TypeParchment.Parent;
31
31
  } & ParentBlotReturnMap;
@@ -82,7 +82,7 @@ function mixinProps<T = any, U = any>(target: T, source: U) {
82
82
  Object.defineProperty(target, prop, Object.getOwnPropertyDescriptor(source, prop)!);
83
83
  }
84
84
  return target as typeof target & Omit<typeof source, 'constructor'>;
85
- };
85
+ }
86
86
  export function mixinClass<
87
87
  T extends Constructor,
88
88
  U extends Constructor[],
@@ -100,7 +100,7 @@ export function mixinClass<
100
100
  }
101
101
 
102
102
  return targetClass;
103
- };
103
+ }
104
104
 
105
105
  const viewportPadding = 8;
106
106
  export const limitDomInViewPort = (rect: { left: number; top: number; width: number; height: number }) => {
@@ -134,7 +134,7 @@ export const limitDomInViewPort = (rect: { left: number; top: number; width: num
134
134
 
135
135
  interface ScrollHandle {
136
136
  scrollHandler: [HTMLElement, (e: Event) => void][];
137
- };
137
+ }
138
138
  export function addScrollEvent(this: ScrollHandle, dom: HTMLElement, handle: (e: Event) => void) {
139
139
  dom.addEventListener('scroll', handle);
140
140
  this.scrollHandler.push([dom, handle]);