quill-table-up 2.0.1 → 2.0.3
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/dist/index.d.ts +5 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/table-creator.css +1 -1
- package/package.json +9 -14
- package/src/__tests__/e2e/custom-creator.test.ts +44 -0
- package/src/__tests__/e2e/table-align.test.ts +39 -0
- package/src/__tests__/e2e/table-resize.test.ts +152 -0
- package/src/__tests__/e2e/table-scrollbar.test.ts +31 -0
- package/src/__tests__/e2e/table-selection.test.ts +83 -0
- package/src/__tests__/e2e/utils.ts +6 -0
- package/src/__tests__/unit/table-insert-blot.test.ts +464 -0
- package/src/__tests__/unit/table-insert-remove-merge.test.ts +1270 -0
- package/src/__tests__/unit/table-redo-undo.test.ts +909 -0
- package/src/__tests__/unit/utils.test-d.ts +49 -0
- package/src/__tests__/unit/utils.test.ts +715 -0
- package/src/__tests__/unit/utils.ts +216 -0
- package/src/__tests__/unit/vitest.d.ts +12 -0
- package/src/formats/container-format.ts +52 -0
- package/src/formats/index.ts +10 -0
- package/src/formats/overrides/block.ts +93 -0
- package/src/formats/overrides/blockquote.ts +8 -0
- package/src/formats/overrides/code.ts +8 -0
- package/src/formats/overrides/header.ts +8 -0
- package/src/formats/overrides/index.ts +6 -0
- package/src/formats/overrides/list.ts +10 -0
- package/src/formats/overrides/scroll.ts +51 -0
- package/src/formats/table-body-format.ts +92 -0
- package/src/formats/table-cell-format.ts +139 -0
- package/src/formats/table-cell-inner-format.ts +251 -0
- package/src/formats/table-col-format.ts +174 -0
- package/src/formats/table-colgroup-format.ts +133 -0
- package/src/formats/table-main-format.ts +143 -0
- package/src/formats/table-row-format.ts +147 -0
- package/src/formats/table-wrapper-format.ts +55 -0
- package/src/formats/utils.ts +3 -0
- package/src/index.ts +1157 -0
- package/src/modules/index.ts +5 -0
- package/src/modules/table-align.ts +116 -0
- package/src/modules/table-menu/constants.ts +140 -0
- package/src/modules/table-menu/index.ts +3 -0
- package/src/modules/table-menu/table-menu-common.ts +249 -0
- package/src/modules/table-menu/table-menu-contextmenu.ts +94 -0
- package/src/modules/table-menu/table-menu-select.ts +28 -0
- package/src/modules/table-resize/index.ts +5 -0
- package/src/modules/table-resize/table-resize-box.ts +293 -0
- package/src/modules/table-resize/table-resize-common.ts +343 -0
- package/src/modules/table-resize/table-resize-line.ts +163 -0
- package/src/modules/table-resize/table-resize-scale.ts +154 -0
- package/src/modules/table-resize/utils.ts +3 -0
- package/src/modules/table-scrollbar.ts +255 -0
- package/src/modules/table-selection.ts +262 -0
- package/src/style/button.less +45 -0
- package/src/style/color-picker.less +134 -0
- package/src/style/dialog.less +53 -0
- package/src/style/functions.less +9 -0
- package/src/style/index.less +89 -0
- package/src/style/input.less +64 -0
- package/src/style/select-box.less +51 -0
- package/src/style/table-creator.less +68 -0
- package/src/style/table-menu.less +122 -0
- package/src/style/table-resize-scale.less +31 -0
- package/src/style/table-resize.less +183 -0
- package/src/style/table-scrollbar.less +49 -0
- package/src/style/table-selection.less +15 -0
- package/src/style/tooltip.less +19 -0
- package/src/style/variables.less +1 -0
- package/src/svg/background.svg +1 -0
- package/src/svg/border.svg +1 -0
- package/src/svg/color.svg +1 -0
- package/src/svg/insert-bottom.svg +1 -0
- package/src/svg/insert-left.svg +1 -0
- package/src/svg/insert-right.svg +1 -0
- package/src/svg/insert-top.svg +1 -0
- package/src/svg/merge-cell.svg +1 -0
- package/src/svg/remove-column.svg +1 -0
- package/src/svg/remove-row.svg +1 -0
- package/src/svg/remove-table.svg +1 -0
- package/src/svg/split-cell.svg +1 -0
- package/src/types.d.ts +4 -0
- package/src/utils/bem.ts +23 -0
- package/src/utils/color.ts +109 -0
- package/src/utils/components/button.ts +22 -0
- package/src/utils/components/color-picker.ts +236 -0
- package/src/utils/components/dialog.ts +41 -0
- package/src/utils/components/index.ts +6 -0
- package/src/utils/components/input.ts +74 -0
- package/src/utils/components/table/creator.ts +86 -0
- package/src/utils/components/table/index.ts +2 -0
- package/src/utils/components/table/select-box.ts +83 -0
- package/src/utils/components/tooltip.ts +186 -0
- package/src/utils/constants.ts +99 -0
- package/src/utils/index.ts +7 -0
- package/src/utils/is.ts +6 -0
- package/src/utils/position.ts +21 -0
- package/src/utils/types.ts +131 -0
- package/src/utils/utils.ts +139 -0
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import type { TableUp } from '..';
|
|
2
|
+
import type { TableCellInnerFormat, TableMainFormat } from '../formats';
|
|
3
|
+
import type { InternalModule, RelactiveRect, TableSelectionOptions } from '../utils';
|
|
4
|
+
import Quill from 'quill';
|
|
5
|
+
import { TableCellFormat } from '../formats';
|
|
6
|
+
import { addScrollEvent, clearScrollEvent, createBEM, getRelativeRect, isRectanglesIntersect } from '../utils';
|
|
7
|
+
|
|
8
|
+
const ERROR_LIMIT = 2;
|
|
9
|
+
export class TableSelection {
|
|
10
|
+
options: TableSelectionOptions;
|
|
11
|
+
boundary: RelactiveRect | null = null;
|
|
12
|
+
startScrollX: number = 0;
|
|
13
|
+
startScrollY: number = 0;
|
|
14
|
+
selectedTableScrollX: number = 0;
|
|
15
|
+
selectedTableScrollY: number = 0;
|
|
16
|
+
selectedEditorScrollX: number = 0;
|
|
17
|
+
selectedEditorScrollY: number = 0;
|
|
18
|
+
selectedTds: TableCellInnerFormat[] = [];
|
|
19
|
+
cellSelectWrap: HTMLElement;
|
|
20
|
+
cellSelect: HTMLElement;
|
|
21
|
+
dragging: boolean = false;
|
|
22
|
+
scrollHandler: [HTMLElement, (...args: any[]) => void][] = [];
|
|
23
|
+
selectingHandler = this.mouseDownHandler.bind(this);
|
|
24
|
+
tableMenu?: InternalModule;
|
|
25
|
+
resizeObserver: ResizeObserver;
|
|
26
|
+
bem = createBEM('selection');
|
|
27
|
+
|
|
28
|
+
constructor(tableModule: TableUp, public table: HTMLElement, public quill: Quill, options: Partial<TableSelectionOptions> = {}) {
|
|
29
|
+
this.options = this.resolveOptions(options);
|
|
30
|
+
|
|
31
|
+
this.cellSelectWrap = tableModule.addContainer(this.bem.b());
|
|
32
|
+
this.cellSelect = this.helpLinesInitial();
|
|
33
|
+
|
|
34
|
+
this.resizeObserver = new ResizeObserver(() => this.hide());
|
|
35
|
+
this.resizeObserver.observe(this.table);
|
|
36
|
+
this.resizeObserver.observe(this.quill.root);
|
|
37
|
+
|
|
38
|
+
this.quill.root.addEventListener('mousedown', this.selectingHandler, false);
|
|
39
|
+
if (this.options.tableMenu) {
|
|
40
|
+
this.tableMenu = new this.options.tableMenu(tableModule, quill, this.options.tableMenuOptions);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
resolveOptions(options: Partial<TableSelectionOptions>): TableSelectionOptions {
|
|
45
|
+
return Object.assign({
|
|
46
|
+
selectColor: '#0589f3',
|
|
47
|
+
tableMenuOptions: {},
|
|
48
|
+
} as TableSelectionOptions, options);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
helpLinesInitial() {
|
|
52
|
+
const cellSelect = document.createElement('div');
|
|
53
|
+
cellSelect.classList.add(this.bem.be('line'));
|
|
54
|
+
Object.assign(cellSelect.style, {
|
|
55
|
+
'border-color': this.options.selectColor,
|
|
56
|
+
});
|
|
57
|
+
this.cellSelectWrap.appendChild(cellSelect);
|
|
58
|
+
return cellSelect;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
computeSelectedTds(startPoint: { x: number; y: number }, endPoint: { x: number; y: number }) {
|
|
62
|
+
type TempSortedTableCellFormat = TableCellFormat & { index?: number; __rect?: DOMRect };
|
|
63
|
+
|
|
64
|
+
// Use TableCell to calculation selected range, because TableCellInner is scrollable, the width will effect calculate
|
|
65
|
+
const tableMain = Quill.find(this.table) as TableMainFormat;
|
|
66
|
+
if (!tableMain) return [];
|
|
67
|
+
const tableCells = new Set((tableMain.descendants(TableCellFormat) as TempSortedTableCellFormat[]).map((cell, i) => {
|
|
68
|
+
cell.index = i;
|
|
69
|
+
return cell;
|
|
70
|
+
}));
|
|
71
|
+
|
|
72
|
+
const { x: tableScrollX, y: tableScrollY } = this.getTableViewScroll();
|
|
73
|
+
const { x: editorScrollX, y: editorScrollY } = this.getQuillViewScroll();
|
|
74
|
+
this.selectedTableScrollX = tableScrollX;
|
|
75
|
+
this.selectedTableScrollY = tableScrollY;
|
|
76
|
+
this.selectedEditorScrollX = editorScrollX;
|
|
77
|
+
this.selectedEditorScrollY = editorScrollY;
|
|
78
|
+
|
|
79
|
+
// set boundary to initially mouse move rectangle
|
|
80
|
+
const tableRect = this.table.getBoundingClientRect();
|
|
81
|
+
const startPointX = startPoint.x - tableScrollX + this.startScrollX;
|
|
82
|
+
const startPointY = startPoint.y - tableScrollY + this.startScrollY;
|
|
83
|
+
let boundary = {
|
|
84
|
+
x: Math.max(tableRect.left, Math.min(endPoint.x, startPointX)),
|
|
85
|
+
y: Math.max(tableRect.top, Math.min(endPoint.y, startPointY)),
|
|
86
|
+
x1: Math.min(tableRect.right, Math.max(endPoint.x, startPointX)),
|
|
87
|
+
y1: Math.min(tableRect.bottom, Math.max(endPoint.y, startPointY)),
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const selectedCells = new Set<TempSortedTableCellFormat>();
|
|
91
|
+
let findEnd = true;
|
|
92
|
+
// loop all cells to find correct boundary
|
|
93
|
+
while (findEnd) {
|
|
94
|
+
findEnd = false;
|
|
95
|
+
for (const cell of tableCells) {
|
|
96
|
+
if (!cell.__rect) {
|
|
97
|
+
cell.__rect = cell.domNode.getBoundingClientRect();
|
|
98
|
+
}
|
|
99
|
+
// Determine whether the cell intersects with the current boundary
|
|
100
|
+
const { x, y, right, bottom } = cell.__rect;
|
|
101
|
+
if (isRectanglesIntersect(boundary, { x, y, x1: right, y1: bottom }, ERROR_LIMIT)) {
|
|
102
|
+
// add cell to selected
|
|
103
|
+
selectedCells.add(cell);
|
|
104
|
+
tableCells.delete(cell);
|
|
105
|
+
// update boundary
|
|
106
|
+
boundary = {
|
|
107
|
+
x: Math.min(boundary.x, x),
|
|
108
|
+
y: Math.min(boundary.y, y),
|
|
109
|
+
x1: Math.max(boundary.x1, right),
|
|
110
|
+
y1: Math.max(boundary.y1, bottom),
|
|
111
|
+
};
|
|
112
|
+
// recalculate boundary last cells
|
|
113
|
+
findEnd = true;
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
else if (x > boundary.x1 && y > boundary.y1) {
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
for (const cell of [...selectedCells, ...tableCells]) {
|
|
122
|
+
delete cell.__rect;
|
|
123
|
+
}
|
|
124
|
+
// save result boundary relative to the editor
|
|
125
|
+
this.boundary = getRelativeRect({
|
|
126
|
+
...boundary,
|
|
127
|
+
width: boundary.x1 - boundary.x,
|
|
128
|
+
height: boundary.y1 - boundary.y,
|
|
129
|
+
}, this.quill.root);
|
|
130
|
+
return Array.from(selectedCells).sort((a, b) => a.index! - b.index!).map((cell) => {
|
|
131
|
+
delete cell.index;
|
|
132
|
+
return cell.getCellInner();
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
mouseDownHandler(mousedownEvent: MouseEvent) {
|
|
137
|
+
const { button, target, clientX, clientY } = mousedownEvent;
|
|
138
|
+
const closestTable = (target as HTMLElement).closest('.ql-table') as HTMLElement;
|
|
139
|
+
if (button !== 0 || !closestTable) return;
|
|
140
|
+
|
|
141
|
+
const startTableId = closestTable.dataset.tableId;
|
|
142
|
+
const startPoint = { x: clientX, y: clientY };
|
|
143
|
+
const { x: tableScrollX, y: tableScrollY } = this.getTableViewScroll();
|
|
144
|
+
this.startScrollX = tableScrollX;
|
|
145
|
+
this.startScrollY = tableScrollY;
|
|
146
|
+
this.selectedTds = this.computeSelectedTds(startPoint, startPoint);
|
|
147
|
+
this.show();
|
|
148
|
+
if (this.tableMenu) {
|
|
149
|
+
this.tableMenu.hide();
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const mouseMoveHandler = (mousemoveEvent: MouseEvent) => {
|
|
153
|
+
const { button, target, clientX, clientY } = mousemoveEvent;
|
|
154
|
+
const closestTable = (target as HTMLElement).closest('.ql-table') as HTMLElement;
|
|
155
|
+
if (
|
|
156
|
+
button !== 0
|
|
157
|
+
|| !closestTable
|
|
158
|
+
|| closestTable.dataset.tableId !== startTableId
|
|
159
|
+
) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
this.dragging = true;
|
|
164
|
+
const movePoint = { x: clientX, y: clientY };
|
|
165
|
+
this.selectedTds = this.computeSelectedTds(startPoint, movePoint);
|
|
166
|
+
if (this.selectedTds.length > 1) {
|
|
167
|
+
this.quill.blur();
|
|
168
|
+
}
|
|
169
|
+
this.update();
|
|
170
|
+
};
|
|
171
|
+
const mouseUpHandler = () => {
|
|
172
|
+
document.body.removeEventListener('mousemove', mouseMoveHandler, false);
|
|
173
|
+
document.body.removeEventListener('mouseup', mouseUpHandler, false);
|
|
174
|
+
this.dragging = false;
|
|
175
|
+
this.startScrollX = 0;
|
|
176
|
+
this.startScrollY = 0;
|
|
177
|
+
if (this.tableMenu) {
|
|
178
|
+
this.tableMenu.update();
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
document.body.addEventListener('mousemove', mouseMoveHandler, false);
|
|
183
|
+
document.body.addEventListener('mouseup', mouseUpHandler, false);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
update() {
|
|
187
|
+
if (this.selectedTds.length === 0 || !this.boundary) return;
|
|
188
|
+
const { x: editorScrollX, y: editorScrollY } = this.getQuillViewScroll();
|
|
189
|
+
const { x: tableScrollX, y: tableScrollY } = this.getTableViewScroll();
|
|
190
|
+
const tableWrapperRect = this.table.parentElement!.getBoundingClientRect();
|
|
191
|
+
const rootRect = this.quill.root.getBoundingClientRect();
|
|
192
|
+
const wrapLeft = tableWrapperRect.x - rootRect.x;
|
|
193
|
+
const wrapTop = tableWrapperRect.y - rootRect.y;
|
|
194
|
+
|
|
195
|
+
Object.assign(this.cellSelect.style, {
|
|
196
|
+
left: `${this.selectedEditorScrollX * 2 - editorScrollX + this.boundary.x + this.selectedTableScrollX - tableScrollX - wrapLeft}px`,
|
|
197
|
+
top: `${this.selectedEditorScrollY * 2 - editorScrollY + this.boundary.y + this.selectedTableScrollY - tableScrollY - wrapTop}px`,
|
|
198
|
+
width: `${this.boundary.width}px`,
|
|
199
|
+
height: `${this.boundary.height}px`,
|
|
200
|
+
});
|
|
201
|
+
Object.assign(this.cellSelectWrap.style, {
|
|
202
|
+
left: `${wrapLeft}px`,
|
|
203
|
+
top: `${wrapTop}px`,
|
|
204
|
+
width: `${tableWrapperRect.width + 2}px`,
|
|
205
|
+
height: `${tableWrapperRect.height + 2}px`,
|
|
206
|
+
});
|
|
207
|
+
if (!this.dragging && this.tableMenu) {
|
|
208
|
+
this.tableMenu.update();
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
getQuillViewScroll() {
|
|
213
|
+
return {
|
|
214
|
+
x: this.quill.root.scrollLeft,
|
|
215
|
+
y: this.quill.root.scrollTop,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
getTableViewScroll() {
|
|
220
|
+
return {
|
|
221
|
+
x: this.table.parentElement!.scrollLeft,
|
|
222
|
+
y: this.table.parentElement!.scrollTop,
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
show() {
|
|
227
|
+
clearScrollEvent.call(this);
|
|
228
|
+
|
|
229
|
+
Object.assign(this.cellSelectWrap.style, { display: 'block' });
|
|
230
|
+
this.update();
|
|
231
|
+
|
|
232
|
+
addScrollEvent.call(this, this.quill.root, () => {
|
|
233
|
+
this.update();
|
|
234
|
+
});
|
|
235
|
+
addScrollEvent.call(this, this.table.parentElement!, () => {
|
|
236
|
+
this.update();
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
hide() {
|
|
241
|
+
this.boundary = null;
|
|
242
|
+
this.selectedTds = [];
|
|
243
|
+
this.cellSelectWrap && Object.assign(this.cellSelectWrap.style, { display: 'none' });
|
|
244
|
+
if (this.tableMenu) {
|
|
245
|
+
this.tableMenu.hide();
|
|
246
|
+
}
|
|
247
|
+
clearScrollEvent.call(this);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
destroy() {
|
|
251
|
+
this.resizeObserver.disconnect();
|
|
252
|
+
this.hide();
|
|
253
|
+
this.cellSelectWrap.remove();
|
|
254
|
+
if (this.tableMenu) {
|
|
255
|
+
this.tableMenu.destroy();
|
|
256
|
+
}
|
|
257
|
+
clearScrollEvent.call(this);
|
|
258
|
+
|
|
259
|
+
this.quill.root.removeEventListener('mousedown', this.selectingHandler, false);
|
|
260
|
+
return null;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
@import './variables.less';
|
|
2
|
+
@import './functions.less';
|
|
3
|
+
|
|
4
|
+
.@{namespace}-button {
|
|
5
|
+
.setCssVar(table-btn-color, #606266);
|
|
6
|
+
.setCssVar(table-btn-bg-hover, #f3f4f6);
|
|
7
|
+
.setCssVar(table-btn-color-border, #dcdfe6);
|
|
8
|
+
.setCssVar(table-btn-border, 1px solid .getCssVar(table-btn-color-border) []);
|
|
9
|
+
.setCssVar(table-btn-confirm-color-border, #409eff);
|
|
10
|
+
.setCssVar(table-btn-confirm-bg, #409eff);
|
|
11
|
+
.setCssVar(table-btn-confirm-hover, #79bbff);
|
|
12
|
+
.setCssVar(table-btn-confirm-outline-focus-visible, 2px solid #a0cfff);
|
|
13
|
+
|
|
14
|
+
box-sizing: border-box;
|
|
15
|
+
display: inline-flex;
|
|
16
|
+
height: 32px;
|
|
17
|
+
line-height: 1;
|
|
18
|
+
margin: 0;
|
|
19
|
+
padding: 8px 16px;
|
|
20
|
+
border-radius: 4px;
|
|
21
|
+
border: .getCssVar(table-btn-border) [];
|
|
22
|
+
color: .getCssVar(table-btn-color) [];
|
|
23
|
+
background-color: transparent;
|
|
24
|
+
font-size: 14px;
|
|
25
|
+
cursor: pointer;
|
|
26
|
+
& + & {
|
|
27
|
+
margin-left: 6px;
|
|
28
|
+
}
|
|
29
|
+
&:hover {
|
|
30
|
+
background-color: .getCssVar(table-btn-bg-hover) [];
|
|
31
|
+
}
|
|
32
|
+
&.confirm {
|
|
33
|
+
border-color: .getCssVar(table-btn-confirm-color-border) [];
|
|
34
|
+
background-color: .getCssVar(table-btn-confirm-bg) [];
|
|
35
|
+
color: #fff;
|
|
36
|
+
&:hover {
|
|
37
|
+
border-color: .getCssVar(table-btn-confirm-hover) [];
|
|
38
|
+
background-color: .getCssVar(table-btn-confirm-hover) [];
|
|
39
|
+
}
|
|
40
|
+
&:focus-visible {
|
|
41
|
+
outline: .getCssVar(table-btn-confirm-outline-focus-visible) [];
|
|
42
|
+
outline-offset: 1px;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
@import './variables.less';
|
|
2
|
+
|
|
3
|
+
@panelWidth: 230px;
|
|
4
|
+
@panelHeight: 150px;
|
|
5
|
+
@barSize: 12px;
|
|
6
|
+
@handleSize: 16px;
|
|
7
|
+
@handleSizeSec: 10px;
|
|
8
|
+
@barGap: 10px;
|
|
9
|
+
@contentPadding: 8px;
|
|
10
|
+
|
|
11
|
+
.handle(@isBlock: false) {
|
|
12
|
+
box-sizing: border-box;
|
|
13
|
+
position: absolute;
|
|
14
|
+
border: 1px solid #ffffff;
|
|
15
|
+
cursor: pointer;
|
|
16
|
+
|
|
17
|
+
& when(@isBlock) {
|
|
18
|
+
background-color: #ffffff;
|
|
19
|
+
box-shadow: 0 0 2px #0009;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.@{namespace}-color-picker {
|
|
24
|
+
.setCssVar(color-picker-bg-color, #ffffff);
|
|
25
|
+
|
|
26
|
+
box-sizing: border-box;
|
|
27
|
+
display: inline-flex;
|
|
28
|
+
flex-direction: column;
|
|
29
|
+
width: @panelWidth + @contentPadding * 2 + @barSize + @barGap;
|
|
30
|
+
padding: @contentPadding;
|
|
31
|
+
border-radius: 6px;
|
|
32
|
+
background: .getCssVar(color-picker-bg-color) [];
|
|
33
|
+
box-shadow: 0 0 6px #b2b5b8;
|
|
34
|
+
|
|
35
|
+
&__content {
|
|
36
|
+
box-sizing: border-box;
|
|
37
|
+
width: 100%;
|
|
38
|
+
height: @panelHeight + @contentPadding * 2 + @barSize + @barGap;
|
|
39
|
+
padding-top: @contentPadding;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
&__selector {
|
|
43
|
+
width: @panelWidth;
|
|
44
|
+
height: @panelHeight;
|
|
45
|
+
position: absolute;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
&__background {
|
|
49
|
+
width: 100%;
|
|
50
|
+
height: 100%;
|
|
51
|
+
background: linear-gradient(to top, #000 0%, rgba(0, 0, 0, 0) 100%),
|
|
52
|
+
linear-gradient(to right, #fff 0%, rgba(255, 255, 255, 0) 100%);
|
|
53
|
+
&-handle {
|
|
54
|
+
.handle();
|
|
55
|
+
@size: 10px;
|
|
56
|
+
top: 0px;
|
|
57
|
+
left: @panelWidth;
|
|
58
|
+
border-radius: 100%;
|
|
59
|
+
width: @size;
|
|
60
|
+
height: @size;
|
|
61
|
+
transform: translate(-1 * (@size / 2), -1 * (@size / 2));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
&__hue {
|
|
66
|
+
width: @barSize;
|
|
67
|
+
height: @panelHeight;
|
|
68
|
+
margin-left: @panelWidth + @barGap;
|
|
69
|
+
position: absolute;
|
|
70
|
+
background: linear-gradient(0deg, red 0, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, red);
|
|
71
|
+
&-handle {
|
|
72
|
+
.handle(true);
|
|
73
|
+
left: 0;
|
|
74
|
+
width: @handleSize;
|
|
75
|
+
height: @handleSizeSec;
|
|
76
|
+
transform: translate(((@barSize - @handleSize) / 2), (-1 * @handleSizeSec / 2));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
&__alpha {
|
|
81
|
+
width: @panelWidth;
|
|
82
|
+
height: @barSize;
|
|
83
|
+
position: absolute;
|
|
84
|
+
margin-top: @panelHeight + @barGap;
|
|
85
|
+
background: linear-gradient(45deg, #ccc 25%, transparent 25%), linear-gradient(135deg, #ccc 25%, transparent 25%),
|
|
86
|
+
linear-gradient(45deg, transparent 75%, #ccc 75%), linear-gradient(135deg, transparent 75%, #ccc 75%);
|
|
87
|
+
background-size: @barSize @barSize;
|
|
88
|
+
background-position:
|
|
89
|
+
0 0,
|
|
90
|
+
(@barSize / 2) 0,
|
|
91
|
+
(@barSize / 2) (-1 * @barSize / 2),
|
|
92
|
+
0 (@barSize / 2);
|
|
93
|
+
&-bg {
|
|
94
|
+
position: relative;
|
|
95
|
+
height: 100%;
|
|
96
|
+
background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%);
|
|
97
|
+
}
|
|
98
|
+
&-handle {
|
|
99
|
+
.handle(true);
|
|
100
|
+
top: 0;
|
|
101
|
+
width: @handleSizeSec;
|
|
102
|
+
height: @handleSize;
|
|
103
|
+
transform: translate((-1 * @handleSizeSec / 2), ((@barSize - @handleSize) / 2));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
&__action {
|
|
107
|
+
box-sizing: border-box;
|
|
108
|
+
display: flex;
|
|
109
|
+
align-items: center;
|
|
110
|
+
gap: 6px;
|
|
111
|
+
width: 100%;
|
|
112
|
+
padding-top: @contentPadding;
|
|
113
|
+
border-top: 1px solid #e9ecef;
|
|
114
|
+
&-item {
|
|
115
|
+
flex: 1;
|
|
116
|
+
display: inline-flex;
|
|
117
|
+
align-items: center;
|
|
118
|
+
font-size: 12px;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
&__input {
|
|
123
|
+
box-sizing: border-box;
|
|
124
|
+
width: 100%;
|
|
125
|
+
height: 22px;
|
|
126
|
+
margin-left: 2px;
|
|
127
|
+
padding: 2px 0px 2px 4px;
|
|
128
|
+
background-color: #ffffff;
|
|
129
|
+
border: 1px solid #ced4da;
|
|
130
|
+
border-radius: 4px;
|
|
131
|
+
outline: none;
|
|
132
|
+
color: #405057;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
@import './variables.less';
|
|
2
|
+
@import './functions.less';
|
|
3
|
+
@import './button.less';
|
|
4
|
+
|
|
5
|
+
.@{namespace}-dialog {
|
|
6
|
+
.setCssVar(dialog-bg, rgba(0, 0, 0, 0.5));
|
|
7
|
+
.setCssVar(dialog-color-border, #ebeef5);
|
|
8
|
+
.setCssVar(dialog-color-boxshadow, rgba(0, 0, 0, 0.12));
|
|
9
|
+
.setCssVar(dialog-border, 1px solid .getCssVar(dialog-color-border) []);
|
|
10
|
+
.setCssVar(dialog-boxshadow, 0px 0px 12px .getCssVar(dialog-color-boxshadow) []);
|
|
11
|
+
|
|
12
|
+
position: fixed;
|
|
13
|
+
top: 0;
|
|
14
|
+
right: 0;
|
|
15
|
+
bottom: 0;
|
|
16
|
+
left: 0;
|
|
17
|
+
z-index: 2000;
|
|
18
|
+
height: 100%;
|
|
19
|
+
background-color: .getCssVar(dialog-bg) [];
|
|
20
|
+
overflow: auto;
|
|
21
|
+
&__overlay {
|
|
22
|
+
position: fixed;
|
|
23
|
+
top: 0;
|
|
24
|
+
right: 0;
|
|
25
|
+
bottom: 0;
|
|
26
|
+
left: 0;
|
|
27
|
+
padding: 16px;
|
|
28
|
+
overflow: auto;
|
|
29
|
+
text-align: center;
|
|
30
|
+
&::after {
|
|
31
|
+
content: '';
|
|
32
|
+
display: inline-block;
|
|
33
|
+
height: 100%;
|
|
34
|
+
width: 0;
|
|
35
|
+
vertical-align: middle;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
&__content {
|
|
39
|
+
box-sizing: border-box;
|
|
40
|
+
display: inline-block;
|
|
41
|
+
max-width: 50vw;
|
|
42
|
+
width: 100%;
|
|
43
|
+
vertical-align: middle;
|
|
44
|
+
background-color: #fff;
|
|
45
|
+
border-radius: 4px;
|
|
46
|
+
border: .getCssVar(dialog-border) [];
|
|
47
|
+
font-size: 18px;
|
|
48
|
+
box-shadow: .getCssVar(dialog-boxshadow) [];
|
|
49
|
+
text-align: left;
|
|
50
|
+
overflow: hidden;
|
|
51
|
+
box-sizing: border-box;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
.ql-toolbar {
|
|
2
|
+
.ql-picker:not(.ql-color-picker):not(.ql-icon-picker).ql-table-up {
|
|
3
|
+
width: 28px;
|
|
4
|
+
.ql-picker-label {
|
|
5
|
+
padding: 2px 4px;
|
|
6
|
+
svg {
|
|
7
|
+
position: static;
|
|
8
|
+
margin-top: 0;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
.ql-picker.ql-expanded .ql-picker-options {
|
|
13
|
+
z-index: 1;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.ql-editor {
|
|
18
|
+
.ql {
|
|
19
|
+
&-table {
|
|
20
|
+
display: table;
|
|
21
|
+
border-collapse: collapse;
|
|
22
|
+
table-layout: fixed;
|
|
23
|
+
width: auto;
|
|
24
|
+
&[data-full] {
|
|
25
|
+
width: 100%;
|
|
26
|
+
}
|
|
27
|
+
&-wrapper {
|
|
28
|
+
width: 100%;
|
|
29
|
+
overflow: auto;
|
|
30
|
+
scrollbar-width: none;
|
|
31
|
+
}
|
|
32
|
+
&-cell {
|
|
33
|
+
padding: 8px 12px;
|
|
34
|
+
border-color: transparent;
|
|
35
|
+
font-size: 14px;
|
|
36
|
+
outline: none;
|
|
37
|
+
overflow: auto;
|
|
38
|
+
&-inner {
|
|
39
|
+
display: inline-block;
|
|
40
|
+
min-width: 100%;
|
|
41
|
+
word-break: break-word;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
col {
|
|
45
|
+
border-collapse: separate;
|
|
46
|
+
text-indent: initial;
|
|
47
|
+
display: table-column;
|
|
48
|
+
table-layout: fixed;
|
|
49
|
+
}
|
|
50
|
+
td {
|
|
51
|
+
border: 1px solid #a1a1aa;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.@{namespace} {
|
|
58
|
+
&-toolbox {
|
|
59
|
+
position: absolute;
|
|
60
|
+
top: 0px;
|
|
61
|
+
left: 0px;
|
|
62
|
+
width: 100%;
|
|
63
|
+
height: 100%;
|
|
64
|
+
overflow: hidden;
|
|
65
|
+
pointer-events: none;
|
|
66
|
+
* {
|
|
67
|
+
pointer-events: all;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@import './tooltip.less';
|
|
73
|
+
@import './dialog.less';
|
|
74
|
+
@import './color-picker.less';
|
|
75
|
+
|
|
76
|
+
.@{namespace}-tooltip {
|
|
77
|
+
.@{namespace}-color-picker {
|
|
78
|
+
.setCssVar(color-picker-bg-color, transparent);
|
|
79
|
+
box-shadow: none;
|
|
80
|
+
width: 252px;
|
|
81
|
+
padding: 8px 0px;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
@import './table-selection.less';
|
|
86
|
+
@import './table-resize.less';
|
|
87
|
+
@import './table-resize-scale.less';
|
|
88
|
+
@import './table-scrollbar.less';
|
|
89
|
+
@import './table-menu.less';
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
@import './variables.less';
|
|
2
|
+
@import './functions.less';
|
|
3
|
+
|
|
4
|
+
.@{namespace}-input {
|
|
5
|
+
&__item {
|
|
6
|
+
.setCssVar(input-height, 32px);
|
|
7
|
+
.setCssVar(input-inner-height, calc(.getCssVar(input-height) [] - 2px));
|
|
8
|
+
.setCssVar(input-color-text, #606266);
|
|
9
|
+
.setCssVar(input-color-boxshaow, #dcdfe6);
|
|
10
|
+
.setCssVar(input-color-focus, #409eff);
|
|
11
|
+
.setCssVar(input-color-error, #f56c6c);
|
|
12
|
+
.setCssVar(input-boxshaow, 0 0 0 1px .getCssVar(input-color-boxshaow) [] inset);
|
|
13
|
+
.setCssVar(input-boxshaow-focus, 0 0 0 1px .getCssVar(input-color-focus) [] inset);
|
|
14
|
+
.setCssVar(input-boxshaow-error, 0 0 0 1px .getCssVar(input-color-error) [] inset);
|
|
15
|
+
|
|
16
|
+
display: flex;
|
|
17
|
+
align-items: center;
|
|
18
|
+
& + & {
|
|
19
|
+
margin-top: 18px;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
&__label {
|
|
23
|
+
width: 80px;
|
|
24
|
+
flex-shrink: 0;
|
|
25
|
+
}
|
|
26
|
+
&__input {
|
|
27
|
+
box-sizing: border-box;
|
|
28
|
+
position: relative;
|
|
29
|
+
display: flex;
|
|
30
|
+
flex-wrap: wrap;
|
|
31
|
+
width: 100%;
|
|
32
|
+
height: .getCssVar(input-height) [];
|
|
33
|
+
line-height: .getCssVar(input-height) [];
|
|
34
|
+
padding: 1px 8px;
|
|
35
|
+
border-radius: 4px;
|
|
36
|
+
box-shadow: .getCssVar(input-boxshaow) [];
|
|
37
|
+
transition: box-shadow 0.2s linear;
|
|
38
|
+
&.focus {
|
|
39
|
+
box-shadow: .getCssVar(input-boxshaow-focus) [];
|
|
40
|
+
}
|
|
41
|
+
input {
|
|
42
|
+
width: 100%;
|
|
43
|
+
height: .getCssVar(input-inner-height) [];
|
|
44
|
+
line-height: .getCssVar(input-inner-height) [];
|
|
45
|
+
flex-grow: 1;
|
|
46
|
+
font-size: 14px;
|
|
47
|
+
color: .getCssVar(input-color-text) [];
|
|
48
|
+
outline: none;
|
|
49
|
+
border: 0;
|
|
50
|
+
padding: 0;
|
|
51
|
+
}
|
|
52
|
+
&.error {
|
|
53
|
+
box-shadow: .getCssVar(input-boxshaow-error) [];
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
&__error-tip {
|
|
57
|
+
position: absolute;
|
|
58
|
+
top: 100%;
|
|
59
|
+
left: 0;
|
|
60
|
+
font-size: 12px;
|
|
61
|
+
color: .getCssVar(input-color-error) [];
|
|
62
|
+
line-height: 16px;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
@import './variables.less';
|
|
2
|
+
@import './functions.less';
|
|
3
|
+
|
|
4
|
+
.ql-snow {
|
|
5
|
+
.@{namespace}-select-box {
|
|
6
|
+
.setCssVar(select-box-color-bg-hover, rgb(245, 245, 245));
|
|
7
|
+
.setCssVar(select-box-color-bg-active, rgb(224, 242, 254));
|
|
8
|
+
.setCssVar(select-box-custom-color-text, rgb(13, 13, 13));
|
|
9
|
+
.setCssVar(select-box-custom-color-bg, transparent);
|
|
10
|
+
.setCssVar(select-box-custom-color-bg-hover, rgb(235, 235, 235));
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
.@{namespace}-select-box {
|
|
14
|
+
.setCssVar(select-box-color-border, #e5e7eb);
|
|
15
|
+
.setCssVar(select-box-border, 1px solid .getCssVar(select-box-color-border) []);
|
|
16
|
+
.setCssVar(select-box-color-active, rgb(14, 165, 233));
|
|
17
|
+
.setCssVar(select-box-color-bg-hover, rgb(245, 245, 245));
|
|
18
|
+
.setCssVar(select-box-color-bg-active, transparent);
|
|
19
|
+
.setCssVar(select-box-custom-color-text, rgb(245, 245, 245));
|
|
20
|
+
.setCssVar(select-box-custom-color-bg, transparent);
|
|
21
|
+
.setCssVar(select-box-custom-color-bg-hover, rgb(44, 44, 44));
|
|
22
|
+
|
|
23
|
+
&__block {
|
|
24
|
+
display: flex;
|
|
25
|
+
width: 160px;
|
|
26
|
+
flex-wrap: wrap;
|
|
27
|
+
align-items: center;
|
|
28
|
+
justify-content: center;
|
|
29
|
+
}
|
|
30
|
+
&__item {
|
|
31
|
+
margin: 2px;
|
|
32
|
+
height: 16px;
|
|
33
|
+
width: 16px;
|
|
34
|
+
border: .getCssVar(select-box-border) [];
|
|
35
|
+
&.active {
|
|
36
|
+
border-color: .getCssVar(select-box-color-active) [];
|
|
37
|
+
background-color: .getCssVar(select-box-color-bg-active) [];
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
&__custom {
|
|
41
|
+
padding: 8px;
|
|
42
|
+
color: .getCssVar(select-box-custom-color-text) [];
|
|
43
|
+
background-color: .getCssVar(select-box-custom-color-bg) [];
|
|
44
|
+
font-size: 16px;
|
|
45
|
+
text-align: center;
|
|
46
|
+
cursor: pointer;
|
|
47
|
+
&:hover {
|
|
48
|
+
background-color: .getCssVar(select-box-custom-color-bg-hover) [];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|