stk-table-vue 0.1.0 → 0.2.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.
@@ -1,1441 +1,1490 @@
1
- import { onMounted, onBeforeUnmount, watch, ref, computed, defineComponent, shallowRef, toRaw, openBlock, createElementBlock, normalizeClass, unref, normalizeStyle, withDirectives, createElementVNode, vShow, Fragment, renderList, createCommentVNode, createBlock, resolveDynamicComponent, renderSlot, toDisplayString, createTextVNode } from "vue";
2
- import { interpolateRgb } from "d3-interpolate";
3
- const Default_Col_Width = "100";
4
- const Default_Table_Height = 100;
5
- const Default_Table_Width = 200;
6
- const Default_Row_Height = 28;
7
- const Highlight_Color = {
8
- light: { from: "#71a2fd", to: "#fff" },
9
- dark: { from: "#1e4c99", to: "#181c21" }
10
- };
11
- const Highlight_Duration = 2e3;
12
- const Highlight_Color_Change_Freq = 100;
13
- let _chromeVersion = 0;
14
- try {
15
- const userAgent = navigator.userAgent.match(/chrome\/\d+/i);
16
- if (userAgent) {
17
- _chromeVersion = +userAgent[0].split("/")[1];
18
- }
19
- } catch (e) {
20
- console.error("Cannot get Chrome version", e);
21
- }
22
- const Is_Legacy_Mode = _chromeVersion < 56;
23
- function useAutoResize({ tableContainer, initVirtualScroll, scrollTo, props, debounceMs }) {
24
- let resizeObserver = null;
25
- onMounted(() => {
26
- initResizeObserver();
27
- });
28
- onBeforeUnmount(() => {
29
- removeResizeObserver();
30
- });
31
- function initResizeObserver() {
32
- if (window.ResizeObserver) {
33
- if (!tableContainer.value) {
34
- const watchDom = watch(
35
- () => tableContainer,
36
- () => {
37
- initResizeObserver();
38
- watchDom();
39
- }
40
- );
41
- return;
42
- }
43
- resizeObserver = new ResizeObserver(resizeCallback);
44
- resizeObserver.observe(tableContainer.value);
45
- } else {
46
- window.addEventListener("resize", resizeCallback);
47
- }
48
- }
49
- function removeResizeObserver() {
50
- if (resizeObserver) {
51
- resizeObserver.disconnect();
52
- resizeObserver = null;
53
- } else {
54
- window.removeEventListener("resize", resizeCallback);
55
- }
56
- }
57
- let debounceTime = 0;
58
- function resizeCallback() {
59
- if (debounceTime) {
60
- window.clearTimeout(debounceTime);
61
- }
62
- debounceTime = window.setTimeout(() => {
63
- if (props.autoResize) {
64
- initVirtualScroll();
65
- if (typeof props.autoResize === "function") {
66
- props.autoResize();
67
- }
68
- }
69
- debounceTime = 0;
70
- }, debounceMs);
71
- }
72
- }
73
- function useColResize({
74
- tableContainer,
75
- tableHeaderLast,
76
- colResizeIndicator,
77
- props,
78
- emits,
79
- colKeyGen
80
- }) {
81
- const isColResizing = ref(false);
82
- let colResizeState = {
83
- currentCol: null,
84
- currentColIndex: 0,
85
- lastCol: null,
86
- startX: 0,
87
- startOffsetTableX: 0
88
- };
89
- onMounted(() => {
90
- initColResizeEvent();
91
- });
92
- onBeforeUnmount(() => {
93
- clearColResizeEvent();
94
- });
95
- function initColResizeEvent() {
96
- window.addEventListener("mousemove", onThResizeMouseMove);
97
- window.addEventListener("mouseup", onThResizeMouseUp);
98
- }
99
- function clearColResizeEvent() {
100
- window.removeEventListener("mousemove", onThResizeMouseMove);
101
- window.removeEventListener("mouseup", onThResizeMouseUp);
102
- }
103
- function onThResizeMouseDown(e, col, isPrev = false) {
104
- if (!tableContainer.value)
105
- return;
106
- e.stopPropagation();
107
- e.preventDefault();
108
- const { clientX } = e;
109
- const { scrollLeft, scrollTop } = tableContainer.value;
110
- const { left } = tableContainer.value.getBoundingClientRect();
111
- let colIndex = tableHeaderLast.value.findIndex((it) => colKeyGen(it) === colKeyGen(col));
112
- if (isPrev) {
113
- colIndex -= 1;
114
- col = tableHeaderLast.value[colIndex];
115
- }
116
- const offsetTableX = clientX - left + scrollLeft;
117
- isColResizing.value = true;
118
- Object.assign(colResizeState, {
119
- currentCol: col,
120
- currentColIndex: colIndex,
121
- lastCol: findLastChildCol(col),
122
- startX: clientX,
123
- startOffsetTableX: offsetTableX
124
- });
125
- if (colResizeIndicator.value) {
126
- const style = colResizeIndicator.value.style;
127
- style.display = "block";
128
- style.left = offsetTableX + "px";
129
- style.top = scrollTop + "px";
130
- }
131
- }
132
- function onThResizeMouseMove(e) {
133
- if (!isColResizing.value)
134
- return;
135
- e.stopPropagation();
136
- e.preventDefault();
137
- const { lastCol, startX, startOffsetTableX } = colResizeState;
138
- const { clientX } = e;
139
- let moveX = clientX - startX;
140
- const currentColWidth = parseInt((lastCol == null ? void 0 : lastCol.width) || Default_Col_Width);
141
- if (currentColWidth + moveX < props.colMinWidth) {
142
- moveX = -currentColWidth;
143
- }
144
- const offsetTableX = startOffsetTableX + moveX;
145
- if (!colResizeIndicator.value)
146
- return;
147
- colResizeIndicator.value.style.left = offsetTableX + "px";
148
- }
149
- function onThResizeMouseUp(e) {
150
- if (!isColResizing.value)
151
- return;
152
- const { startX, lastCol } = colResizeState;
153
- const { clientX } = e;
154
- const moveX = clientX - startX;
155
- let width = parseInt((lastCol == null ? void 0 : lastCol.width) || Default_Col_Width) + moveX;
156
- if (width < props.colMinWidth)
157
- width = props.colMinWidth;
158
- const curCol = tableHeaderLast.value.find((it) => colKeyGen(it) === colKeyGen(lastCol));
159
- if (!curCol)
160
- return;
161
- curCol.width = width + "px";
162
- emits("update:columns", [...props.columns]);
163
- if (colResizeIndicator.value) {
164
- const style = colResizeIndicator.value.style;
165
- style.display = "none";
166
- style.left = "0";
167
- style.top = "0";
168
- }
169
- isColResizing.value = false;
170
- colResizeState = {
171
- currentCol: null,
172
- currentColIndex: 0,
173
- lastCol: null,
174
- startX: 0,
175
- startOffsetTableX: 0
176
- };
177
- }
178
- function findLastChildCol(column) {
179
- var _a;
180
- if ((_a = column == null ? void 0 : column.children) == null ? void 0 : _a.length) {
181
- const lastChild = column.children.at(-1);
182
- return findLastChildCol(lastChild);
183
- }
184
- return column;
185
- }
186
- return {
187
- isColResizing,
188
- onThResizeMouseDown,
189
- onThResizeMouseMove,
190
- onThResizeMouseUp
191
- };
192
- }
193
- function useFixedStyle({ props, tableHeaderLast, virtualScroll, virtualScrollX, virtualX_on, virtualX_offsetRight }) {
194
- const fixedColumnsPositionStore = computed(() => {
195
- const store = {};
196
- const cols = [...tableHeaderLast.value];
197
- let left = 0;
198
- let rightStartIndex = 0;
199
- for (let i = 0; i < cols.length; i++) {
200
- const item = cols[i];
201
- if (item.fixed === "left") {
202
- store[item.dataIndex] = left;
203
- left += parseInt(item.width || Default_Col_Width);
204
- }
205
- if (!rightStartIndex && item.fixed === "right") {
206
- rightStartIndex = i;
207
- }
208
- }
209
- let right = 0;
210
- for (let i = cols.length - 1; i >= rightStartIndex; i--) {
211
- const item = cols[i];
212
- if (item.fixed === "right") {
213
- store[item.dataIndex] = right;
214
- right += parseInt(item.width || Default_Col_Width);
215
- }
216
- }
217
- return store;
218
- });
219
- function getFixedStyle(tagType, col, depth = 0) {
220
- const { fixed, dataIndex } = col;
221
- const isFixedLeft = fixed === "left";
222
- const style = {};
223
- if (Is_Legacy_Mode) {
224
- style.position = "relative";
225
- } else {
226
- style.position = "sticky";
227
- }
228
- if (tagType === 1) {
229
- if (Is_Legacy_Mode) {
230
- style.top = virtualScroll.value.scrollTop + depth * props.rowHeight + "px";
231
- } else {
232
- style.top = depth * props.rowHeight + "px";
233
- }
234
- style.zIndex = isFixedLeft ? "5" : "4";
235
- } else {
236
- style.zIndex = isFixedLeft ? "3" : "2";
237
- }
238
- if (fixed === "left" || fixed === "right") {
239
- if (Is_Legacy_Mode) {
240
- if (isFixedLeft) {
241
- if (virtualX_on.value)
242
- style.left = virtualScrollX.value.scrollLeft - virtualScrollX.value.offsetLeft + "px";
243
- else
244
- style.left = virtualScrollX.value.scrollLeft + "px";
245
- } else {
246
- style.right = `${virtualX_offsetRight.value}px`;
247
- }
248
- } else {
249
- if (isFixedLeft) {
250
- style.left = fixedColumnsPositionStore.value[dataIndex] + "px";
251
- } else {
252
- style.right = fixedColumnsPositionStore.value[dataIndex] + "px";
253
- }
254
- }
255
- }
256
- return style;
257
- }
258
- return {
259
- getFixedStyle
260
- };
261
- }
262
- function useHighlight({ props, tableContainer, rowKeyGen }) {
263
- const highlightInter = computed(() => {
264
- return interpolateRgb(Highlight_Color[props.theme].from, Highlight_Color[props.theme].to);
265
- });
266
- const highlightDimRows = /* @__PURE__ */ new Set();
267
- const highlightDimRowsTimeout = /* @__PURE__ */ new Map();
268
- const highlightDimCellsTimeout = /* @__PURE__ */ new Map();
269
- let calcHighlightDimLoop = false;
270
- function calcHighlightLoop() {
271
- if (calcHighlightDimLoop)
272
- return;
273
- calcHighlightDimLoop = true;
274
- const recursion = () => {
275
- window.setTimeout(() => {
276
- const nowTs = Date.now();
277
- const needDeleteRows = [];
278
- highlightDimRows.forEach((row) => {
279
- const progress = (nowTs - row._bgc_progress_ms) / Highlight_Duration;
280
- if (0 < progress && progress < 1) {
281
- row._bgc = highlightInter.value(progress);
282
- } else {
283
- row._bgc = "";
284
- needDeleteRows.push(row);
285
- }
286
- });
287
- needDeleteRows.forEach((row) => highlightDimRows.delete(row));
288
- if (highlightDimRows.size > 0) {
289
- recursion();
290
- } else {
291
- calcHighlightDimLoop = false;
292
- }
293
- }, Highlight_Color_Change_Freq);
294
- };
295
- recursion();
296
- }
297
- function setHighlightDimCell(rowKeyValue, dataIndex) {
298
- var _a;
299
- const cellEl = (_a = tableContainer.value) == null ? void 0 : _a.querySelector(`[data-row-key="${rowKeyValue}"]>[data-index="${dataIndex}"]`);
300
- if (!cellEl)
301
- return;
302
- if (cellEl.classList.contains("highlight-cell")) {
303
- cellEl.classList.remove("highlight-cell");
304
- void cellEl.offsetHeight;
305
- }
306
- cellEl.classList.add("highlight-cell");
307
- window.clearTimeout(highlightDimCellsTimeout.get(rowKeyValue));
308
- highlightDimCellsTimeout.set(
309
- rowKeyValue,
310
- window.setTimeout(() => {
311
- cellEl.classList.remove("highlight-cell");
312
- highlightDimCellsTimeout.delete(rowKeyValue);
313
- }, Highlight_Duration)
314
- );
315
- }
316
- function setHighlightDimRow(rowKeyValues) {
317
- var _a, _b;
318
- if (!Array.isArray(rowKeyValues))
319
- rowKeyValues = [rowKeyValues];
320
- if (props.virtual) {
321
- const nowTs = Date.now();
322
- for (let i = 0; i < rowKeyValues.length; i++) {
323
- const rowKeyValue = rowKeyValues[i];
324
- const row = props.dataSource.find((it) => rowKeyGen(it) === rowKeyValue);
325
- if (!row)
326
- continue;
327
- row._bgc_progress_ms = nowTs;
328
- highlightDimRows.add(row);
329
- }
330
- calcHighlightLoop();
331
- } else {
332
- let needRepaint = false;
333
- const rowElTemp = [];
334
- for (let i = 0; i < rowKeyValues.length; i++) {
335
- const rowKeyValue = rowKeyValues[i];
336
- const rowEl = (_a = tableContainer.value) == null ? void 0 : _a.querySelector(`[data-row-key="${rowKeyValue}"]`);
337
- if (!rowEl)
338
- continue;
339
- if (rowEl.classList.contains("highlight-row")) {
340
- rowEl.classList.remove("highlight-row");
341
- needRepaint = true;
342
- }
343
- rowElTemp.push(rowEl);
344
- window.clearTimeout(highlightDimRowsTimeout.get(rowKeyValue));
345
- highlightDimRowsTimeout.set(
346
- rowKeyValue,
347
- window.setTimeout(() => {
348
- rowEl.classList.remove("highlight-row");
349
- highlightDimRowsTimeout.delete(rowKeyValue);
350
- }, Highlight_Duration)
351
- );
352
- }
353
- if (needRepaint) {
354
- void ((_b = tableContainer.value) == null ? void 0 : _b.offsetWidth);
355
- }
356
- rowElTemp.forEach((el) => el.classList.add("highlight-row"));
357
- }
358
- }
359
- return {
360
- setHighlightDimRow,
361
- setHighlightDimCell
362
- };
363
- }
364
- const SCROLL_CODES = ["ArrowUp", "ArrowRight", "ArrowDown", "ArrowLeft", "PageUp", "PageDown"];
365
- function useKeyboardArrowScroll(targetElement, { props, scrollTo, virtualScroll, virtualScrollX, tableHeaders }) {
366
- let isMouseOver = false;
367
- onMounted(() => {
368
- var _a, _b, _c;
369
- window.addEventListener("keydown", handleKeydown);
370
- (_a = targetElement.value) == null ? void 0 : _a.addEventListener("mouseenter", handleMouseEnter);
371
- (_b = targetElement.value) == null ? void 0 : _b.addEventListener("mouseleave", handleMouseLeave);
372
- (_c = targetElement.value) == null ? void 0 : _c.addEventListener("mousedown", handleMouseDown);
373
- });
374
- onBeforeUnmount(() => {
375
- var _a, _b, _c;
376
- window.removeEventListener("keydown", handleKeydown);
377
- (_a = targetElement.value) == null ? void 0 : _a.removeEventListener("mouseenter", handleMouseEnter);
378
- (_b = targetElement.value) == null ? void 0 : _b.removeEventListener("mouseleave", handleMouseLeave);
379
- (_c = targetElement.value) == null ? void 0 : _c.removeEventListener("mousedown", handleMouseDown);
380
- });
381
- function handleKeydown(e) {
382
- if (!SCROLL_CODES.includes(e.code))
383
- return;
384
- if (!isMouseOver)
385
- return;
386
- e.preventDefault();
387
- const { scrollTop, rowHeight, pageSize } = virtualScroll.value;
388
- const { scrollLeft } = virtualScrollX.value;
389
- const { headless, headerRowHeight } = props;
390
- const headerHeight = headless ? 0 : tableHeaders.value.length * (headerRowHeight || rowHeight);
391
- if (e.code === SCROLL_CODES[0]) {
392
- scrollTo(scrollTop - rowHeight, null);
393
- } else if (e.code === SCROLL_CODES[1]) {
394
- scrollTo(null, scrollLeft + rowHeight);
395
- } else if (e.code === SCROLL_CODES[2]) {
396
- scrollTo(scrollTop + rowHeight, null);
397
- } else if (e.code === SCROLL_CODES[3]) {
398
- scrollTo(null, scrollLeft - rowHeight);
399
- } else if (e.code === SCROLL_CODES[4]) {
400
- scrollTo(scrollTop - rowHeight * pageSize - headerHeight, null);
401
- } else if (e.code === SCROLL_CODES[5]) {
402
- scrollTo(scrollTop + rowHeight * pageSize - headerHeight, null);
403
- }
404
- }
405
- function handleMouseEnter() {
406
- isMouseOver = true;
407
- }
408
- function handleMouseLeave() {
409
- isMouseOver = false;
410
- }
411
- function handleMouseDown() {
412
- if (!isMouseOver)
413
- isMouseOver = true;
414
- }
415
- }
416
- function useThDrag({ emits }) {
417
- let dragStartKey = void 0;
418
- function onThDragStart(e) {
419
- dragStartKey = e.target.dataset.colKey;
420
- emits("th-drag-start", dragStartKey);
421
- }
422
- function onThDragOver(e) {
423
- e.preventDefault();
424
- }
425
- function onThDrop(e) {
426
- let th = e.target;
427
- while (th) {
428
- if (th.tagName === "TH")
429
- break;
430
- th = th.parentNode;
431
- }
432
- if (dragStartKey !== th.dataset.colKey) {
433
- emits("col-order-change", dragStartKey, th.dataset.colKey);
434
- }
435
- emits("th-drop", th.dataset.colKey);
436
- }
437
- return {
438
- onThDragStart,
439
- onThDragOver,
440
- onThDrop
441
- };
442
- }
443
- function getCalcWidth(col) {
444
- return parseInt(col.minWidth || col.width || Default_Col_Width);
445
- }
446
- function useVirtualScroll({ tableContainer, props, dataSourceCopy, tableHeaderLast }) {
447
- const virtualScroll = ref({
448
- containerHeight: 0,
449
- rowHeight: props.rowHeight,
450
- pageSize: 10,
451
- startIndex: 0,
452
- endIndex: 0,
453
- offsetTop: 0,
454
- scrollTop: 0
455
- });
456
- const virtualScrollX = ref({
457
- containerWidth: 0,
458
- startIndex: 0,
459
- endIndex: 0,
460
- offsetLeft: 0,
461
- scrollLeft: 0
462
- });
463
- const virtual_on = computed(() => {
464
- return props.virtual && dataSourceCopy.value.length > virtualScroll.value.pageSize * 2;
465
- });
466
- const virtual_dataSourcePart = computed(() => {
467
- if (!virtual_on.value)
468
- return dataSourceCopy.value;
469
- const { startIndex, endIndex } = virtualScroll.value;
470
- return dataSourceCopy.value.slice(startIndex, endIndex);
471
- });
472
- const virtual_offsetBottom = computed(() => {
473
- if (!virtual_on.value)
474
- return 0;
475
- const { startIndex, rowHeight } = virtualScroll.value;
476
- return (dataSourceCopy.value.length - startIndex - virtual_dataSourcePart.value.length) * rowHeight;
477
- });
478
- const virtualX_on = computed(() => {
479
- return props.virtualX && tableHeaderLast.value.reduce((sum, col) => sum += getCalcWidth(col), 0) > virtualScrollX.value.containerWidth + 100;
480
- });
481
- const virtualX_columnPart = computed(() => {
482
- if (virtualX_on.value) {
483
- const leftCols = [];
484
- const rightCols = [];
485
- const { startIndex, endIndex } = virtualScrollX.value;
486
- for (let i = 0; i < startIndex; i++) {
487
- const col = tableHeaderLast.value[i];
488
- if (col.fixed === "left")
489
- leftCols.push(col);
490
- }
491
- for (let i = endIndex; i < tableHeaderLast.value.length; i++) {
492
- const col = tableHeaderLast.value[i];
493
- if (col.fixed === "right")
494
- rightCols.push(col);
495
- }
496
- const mainColumns = tableHeaderLast.value.slice(startIndex, endIndex);
497
- return leftCols.concat(mainColumns).concat(rightCols);
498
- }
499
- return tableHeaderLast.value;
500
- });
501
- const virtualX_offsetRight = computed(() => {
502
- if (!virtualX_on.value)
503
- return 0;
504
- let width = 0;
505
- for (let i = virtualScrollX.value.endIndex; i < tableHeaderLast.value.length; i++) {
506
- const col = tableHeaderLast.value[i];
507
- if (col.fixed !== "right") {
508
- width += getCalcWidth(col);
509
- }
510
- }
511
- return width;
512
- });
513
- function initVirtualScrollY(height) {
514
- if (!virtual_on.value)
515
- return;
516
- const { offsetHeight, scrollTop } = tableContainer.value || {};
517
- const { rowHeight } = virtualScroll.value;
518
- let containerHeight;
519
- if (typeof height === "number") {
520
- containerHeight = height;
521
- } else {
522
- containerHeight = offsetHeight || Default_Table_Height;
523
- }
524
- Object.assign(virtualScroll.value, {
525
- containerHeight,
526
- pageSize: Math.ceil(containerHeight / rowHeight) + 1
527
- // 这里最终+1,因为headless=true无头时,需要上下各预渲染一行。
528
- });
529
- updateVirtualScrollY(scrollTop);
530
- }
531
- function initVirtualScrollX() {
532
- if (!props.virtualX)
533
- return;
534
- const { offsetWidth, scrollLeft } = tableContainer.value || {};
535
- virtualScrollX.value.containerWidth = offsetWidth || Default_Table_Width;
536
- updateVirtualScrollX(scrollLeft);
537
- }
538
- function initVirtualScroll(height) {
539
- initVirtualScrollY(height);
540
- initVirtualScrollX();
541
- }
542
- function updateVirtualScrollY(sTop = 0) {
543
- const { rowHeight, pageSize } = virtualScroll.value;
544
- const startIndex = Math.floor(sTop / rowHeight);
545
- let endIndex = startIndex + pageSize;
546
- if (endIndex > dataSourceCopy.value.length) {
547
- endIndex = dataSourceCopy.value.length;
548
- }
549
- Object.assign(virtualScroll.value, {
550
- startIndex,
551
- offsetTop: startIndex * rowHeight,
552
- // startIndex之前的高度
553
- endIndex
554
- });
555
- }
556
- function updateVirtualScrollX(sLeft = 0) {
557
- var _a;
558
- const headerLength = (_a = tableHeaderLast.value) == null ? void 0 : _a.length;
559
- if (!headerLength)
560
- return;
561
- let startIndex = 0;
562
- let offsetLeft = 0;
563
- let colWidthSum = 0;
564
- for (let colIndex = 0; colIndex < headerLength; colIndex++) {
565
- startIndex++;
566
- const col = tableHeaderLast.value[colIndex];
567
- if (col.fixed === "left")
568
- continue;
569
- const colWidth = getCalcWidth(col);
570
- colWidthSum += colWidth;
571
- if (colWidthSum >= sLeft) {
572
- offsetLeft = colWidthSum - colWidth;
573
- startIndex--;
574
- break;
575
- }
576
- }
577
- colWidthSum = 0;
578
- let endIndex = headerLength;
579
- for (let colIndex = startIndex; colIndex < headerLength; colIndex++) {
580
- const col = tableHeaderLast.value[colIndex];
581
- colWidthSum += getCalcWidth(col);
582
- if (colWidthSum >= virtualScrollX.value.containerWidth) {
583
- endIndex = colIndex + 1;
584
- break;
585
- }
586
- }
587
- if (endIndex > headerLength) {
588
- endIndex = headerLength;
589
- }
590
- Object.assign(virtualScrollX.value, { startIndex, endIndex, offsetLeft });
591
- }
592
- return {
593
- virtualScroll,
594
- virtualScrollX,
595
- virtual_on,
596
- virtual_dataSourcePart,
597
- virtual_offsetBottom,
598
- virtualX_on,
599
- virtualX_columnPart,
600
- virtualX_offsetRight,
601
- initVirtualScroll,
602
- initVirtualScrollY,
603
- initVirtualScrollX,
604
- updateVirtualScrollY,
605
- updateVirtualScrollX
606
- };
607
- }
608
- function insertToOrderedArray(sortState, newItem, targetArray) {
609
- const { dataIndex, order } = sortState;
610
- let { sortType } = sortState;
611
- if (!sortType)
612
- sortType = typeof newItem[dataIndex];
613
- const data = [...targetArray];
614
- if (!order) {
615
- data.unshift(newItem);
616
- return data;
617
- }
618
- let sIndex = 0;
619
- let eIndex = data.length - 1;
620
- const targetVal = newItem[dataIndex];
621
- while (sIndex <= eIndex) {
622
- const midIndex = Math.floor((sIndex + eIndex) / 2);
623
- const midVal = data[midIndex][dataIndex];
624
- const compareRes = strCompare(midVal, targetVal, sortType);
625
- if (compareRes === 0) {
626
- sIndex = midIndex;
627
- break;
628
- } else if (compareRes === -1) {
629
- if (order === "asc")
630
- sIndex = midIndex + 1;
631
- else
632
- eIndex = midIndex - 1;
633
- } else {
634
- if (order === "asc")
635
- eIndex = midIndex - 1;
636
- else
637
- sIndex = midIndex + 1;
638
- }
639
- }
640
- data.splice(sIndex, 0, newItem);
641
- return data;
642
- }
643
- function strCompare(a, b, type) {
644
- if (type === "number") {
645
- if (+a > +b)
646
- return 1;
647
- else if (+a === +b)
648
- return 0;
649
- else
650
- return -1;
651
- } else {
652
- return String(a).localeCompare(b);
653
- }
654
- }
655
- function tableSort(sortOption, order, dataSource) {
656
- if (!(dataSource == null ? void 0 : dataSource.length))
657
- return dataSource || [];
658
- let targetDataSource = [...dataSource];
659
- if (typeof sortOption.sorter === "function") {
660
- const customSorterData = sortOption.sorter(targetDataSource, { order, column: sortOption });
661
- if (customSorterData)
662
- targetDataSource = customSorterData;
663
- } else if (order) {
664
- const sortField = sortOption.sortField || sortOption.dataIndex;
665
- let { sortType } = sortOption;
666
- if (!sortType)
667
- sortType = typeof dataSource[0][sortField];
668
- if (sortType === "number") {
669
- const nanArr = [];
670
- const numArr = [];
671
- for (let i = 0; i < targetDataSource.length; i++) {
672
- const row = targetDataSource[i];
673
- if (row[sortField] === null || row[sortField] === "" || typeof row[sortField] === "boolean" || Number.isNaN(+row[sortField])) {
674
- nanArr.push(row);
675
- } else {
676
- numArr.push(row);
677
- }
678
- }
679
- if (order === "asc") {
680
- numArr.sort((a, b) => +a[sortField] - +b[sortField]);
681
- targetDataSource = [...nanArr, ...numArr];
682
- } else {
683
- numArr.sort((a, b) => +b[sortField] - +a[sortField]);
684
- targetDataSource = [...numArr, ...nanArr];
685
- }
686
- } else {
687
- if (order === "asc") {
688
- targetDataSource.sort((a, b) => String(a[sortField]).localeCompare(b[sortField]));
689
- } else {
690
- targetDataSource.sort((a, b) => String(a[sortField]).localeCompare(b[sortField]) * -1);
691
- }
692
- }
693
- }
694
- return targetDataSource;
695
- }
696
- function howDeepTheHeader(arr, level = 1) {
697
- const levels = [level];
698
- arr.forEach((item) => {
699
- var _a;
700
- if ((_a = item.children) == null ? void 0 : _a.length) {
701
- levels.push(howDeepTheHeader(item.children, level + 1));
702
- }
703
- });
704
- return Math.max(...levels);
705
- }
706
- const _hoisted_1 = {
707
- key: 0
708
- };
709
- const _hoisted_2 = ["data-col-key", "draggable", "rowspan", "colspan", "title", "onClick"];
710
- const _hoisted_3 = {
711
- class: "table-header-cell-wrapper"
712
- };
713
- const _hoisted_4 = {
714
- class: "table-header-title"
715
- };
716
- const _hoisted_5 = {
717
- key: 2,
718
- class: "table-header-sorter"
719
- };
720
- const _hoisted_6 = /* @__PURE__ */ createElementVNode("svg", {
721
- xmlns: "http://www.w3.org/2000/svg",
722
- width: "16px",
723
- height: "16px",
724
- viewBox: "0 0 16 16"
725
- }, [/* @__PURE__ */ createElementVNode("polygon", {
726
- class: "arrow-up",
727
- fill: "#757699",
728
- points: "8 2 4.8 6 11.2 6"
729
- }), /* @__PURE__ */ createElementVNode("polygon", {
730
- class: "arrow-down",
731
- transform: "translate(8, 12) rotate(-180) translate(-8, -12) ",
732
- points: "8 10 4.8 14 11.2 14"
733
- })], -1);
734
- const _hoisted_7 = [_hoisted_6];
735
- const _hoisted_8 = ["onMousedown"];
736
- const _hoisted_9 = ["onMousedown"];
737
- const _hoisted_10 = {
738
- key: 0,
739
- class: "virtual-x-left",
740
- style: {
741
- "padding": "0"
742
- }
743
- };
744
- const _hoisted_11 = ["data-row-key", "onClick", "onDblclick", "onContextmenu", "onMouseover"];
745
- const _hoisted_12 = {
746
- key: 0,
747
- class: "virtual-x-left",
748
- style: {
749
- "padding": "0"
750
- }
751
- };
752
- const _hoisted_13 = ["data-index", "onClick"];
753
- const _hoisted_14 = ["title"];
754
- const _sfc_main = /* @__PURE__ */ defineComponent({
755
- __name: "StkTable",
756
- props: {
757
- width: {
758
- default: ""
759
- },
760
- minWidth: {
761
- default: ""
762
- },
763
- maxWidth: {
764
- default: ""
765
- },
766
- stripe: {
767
- type: Boolean,
768
- default: false
769
- },
770
- fixedMode: {
771
- type: Boolean,
772
- default: false
773
- },
774
- headless: {
775
- type: Boolean,
776
- default: false
777
- },
778
- theme: {
779
- default: "light"
780
- },
781
- rowHeight: {
782
- default: Default_Row_Height
783
- },
784
- headerRowHeight: {
785
- default: null
786
- },
787
- virtual: {
788
- type: Boolean,
789
- default: false
790
- },
791
- virtualX: {
792
- type: Boolean,
793
- default: false
794
- },
795
- columns: {
796
- default: () => []
797
- },
798
- dataSource: {
799
- default: () => []
800
- },
801
- rowKey: {
802
- type: [String, Function],
803
- default: ""
804
- },
805
- colKey: {
806
- type: [String, Function],
807
- default: "dataIndex"
808
- },
809
- emptyCellText: {
810
- default: "--"
811
- },
812
- noDataFull: {
813
- type: Boolean,
814
- default: false
815
- },
816
- showNoData: {
817
- type: Boolean,
818
- default: true
819
- },
820
- sortRemote: {
821
- type: Boolean,
822
- default: false
823
- },
824
- showHeaderOverflow: {
825
- type: Boolean,
826
- default: false
827
- },
828
- showOverflow: {
829
- type: Boolean,
830
- default: false
831
- },
832
- showTrHoverClass: {
833
- type: Boolean,
834
- default: false
835
- },
836
- headerDrag: {
837
- type: Boolean,
838
- default: false
839
- },
840
- rowClassName: {
841
- type: Function,
842
- default: () => ""
843
- },
844
- colResizable: {
845
- type: Boolean,
846
- default: false
847
- },
848
- colMinWidth: {
849
- default: 10
850
- },
851
- bordered: {
852
- type: [Boolean, String],
853
- default: true
854
- },
855
- autoResize: {
856
- type: [Boolean, Function],
857
- default: true
858
- },
859
- fixedColShadow: {
860
- type: Boolean,
861
- default: false
862
- }
863
- },
864
- emits: ["sort-change", "row-click", "current-change", "row-dblclick", "header-row-menu", "row-menu", "cell-click", "header-cell-click", "scroll", "scroll-x", "col-order-change", "th-drag-start", "th-drop", "update:columns"],
865
- setup(__props, {
866
- expose: __expose,
867
- emit: __emit
868
- }) {
869
- const props = __props;
870
- const emits = __emit;
871
- const tableContainer = ref();
872
- const colResizeIndicator = ref();
873
- const currentItem = ref(null);
874
- const currentHover = ref(null);
875
- let sortCol = ref();
876
- let sortOrderIndex = ref(0);
877
- const sortSwitchOrder = [null, "desc", "asc"];
878
- const tableHeaders = ref([]);
879
- const tableHeaderLast = ref([]);
880
- const dataSourceCopy = shallowRef([...props.dataSource]);
881
- const fixedShadow = ref({
882
- /** 是否展示左侧固定列阴影 */
883
- showL: false,
884
- /** 是否展示右侧固定列阴影 */
885
- showR: false,
886
- /** 保存需要出现阴影的列 */
887
- cols: []
888
- });
889
- const rowKeyGenStore = /* @__PURE__ */ new WeakMap();
890
- const {
891
- isColResizing,
892
- onThResizeMouseDown
893
- } = useColResize({
894
- props,
895
- emits,
896
- colKeyGen,
897
- colResizeIndicator,
898
- tableContainer,
899
- tableHeaderLast
900
- });
901
- const {
902
- onThDragStart,
903
- onThDragOver,
904
- onThDrop
905
- } = useThDrag({
906
- emits
907
- });
908
- const {
909
- virtualScroll,
910
- virtualScrollX,
911
- virtual_on,
912
- virtual_dataSourcePart,
913
- virtual_offsetBottom,
914
- virtualX_on,
915
- virtualX_columnPart,
916
- virtualX_offsetRight,
917
- initVirtualScroll,
918
- initVirtualScrollY,
919
- initVirtualScrollX,
920
- updateVirtualScrollY,
921
- updateVirtualScrollX
922
- } = useVirtualScroll({
923
- tableContainer,
924
- props,
925
- dataSourceCopy,
926
- tableHeaderLast
927
- });
928
- const {
929
- getFixedStyle
930
- } = useFixedStyle({
931
- props,
932
- tableHeaderLast,
933
- virtualScroll,
934
- virtualScrollX,
935
- virtualX_on,
936
- virtualX_offsetRight
937
- });
938
- const {
939
- setHighlightDimCell,
940
- setHighlightDimRow
941
- } = useHighlight({
942
- props,
943
- tableContainer,
944
- rowKeyGen
945
- });
946
- if (props.autoResize) {
947
- useAutoResize({
948
- tableContainer,
949
- initVirtualScroll,
950
- scrollTo,
951
- props,
952
- debounceMs: 500
953
- });
954
- }
955
- useKeyboardArrowScroll(tableContainer, {
956
- props,
957
- scrollTo,
958
- virtualScroll,
959
- virtualScrollX,
960
- tableHeaders
961
- });
962
- watch(() => props.columns, () => {
963
- dealColumns();
964
- initVirtualScrollX();
965
- });
966
- dealColumns();
967
- watch(() => props.dataSource, (val) => {
968
- if (!val) {
969
- console.warn("invalid dataSource");
970
- return;
971
- }
972
- let needInitVirtualScrollY = false;
973
- if (dataSourceCopy.value.length !== val.length) {
974
- needInitVirtualScrollY = true;
975
- }
976
- dataSourceCopy.value = [...val];
977
- if (needInitVirtualScrollY)
978
- initVirtualScrollY();
979
- if (sortCol.value) {
980
- const column = tableHeaderLast.value.find((it) => it.dataIndex === sortCol.value);
981
- onColumnSort(column, false);
982
- }
983
- updateFixedShadow();
984
- }, {
985
- deep: false
986
- });
987
- onMounted(() => {
988
- initVirtualScroll();
989
- updateFixedShadow();
990
- });
991
- function dealColumns() {
992
- tableHeaders.value = [];
993
- tableHeaderLast.value = [];
994
- const copyColumn = props.columns;
995
- const deep = howDeepTheHeader(copyColumn);
996
- const tempHeaderLast = [];
997
- if (deep > 1 && props.virtualX) {
998
- console.error("多级表头不支持横向虚拟滚动");
999
- }
1000
- function flat(arr, parent, depth = 0) {
1001
- if (!tableHeaders.value[depth]) {
1002
- tableHeaders.value[depth] = [];
1003
- }
1004
- let allChildrenLen = 0;
1005
- arr.forEach((col) => {
1006
- col.__PARENT__ = parent;
1007
- let colChildrenLen = 1;
1008
- if (col.children) {
1009
- colChildrenLen = flat(
1010
- col.children,
1011
- col,
1012
- depth + 1
1013
- /* , col.fixed */
1014
- );
1015
- } else {
1016
- tempHeaderLast.push(col);
1017
- }
1018
- tableHeaders.value[depth].push(col);
1019
- const rowSpan = col.children ? 1 : deep - depth;
1020
- const colSpan = colChildrenLen;
1021
- if (rowSpan !== 1) {
1022
- col.rowSpan = rowSpan;
1023
- }
1024
- if (colSpan !== 1) {
1025
- col.colSpan = colSpan;
1026
- }
1027
- allChildrenLen += colChildrenLen;
1028
- });
1029
- return allChildrenLen;
1030
- }
1031
- flat(copyColumn, null);
1032
- tableHeaderLast.value = tempHeaderLast;
1033
- dealFixedColShadow();
1034
- }
1035
- function dealFixedColShadow() {
1036
- if (!props.fixedColShadow)
1037
- return;
1038
- fixedShadow.value.cols = [];
1039
- const lastLeftCol = tableHeaderLast.value.findLast((it) => it.fixed === "left");
1040
- const lastRightCol = tableHeaderLast.value.find((it) => it.fixed === "right");
1041
- let node = {
1042
- __PARENT__: lastLeftCol
1043
- };
1044
- while (node = node.__PARENT__) {
1045
- if (node.fixed) {
1046
- fixedShadow.value.cols.push(node);
1047
- }
1048
- }
1049
- node = {
1050
- __PARENT__: lastRightCol
1051
- };
1052
- while (node = node.__PARENT__) {
1053
- if (node.fixed) {
1054
- fixedShadow.value.cols.push(node);
1055
- }
1056
- }
1057
- }
1058
- function getFixedColClass(col) {
1059
- const {
1060
- showR,
1061
- showL,
1062
- cols
1063
- } = fixedShadow.value;
1064
- const classArr = [col.fixed ? "fixed-cell" : "", col.fixed ? "fixed-cell--" + col.fixed : "", props.fixedColShadow && col.fixed && (showL && col.fixed === "left" || showR && col.fixed === "right") && cols.includes(col) ? "fixed-cell--shadow" : ""];
1065
- return classArr;
1066
- }
1067
- function updateFixedShadow() {
1068
- if (!props.fixedColShadow)
1069
- return;
1070
- const {
1071
- clientWidth,
1072
- scrollWidth,
1073
- scrollLeft
1074
- } = tableContainer.value;
1075
- fixedShadow.value.showL = Boolean(scrollLeft);
1076
- fixedShadow.value.showR = Math.abs(scrollWidth - scrollLeft - clientWidth) > 0.5;
1077
- }
1078
- function rowKeyGen(row) {
1079
- let key = rowKeyGenStore.get(row);
1080
- if (!key) {
1081
- key = typeof props.rowKey === "function" ? props.rowKey(row) : row[props.rowKey];
1082
- rowKeyGenStore.set(row, key);
1083
- }
1084
- return key;
1085
- }
1086
- function colKeyGen(col) {
1087
- return typeof props.colKey === "function" ? props.colKey(col) : col[props.colKey];
1088
- }
1089
- function getColWidthStyle(col) {
1090
- const style = {
1091
- width: col.width,
1092
- minWidth: col.minWidth,
1093
- maxWidth: col.maxWidth
1094
- };
1095
- if (props.colResizable) {
1096
- style.minWidth = col.width;
1097
- style.maxWidth = col.width;
1098
- } else {
1099
- style.minWidth = col.minWidth === void 0 ? col.width : col.minWidth;
1100
- style.maxWidth = col.maxWidth === void 0 ? col.width : col.maxWidth;
1101
- }
1102
- return style;
1103
- }
1104
- function getCellStyle(tagType, col, depth) {
1105
- const style = {
1106
- ...getColWidthStyle(col),
1107
- ...getFixedStyle(tagType, col, depth)
1108
- };
1109
- if (tagType === 1) {
1110
- style.textAlign = col.headerAlign;
1111
- } else if (tagType === 2) {
1112
- style.textAlign = col.align;
1113
- }
1114
- return style;
1115
- }
1116
- function onColumnSort(col, click = true, options = {}) {
1117
- if (!(col == null ? void 0 : col.sorter))
1118
- return;
1119
- options = {
1120
- force: false,
1121
- emit: false,
1122
- ...options
1123
- };
1124
- if (sortCol.value !== col.dataIndex) {
1125
- sortCol.value = col.dataIndex;
1126
- sortOrderIndex.value = 0;
1127
- }
1128
- if (click)
1129
- sortOrderIndex.value++;
1130
- sortOrderIndex.value = sortOrderIndex.value % 3;
1131
- const order = sortSwitchOrder[sortOrderIndex.value];
1132
- if (!props.sortRemote || options.force) {
1133
- dataSourceCopy.value = tableSort(col, order, props.dataSource);
1134
- }
1135
- if (click || options.emit) {
1136
- emits("sort-change", col, order, toRaw(dataSourceCopy.value));
1137
- }
1138
- }
1139
- function onRowClick(e, row) {
1140
- emits("row-click", e, row);
1141
- if (currentItem.value === row)
1142
- return;
1143
- currentItem.value = row;
1144
- emits("current-change", e, row);
1145
- }
1146
- function onRowDblclick(e, row) {
1147
- emits("row-dblclick", e, row);
1148
- }
1149
- function onHeaderMenu(e) {
1150
- emits("header-row-menu", e);
1151
- }
1152
- function onRowMenu(e, row) {
1153
- emits("row-menu", e, row);
1154
- }
1155
- function onCellClick(e, row, col) {
1156
- emits("cell-click", e, row, col);
1157
- }
1158
- function onHeaderCellClick(e, col) {
1159
- emits("header-cell-click", e, col);
1160
- }
1161
- function onTableWheel(e) {
1162
- if (isColResizing.value) {
1163
- e.preventDefault();
1164
- e.stopPropagation();
1165
- return;
1166
- }
1167
- }
1168
- function onTableScroll(e) {
1169
- if (!(e == null ? void 0 : e.target))
1170
- return;
1171
- const {
1172
- scrollTop,
1173
- scrollLeft
1174
- } = e.target;
1175
- const {
1176
- scrollTop: vScrollTop,
1177
- startIndex,
1178
- endIndex
1179
- } = virtualScroll.value;
1180
- const {
1181
- scrollLeft: vScrollLeft
1182
- } = virtualScrollX.value;
1183
- const isYScroll = scrollTop !== vScrollTop;
1184
- const isXScroll = scrollLeft !== vScrollLeft;
1185
- if (isYScroll) {
1186
- virtualScroll.value.scrollTop = scrollTop;
1187
- }
1188
- if (virtual_on.value) {
1189
- updateVirtualScrollY(scrollTop);
1190
- }
1191
- if (isXScroll) {
1192
- virtualScrollX.value.scrollLeft = scrollLeft;
1193
- updateFixedShadow();
1194
- }
1195
- if (virtualX_on.value) {
1196
- updateVirtualScrollX(scrollLeft);
1197
- }
1198
- const data = {
1199
- startIndex,
1200
- endIndex
1201
- };
1202
- if (isYScroll) {
1203
- emits("scroll", e, data);
1204
- }
1205
- if (isXScroll) {
1206
- emits("scroll-x", e);
1207
- }
1208
- }
1209
- function onTrMouseOver(_e, row) {
1210
- if (props.showTrHoverClass) {
1211
- currentHover.value = rowKeyGen(row);
1212
- }
1213
- }
1214
- function setCurrentRow(rowKey, option = {
1215
- silent: false
1216
- }) {
1217
- if (!dataSourceCopy.value.length)
1218
- return;
1219
- currentItem.value = dataSourceCopy.value.find((it) => rowKeyGen(it) === rowKey);
1220
- if (!option.silent) {
1221
- emits("current-change", null, currentItem.value);
1222
- }
1223
- }
1224
- function setSorter(dataIndex, order, option = {}) {
1225
- var _a;
1226
- const newOption = {
1227
- silent: true,
1228
- sortOption: null,
1229
- sort: true,
1230
- ...option
1231
- };
1232
- sortCol.value = dataIndex;
1233
- sortOrderIndex.value = sortSwitchOrder.findIndex((it) => it === order);
1234
- if (newOption.sort && ((_a = dataSourceCopy.value) == null ? void 0 : _a.length)) {
1235
- const column = newOption.sortOption || tableHeaderLast.value.find((it) => it.dataIndex === sortCol.value);
1236
- if (column)
1237
- onColumnSort(column, false, {
1238
- force: true,
1239
- emit: !newOption.silent
1240
- });
1241
- else
1242
- console.warn("Can not find column by dataIndex:", sortCol.value);
1243
- }
1244
- return dataSourceCopy.value;
1245
- }
1246
- function resetSorter() {
1247
- sortCol.value = null;
1248
- sortOrderIndex.value = 0;
1249
- dataSourceCopy.value = [...props.dataSource];
1250
- }
1251
- function scrollTo(top = 0, left = 0) {
1252
- if (!tableContainer.value)
1253
- return;
1254
- if (top !== null)
1255
- tableContainer.value.scrollTop = top;
1256
- if (left !== null)
1257
- tableContainer.value.scrollLeft = left;
1258
- }
1259
- function getTableData() {
1260
- return toRaw(dataSourceCopy.value);
1261
- }
1262
- __expose({
1263
- /** 初始化横向纵向虚拟滚动 */
1264
- initVirtualScroll,
1265
- /** 初始化横向虚拟滚动 */
1266
- initVirtualScrollX,
1267
- /** 初始化纵向虚拟滚动 */
1268
- initVirtualScrollY,
1269
- /** 设置当前选中行 */
1270
- setCurrentRow,
1271
- /** 设置高亮渐暗单元格 */
1272
- setHighlightDimCell,
1273
- /** 设置高亮渐暗行 */
1274
- setHighlightDimRow,
1275
- /** 表格排序列dataIndex */
1276
- sortCol,
1277
- /** 设置排序 */
1278
- setSorter,
1279
- /** 重置排序 */
1280
- resetSorter,
1281
- /** 滚动至 */
1282
- scrollTo,
1283
- /** 获取表格数据 */
1284
- getTableData
1285
- });
1286
- return (_ctx, _cache) => {
1287
- return openBlock(), createElementBlock("div", {
1288
- ref_key: "tableContainer",
1289
- ref: tableContainer,
1290
- class: normalizeClass(["stk-table", {
1291
- virtual: _ctx.virtual,
1292
- "virtual-x": _ctx.virtualX,
1293
- dark: _ctx.theme === "dark",
1294
- headless: _ctx.headless,
1295
- "is-col-resizing": unref(isColResizing),
1296
- "col-resizable": props.colResizable,
1297
- border: props.bordered,
1298
- "border-h": props.bordered === "h",
1299
- "border-v": props.bordered === "v",
1300
- "border-body-v": props.bordered === "body-v",
1301
- stripe: props.stripe
1302
- }]),
1303
- style: normalizeStyle(_ctx.virtual && {
1304
- "--row-height": unref(virtualScroll).rowHeight + "px",
1305
- "--header-row-height": (props.headerRowHeight || props.rowHeight) + "px"
1306
- }),
1307
- onScroll: onTableScroll,
1308
- onWheel: onTableWheel
1309
- }, [withDirectives(createElementVNode("div", {
1310
- ref_key: "colResizeIndicator",
1311
- ref: colResizeIndicator,
1312
- class: "column-resize-indicator"
1313
- }, null, 512), [[vShow, _ctx.colResizable]]), createElementVNode("table", {
1314
- class: normalizeClass(["stk-table-main", {
1315
- "fixed-mode": props.fixedMode
1316
- }]),
1317
- style: normalizeStyle({
1318
- width: _ctx.width,
1319
- minWidth: _ctx.minWidth,
1320
- maxWidth: _ctx.maxWidth
1321
- })
1322
- }, [!_ctx.headless ? (openBlock(), createElementBlock("thead", _hoisted_1, [(openBlock(true), createElementBlock(Fragment, null, renderList(tableHeaders.value, (row, rowIndex) => {
1323
- return openBlock(), createElementBlock("tr", {
1324
- key: rowIndex,
1325
- onContextmenu: _cache[3] || (_cache[3] = (e) => onHeaderMenu(e))
1326
- }, [unref(virtualX_on) ? (openBlock(), createElementBlock("th", {
1327
- key: 0,
1328
- class: "virtual-x-left",
1329
- style: normalizeStyle({
1330
- minWidth: unref(virtualScrollX).offsetLeft + "px",
1331
- width: unref(virtualScrollX).offsetLeft + "px"
1332
- })
1333
- }, null, 4)) : createCommentVNode("", true), (openBlock(true), createElementBlock(Fragment, null, renderList(unref(virtualX_on) && rowIndex === tableHeaders.value.length - 1 ? unref(virtualX_columnPart) : row, (col, colIndex) => {
1334
- return openBlock(), createElementBlock("th", {
1335
- key: col.dataIndex,
1336
- "data-col-key": colKeyGen(col),
1337
- draggable: _ctx.headerDrag ? "true" : "false",
1338
- rowspan: unref(virtualX_on) ? 1 : col.rowSpan,
1339
- colspan: col.colSpan,
1340
- style: normalizeStyle(getCellStyle(1, col, rowIndex)),
1341
- title: col.title,
1342
- class: normalizeClass([col.sorter ? "sortable" : "", col.dataIndex === unref(sortCol) && unref(sortOrderIndex) !== 0 && "sorter-" + sortSwitchOrder[unref(sortOrderIndex)], _ctx.showHeaderOverflow ? "text-overflow" : "", col.headerClassName, ...getFixedColClass(col)]),
1343
- onClick: (e) => {
1344
- onColumnSort(col);
1345
- onHeaderCellClick(e, col);
1346
- },
1347
- onDragstart: _cache[0] || (_cache[0] = //@ts-ignore
1348
- (...args) => unref(onThDragStart) && unref(onThDragStart)(...args)),
1349
- onDrop: _cache[1] || (_cache[1] = //@ts-ignore
1350
- (...args) => unref(onThDrop) && unref(onThDrop)(...args)),
1351
- onDragover: _cache[2] || (_cache[2] = //@ts-ignore
1352
- (...args) => unref(onThDragOver) && unref(onThDragOver)(...args))
1353
- }, [createElementVNode("div", _hoisted_3, [col.customHeaderCell ? (openBlock(), createBlock(resolveDynamicComponent(col.customHeaderCell), {
1354
- key: 0,
1355
- col
1356
- }, null, 8, ["col"])) : renderSlot(_ctx.$slots, "tableHeader", {
1357
- key: 1,
1358
- col
1359
- }, () => [createElementVNode("span", _hoisted_4, toDisplayString(col.title), 1)]), col.sorter ? (openBlock(), createElementBlock("span", _hoisted_5, _hoisted_7)) : createCommentVNode("", true), _ctx.colResizable && colIndex > 0 ? (openBlock(), createElementBlock("div", {
1360
- key: 3,
1361
- class: "table-header-resizer left",
1362
- onMousedown: (e) => unref(onThResizeMouseDown)(e, col, true)
1363
- }, null, 40, _hoisted_8)) : createCommentVNode("", true), _ctx.colResizable ? (openBlock(), createElementBlock("div", {
1364
- key: 4,
1365
- class: "table-header-resizer right",
1366
- onMousedown: (e) => unref(onThResizeMouseDown)(e, col)
1367
- }, null, 40, _hoisted_9)) : createCommentVNode("", true)])], 46, _hoisted_2);
1368
- }), 128)), unref(virtualX_on) ? (openBlock(), createElementBlock("th", {
1369
- key: 1,
1370
- class: "virtual-x-right",
1371
- style: normalizeStyle({
1372
- minWidth: unref(virtualX_offsetRight) + "px",
1373
- width: unref(virtualX_offsetRight) + "px"
1374
- })
1375
- }, null, 4)) : createCommentVNode("", true)], 32);
1376
- }), 128))])) : createCommentVNode("", true), createElementVNode("tbody", null, [unref(virtual_on) ? (openBlock(), createElementBlock("tr", {
1377
- key: 0,
1378
- style: normalizeStyle({
1379
- height: `${unref(virtualScroll).offsetTop}px`
1380
- }),
1381
- class: "padding-top-tr"
1382
- }, [unref(virtualX_on) && _ctx.fixedMode && _ctx.headless ? (openBlock(), createElementBlock("td", _hoisted_10)) : createCommentVNode("", true), _ctx.fixedMode && _ctx.headless ? (openBlock(true), createElementBlock(Fragment, {
1383
- key: 1
1384
- }, renderList(unref(virtualX_columnPart), (col) => {
1385
- return openBlock(), createElementBlock("td", {
1386
- key: col.dataIndex,
1387
- style: normalizeStyle(getCellStyle(2, col))
1388
- }, null, 4);
1389
- }), 128)) : createCommentVNode("", true)], 4)) : createCommentVNode("", true), (openBlock(true), createElementBlock(Fragment, null, renderList(unref(virtual_dataSourcePart), (row, i) => {
1390
- return openBlock(), createElementBlock("tr", {
1391
- key: _ctx.rowKey ? rowKeyGen(row) : i,
1392
- "data-row-key": _ctx.rowKey ? rowKeyGen(row) : i,
1393
- class: normalizeClass({
1394
- active: _ctx.rowKey ? rowKeyGen(row) === (currentItem.value && rowKeyGen(currentItem.value)) : row === currentItem.value,
1395
- hover: _ctx.rowKey ? rowKeyGen(row) === currentHover.value : row === currentHover.value,
1396
- [_ctx.rowClassName(row, i)]: true
1397
- }),
1398
- style: normalizeStyle({
1399
- backgroundColor: row._bgc
1400
- }),
1401
- onClick: (e) => onRowClick(e, row),
1402
- onDblclick: (e) => onRowDblclick(e, row),
1403
- onContextmenu: (e) => onRowMenu(e, row),
1404
- onMouseover: (e) => onTrMouseOver(e, row)
1405
- }, [unref(virtualX_on) ? (openBlock(), createElementBlock("td", _hoisted_12)) : createCommentVNode("", true), (openBlock(true), createElementBlock(Fragment, null, renderList(unref(virtualX_columnPart), (col) => {
1406
- return openBlock(), createElementBlock("td", {
1407
- key: col.dataIndex,
1408
- "data-index": col.dataIndex,
1409
- class: normalizeClass([col.className, _ctx.showOverflow ? "text-overflow" : "", ...getFixedColClass(col)]),
1410
- style: normalizeStyle(getCellStyle(2, col)),
1411
- onClick: (e) => onCellClick(e, row, col)
1412
- }, [col.customCell ? (openBlock(), createBlock(resolveDynamicComponent(col.customCell), {
1413
- key: 0,
1414
- col,
1415
- row,
1416
- "cell-value": row[col.dataIndex]
1417
- }, null, 8, ["col", "row", "cell-value"])) : (openBlock(), createElementBlock("div", {
1418
- key: 1,
1419
- class: "table-cell-wrapper",
1420
- title: row[col.dataIndex]
1421
- }, toDisplayString(row[col.dataIndex] ?? _ctx.emptyCellText), 9, _hoisted_14))], 14, _hoisted_13);
1422
- }), 128))], 46, _hoisted_11);
1423
- }), 128)), unref(virtual_on) ? (openBlock(), createElementBlock("tr", {
1424
- key: 1,
1425
- style: normalizeStyle({
1426
- height: `${unref(virtual_offsetBottom)}px`
1427
- })
1428
- }, null, 4)) : createCommentVNode("", true)])], 6), (!dataSourceCopy.value || !dataSourceCopy.value.length) && _ctx.showNoData ? (openBlock(), createElementBlock("div", {
1429
- key: 0,
1430
- class: normalizeClass(["stk-table-no-data", {
1431
- "no-data-full": _ctx.noDataFull
1432
- }])
1433
- }, [renderSlot(_ctx.$slots, "empty", {}, () => [createTextVNode("暂无数据")])], 2)) : createCommentVNode("", true)], 38);
1434
- };
1435
- }
1436
- });
1437
- export {
1438
- _sfc_main as StkTable,
1439
- insertToOrderedArray,
1440
- tableSort
1441
- };
1
+ import { onMounted, onBeforeUnmount, watch, ref, computed, defineComponent, shallowRef, toRaw, openBlock, createElementBlock, normalizeClass, unref, normalizeStyle, withDirectives, createElementVNode, vShow, Fragment, renderList, createCommentVNode, createBlock, resolveDynamicComponent, renderSlot, toDisplayString, createTextVNode } from "vue";
2
+ import { interpolateRgb } from "d3-interpolate";
3
+ const Default_Col_Width = "100";
4
+ const Default_Table_Height = 100;
5
+ const Default_Table_Width = 200;
6
+ const Default_Row_Height = 28;
7
+ const Highlight_Color = {
8
+ light: { from: "#71a2fd", to: "#fff" },
9
+ dark: { from: "#1e4c99", to: "#181c21" }
10
+ };
11
+ const Highlight_Duration = 2e3;
12
+ const Highlight_Color_Change_Freq = 100;
13
+ let _chromeVersion = 0;
14
+ try {
15
+ const userAgent = navigator.userAgent.match(/chrome\/\d+/i);
16
+ if (userAgent) {
17
+ _chromeVersion = +userAgent[0].split("/")[1];
18
+ }
19
+ } catch (e) {
20
+ console.error("Cannot get Chrome version", e);
21
+ }
22
+ const Is_Legacy_Mode = _chromeVersion < 56;
23
+ function useAutoResize({ tableContainer, initVirtualScroll, scrollTo, props, debounceMs }) {
24
+ let resizeObserver = null;
25
+ onMounted(() => {
26
+ initResizeObserver();
27
+ });
28
+ onBeforeUnmount(() => {
29
+ removeResizeObserver();
30
+ });
31
+ function initResizeObserver() {
32
+ if (window.ResizeObserver) {
33
+ if (!tableContainer.value) {
34
+ const watchDom = watch(
35
+ () => tableContainer,
36
+ () => {
37
+ initResizeObserver();
38
+ watchDom();
39
+ }
40
+ );
41
+ return;
42
+ }
43
+ resizeObserver = new ResizeObserver(resizeCallback);
44
+ resizeObserver.observe(tableContainer.value);
45
+ } else {
46
+ window.addEventListener("resize", resizeCallback);
47
+ }
48
+ }
49
+ function removeResizeObserver() {
50
+ if (resizeObserver) {
51
+ resizeObserver.disconnect();
52
+ resizeObserver = null;
53
+ } else {
54
+ window.removeEventListener("resize", resizeCallback);
55
+ }
56
+ }
57
+ let debounceTime = 0;
58
+ function resizeCallback() {
59
+ if (debounceTime) {
60
+ window.clearTimeout(debounceTime);
61
+ }
62
+ debounceTime = window.setTimeout(() => {
63
+ if (props.autoResize) {
64
+ initVirtualScroll();
65
+ if (typeof props.autoResize === "function") {
66
+ props.autoResize();
67
+ }
68
+ }
69
+ debounceTime = 0;
70
+ }, debounceMs);
71
+ }
72
+ }
73
+ function useColResize({
74
+ tableContainer,
75
+ tableHeaderLast,
76
+ colResizeIndicator,
77
+ props,
78
+ emits,
79
+ colKeyGen
80
+ }) {
81
+ const isColResizing = ref(false);
82
+ let colResizeState = {
83
+ currentCol: null,
84
+ currentColIndex: 0,
85
+ lastCol: null,
86
+ startX: 0,
87
+ startOffsetTableX: 0
88
+ };
89
+ onMounted(() => {
90
+ initColResizeEvent();
91
+ });
92
+ onBeforeUnmount(() => {
93
+ clearColResizeEvent();
94
+ });
95
+ function initColResizeEvent() {
96
+ window.addEventListener("mousemove", onThResizeMouseMove);
97
+ window.addEventListener("mouseup", onThResizeMouseUp);
98
+ }
99
+ function clearColResizeEvent() {
100
+ window.removeEventListener("mousemove", onThResizeMouseMove);
101
+ window.removeEventListener("mouseup", onThResizeMouseUp);
102
+ }
103
+ function onThResizeMouseDown(e, col, isPrev = false) {
104
+ if (!tableContainer.value)
105
+ return;
106
+ e.stopPropagation();
107
+ e.preventDefault();
108
+ const { clientX } = e;
109
+ const { scrollLeft, scrollTop } = tableContainer.value;
110
+ const { left } = tableContainer.value.getBoundingClientRect();
111
+ let colIndex = tableHeaderLast.value.findIndex((it) => colKeyGen(it) === colKeyGen(col));
112
+ if (isPrev) {
113
+ colIndex -= 1;
114
+ col = tableHeaderLast.value[colIndex];
115
+ }
116
+ const offsetTableX = clientX - left + scrollLeft;
117
+ isColResizing.value = true;
118
+ Object.assign(colResizeState, {
119
+ currentCol: col,
120
+ currentColIndex: colIndex,
121
+ lastCol: findLastChildCol(col),
122
+ startX: clientX,
123
+ startOffsetTableX: offsetTableX
124
+ });
125
+ if (colResizeIndicator.value) {
126
+ const style = colResizeIndicator.value.style;
127
+ style.display = "block";
128
+ style.left = offsetTableX + "px";
129
+ style.top = scrollTop + "px";
130
+ }
131
+ }
132
+ function onThResizeMouseMove(e) {
133
+ if (!isColResizing.value)
134
+ return;
135
+ e.stopPropagation();
136
+ e.preventDefault();
137
+ const { lastCol, startX, startOffsetTableX } = colResizeState;
138
+ const { clientX } = e;
139
+ let moveX = clientX - startX;
140
+ const currentColWidth = parseInt((lastCol == null ? void 0 : lastCol.width) || Default_Col_Width);
141
+ if (currentColWidth + moveX < props.colMinWidth) {
142
+ moveX = -currentColWidth;
143
+ }
144
+ const offsetTableX = startOffsetTableX + moveX;
145
+ if (!colResizeIndicator.value)
146
+ return;
147
+ colResizeIndicator.value.style.left = offsetTableX + "px";
148
+ }
149
+ function onThResizeMouseUp(e) {
150
+ if (!isColResizing.value)
151
+ return;
152
+ const { startX, lastCol } = colResizeState;
153
+ const { clientX } = e;
154
+ const moveX = clientX - startX;
155
+ let width = parseInt((lastCol == null ? void 0 : lastCol.width) || Default_Col_Width) + moveX;
156
+ if (width < props.colMinWidth)
157
+ width = props.colMinWidth;
158
+ const curCol = tableHeaderLast.value.find((it) => colKeyGen(it) === colKeyGen(lastCol));
159
+ if (!curCol)
160
+ return;
161
+ curCol.width = width + "px";
162
+ emits("update:columns", [...props.columns]);
163
+ if (colResizeIndicator.value) {
164
+ const style = colResizeIndicator.value.style;
165
+ style.display = "none";
166
+ style.left = "0";
167
+ style.top = "0";
168
+ }
169
+ isColResizing.value = false;
170
+ colResizeState = {
171
+ currentCol: null,
172
+ currentColIndex: 0,
173
+ lastCol: null,
174
+ startX: 0,
175
+ startOffsetTableX: 0
176
+ };
177
+ }
178
+ function findLastChildCol(column) {
179
+ var _a;
180
+ if ((_a = column == null ? void 0 : column.children) == null ? void 0 : _a.length) {
181
+ const lastChild = column.children.at(-1);
182
+ return findLastChildCol(lastChild);
183
+ }
184
+ return column;
185
+ }
186
+ return {
187
+ isColResizing,
188
+ onThResizeMouseDown,
189
+ onThResizeMouseMove,
190
+ onThResizeMouseUp
191
+ };
192
+ }
193
+ function useFixedCol({ props, tableHeaderLast, tableContainer }) {
194
+ const fixedShadow = ref({
195
+ showL: false,
196
+ showR: false
197
+ });
198
+ let fixedShadowCols = [];
199
+ function dealFixedColShadow() {
200
+ if (!props.fixedColShadow)
201
+ return;
202
+ fixedShadowCols = [];
203
+ let lastLeftCol = null;
204
+ for (let i = tableHeaderLast.value.length - 1; i > 0; i--) {
205
+ const col = tableHeaderLast.value[i];
206
+ if (col.fixed === "left") {
207
+ lastLeftCol = col;
208
+ break;
209
+ }
210
+ }
211
+ let node = { __PARENT__: lastLeftCol };
212
+ while (node = node.__PARENT__) {
213
+ if (node.fixed) {
214
+ fixedShadowCols.push(node);
215
+ }
216
+ }
217
+ const lastRightCol = tableHeaderLast.value.find((it) => it.fixed === "right");
218
+ node = { __PARENT__: lastRightCol };
219
+ while (node = node.__PARENT__) {
220
+ if (node.fixed) {
221
+ fixedShadowCols.push(node);
222
+ }
223
+ }
224
+ }
225
+ function getFixedColClass(col) {
226
+ const { showR, showL } = fixedShadow.value;
227
+ const showShadow = props.fixedColShadow && col.fixed && (showL && col.fixed === "left" || showR && col.fixed === "right") && fixedShadowCols.includes(col);
228
+ const classObj = {
229
+ "fixed-cell": col.fixed,
230
+ ["fixed-cell--" + col.fixed]: col.fixed,
231
+ "fixed-cell--shadow": showShadow
232
+ };
233
+ return classObj;
234
+ }
235
+ function updateFixedShadow() {
236
+ if (!props.fixedColShadow)
237
+ return;
238
+ const { clientWidth, scrollWidth, scrollLeft } = tableContainer.value;
239
+ fixedShadow.value.showL = Boolean(scrollLeft);
240
+ fixedShadow.value.showR = Math.abs(scrollWidth - scrollLeft - clientWidth) > 0.5;
241
+ }
242
+ return {
243
+ /** 固定列class */
244
+ getFixedColClass,
245
+ /** 处理固定列阴影 */
246
+ dealFixedColShadow,
247
+ /** 滚动条变化时,更新需要展示阴影的列 */
248
+ updateFixedShadow
249
+ };
250
+ }
251
+ function useFixedStyle({ props, tableHeaderLast, virtualScroll, virtualScrollX, virtualX_on, virtualX_offsetRight }) {
252
+ const fixedColumnsPositionStore = computed(() => {
253
+ const store = {};
254
+ const cols = [...tableHeaderLast.value];
255
+ let left = 0;
256
+ let rightStartIndex = 0;
257
+ for (let i = 0; i < cols.length; i++) {
258
+ const item = cols[i];
259
+ if (item.fixed === "left") {
260
+ store[item.dataIndex] = left;
261
+ left += parseInt(item.width || Default_Col_Width);
262
+ }
263
+ if (!rightStartIndex && item.fixed === "right") {
264
+ rightStartIndex = i;
265
+ }
266
+ }
267
+ let right = 0;
268
+ for (let i = cols.length - 1; i >= rightStartIndex; i--) {
269
+ const item = cols[i];
270
+ if (item.fixed === "right") {
271
+ store[item.dataIndex] = right;
272
+ right += parseInt(item.width || Default_Col_Width);
273
+ }
274
+ }
275
+ return store;
276
+ });
277
+ function getFixedStyle(tagType, col, depth = 0) {
278
+ const { fixed, dataIndex } = col;
279
+ const isFixedLeft = fixed === "left";
280
+ const style = {};
281
+ if (Is_Legacy_Mode) {
282
+ style.position = "relative";
283
+ } else {
284
+ style.position = "sticky";
285
+ }
286
+ if (tagType === 1) {
287
+ if (Is_Legacy_Mode) {
288
+ style.top = virtualScroll.value.scrollTop + depth * props.rowHeight + "px";
289
+ } else {
290
+ style.top = depth * props.rowHeight + "px";
291
+ }
292
+ style.zIndex = isFixedLeft ? "5" : "4";
293
+ } else {
294
+ style.zIndex = isFixedLeft ? "3" : "2";
295
+ }
296
+ if (fixed === "left" || fixed === "right") {
297
+ if (Is_Legacy_Mode) {
298
+ if (isFixedLeft) {
299
+ if (virtualX_on.value)
300
+ style.left = virtualScrollX.value.scrollLeft - virtualScrollX.value.offsetLeft + "px";
301
+ else
302
+ style.left = virtualScrollX.value.scrollLeft + "px";
303
+ } else {
304
+ style.right = `${virtualX_offsetRight.value}px`;
305
+ }
306
+ } else {
307
+ if (isFixedLeft) {
308
+ style.left = fixedColumnsPositionStore.value[dataIndex] + "px";
309
+ } else {
310
+ style.right = fixedColumnsPositionStore.value[dataIndex] + "px";
311
+ }
312
+ }
313
+ }
314
+ return style;
315
+ }
316
+ return {
317
+ getFixedStyle
318
+ };
319
+ }
320
+ function useHighlight({ props, tableContainer, rowKeyGen }) {
321
+ const highlightInter = computed(() => {
322
+ return interpolateRgb(Highlight_Color[props.theme].from, Highlight_Color[props.theme].to);
323
+ });
324
+ const highlightDimRows = /* @__PURE__ */ new Set();
325
+ const highlightDimRowsTimeout = /* @__PURE__ */ new Map();
326
+ const highlightDimCellsTimeout = /* @__PURE__ */ new Map();
327
+ let calcHighlightDimLoop = false;
328
+ function calcHighlightLoop() {
329
+ if (calcHighlightDimLoop)
330
+ return;
331
+ calcHighlightDimLoop = true;
332
+ const recursion = () => {
333
+ window.setTimeout(() => {
334
+ const nowTs = Date.now();
335
+ const needDeleteRows = [];
336
+ highlightDimRows.forEach((row) => {
337
+ const progress = (nowTs - row._bgc_progress_ms) / Highlight_Duration;
338
+ if (0 < progress && progress < 1) {
339
+ row._bgc = highlightInter.value(progress);
340
+ } else {
341
+ row._bgc = "";
342
+ needDeleteRows.push(row);
343
+ }
344
+ });
345
+ needDeleteRows.forEach((row) => highlightDimRows.delete(row));
346
+ if (highlightDimRows.size > 0) {
347
+ recursion();
348
+ } else {
349
+ calcHighlightDimLoop = false;
350
+ }
351
+ }, Highlight_Color_Change_Freq);
352
+ };
353
+ recursion();
354
+ }
355
+ function setHighlightDimCell(rowKeyValue, dataIndex) {
356
+ var _a;
357
+ const cellEl = (_a = tableContainer.value) == null ? void 0 : _a.querySelector(`[data-row-key="${rowKeyValue}"]>[data-index="${dataIndex}"]`);
358
+ if (!cellEl)
359
+ return;
360
+ if (cellEl.classList.contains("highlight-cell")) {
361
+ cellEl.classList.remove("highlight-cell");
362
+ void cellEl.offsetHeight;
363
+ }
364
+ cellEl.classList.add("highlight-cell");
365
+ window.clearTimeout(highlightDimCellsTimeout.get(rowKeyValue));
366
+ highlightDimCellsTimeout.set(
367
+ rowKeyValue,
368
+ window.setTimeout(() => {
369
+ cellEl.classList.remove("highlight-cell");
370
+ highlightDimCellsTimeout.delete(rowKeyValue);
371
+ }, Highlight_Duration)
372
+ );
373
+ }
374
+ function setHighlightDimRow(rowKeyValues) {
375
+ var _a, _b;
376
+ if (!Array.isArray(rowKeyValues))
377
+ rowKeyValues = [rowKeyValues];
378
+ if (props.virtual) {
379
+ const nowTs = Date.now();
380
+ for (let i = 0; i < rowKeyValues.length; i++) {
381
+ const rowKeyValue = rowKeyValues[i];
382
+ const row = props.dataSource.find((it) => rowKeyGen(it) === rowKeyValue);
383
+ if (!row)
384
+ continue;
385
+ row._bgc_progress_ms = nowTs;
386
+ highlightDimRows.add(row);
387
+ }
388
+ calcHighlightLoop();
389
+ } else {
390
+ let needRepaint = false;
391
+ const rowElTemp = [];
392
+ for (let i = 0; i < rowKeyValues.length; i++) {
393
+ const rowKeyValue = rowKeyValues[i];
394
+ const rowEl = (_a = tableContainer.value) == null ? void 0 : _a.querySelector(`[data-row-key="${rowKeyValue}"]`);
395
+ if (!rowEl)
396
+ continue;
397
+ if (rowEl.classList.contains("highlight-row")) {
398
+ rowEl.classList.remove("highlight-row");
399
+ needRepaint = true;
400
+ }
401
+ rowElTemp.push(rowEl);
402
+ window.clearTimeout(highlightDimRowsTimeout.get(rowKeyValue));
403
+ highlightDimRowsTimeout.set(
404
+ rowKeyValue,
405
+ window.setTimeout(() => {
406
+ rowEl.classList.remove("highlight-row");
407
+ highlightDimRowsTimeout.delete(rowKeyValue);
408
+ }, Highlight_Duration)
409
+ );
410
+ }
411
+ if (needRepaint) {
412
+ void ((_b = tableContainer.value) == null ? void 0 : _b.offsetWidth);
413
+ }
414
+ rowElTemp.forEach((el) => el.classList.add("highlight-row"));
415
+ }
416
+ }
417
+ return {
418
+ setHighlightDimRow,
419
+ setHighlightDimCell
420
+ };
421
+ }
422
+ const SCROLL_CODES = ["ArrowUp", "ArrowRight", "ArrowDown", "ArrowLeft", "PageUp", "PageDown"];
423
+ function useKeyboardArrowScroll(targetElement, { props, scrollTo, virtualScroll, virtualScrollX, tableHeaders }) {
424
+ let isMouseOver = false;
425
+ onMounted(() => {
426
+ var _a, _b, _c;
427
+ window.addEventListener("keydown", handleKeydown);
428
+ (_a = targetElement.value) == null ? void 0 : _a.addEventListener("mouseenter", handleMouseEnter);
429
+ (_b = targetElement.value) == null ? void 0 : _b.addEventListener("mouseleave", handleMouseLeave);
430
+ (_c = targetElement.value) == null ? void 0 : _c.addEventListener("mousedown", handleMouseDown);
431
+ });
432
+ onBeforeUnmount(() => {
433
+ var _a, _b, _c;
434
+ window.removeEventListener("keydown", handleKeydown);
435
+ (_a = targetElement.value) == null ? void 0 : _a.removeEventListener("mouseenter", handleMouseEnter);
436
+ (_b = targetElement.value) == null ? void 0 : _b.removeEventListener("mouseleave", handleMouseLeave);
437
+ (_c = targetElement.value) == null ? void 0 : _c.removeEventListener("mousedown", handleMouseDown);
438
+ });
439
+ function handleKeydown(e) {
440
+ if (!SCROLL_CODES.includes(e.code))
441
+ return;
442
+ if (!isMouseOver)
443
+ return;
444
+ e.preventDefault();
445
+ const { scrollTop, rowHeight, pageSize } = virtualScroll.value;
446
+ const { scrollLeft } = virtualScrollX.value;
447
+ const { headless, headerRowHeight } = props;
448
+ const headerHeight = headless ? 0 : tableHeaders.value.length * (headerRowHeight || rowHeight);
449
+ if (e.code === SCROLL_CODES[0]) {
450
+ scrollTo(scrollTop - rowHeight, null);
451
+ } else if (e.code === SCROLL_CODES[1]) {
452
+ scrollTo(null, scrollLeft + rowHeight);
453
+ } else if (e.code === SCROLL_CODES[2]) {
454
+ scrollTo(scrollTop + rowHeight, null);
455
+ } else if (e.code === SCROLL_CODES[3]) {
456
+ scrollTo(null, scrollLeft - rowHeight);
457
+ } else if (e.code === SCROLL_CODES[4]) {
458
+ scrollTo(scrollTop - rowHeight * pageSize - headerHeight, null);
459
+ } else if (e.code === SCROLL_CODES[5]) {
460
+ scrollTo(scrollTop + rowHeight * pageSize - headerHeight, null);
461
+ }
462
+ }
463
+ function handleMouseEnter() {
464
+ isMouseOver = true;
465
+ }
466
+ function handleMouseLeave() {
467
+ isMouseOver = false;
468
+ }
469
+ function handleMouseDown() {
470
+ if (!isMouseOver)
471
+ isMouseOver = true;
472
+ }
473
+ }
474
+ function useThDrag({ emits }) {
475
+ let dragStartKey = void 0;
476
+ function onThDragStart(e) {
477
+ dragStartKey = e.target.dataset.colKey;
478
+ emits("th-drag-start", dragStartKey);
479
+ }
480
+ function onThDragOver(e) {
481
+ e.preventDefault();
482
+ }
483
+ function onThDrop(e) {
484
+ let th = e.target;
485
+ while (th) {
486
+ if (th.tagName === "TH")
487
+ break;
488
+ th = th.parentNode;
489
+ }
490
+ if (dragStartKey !== th.dataset.colKey) {
491
+ emits("col-order-change", dragStartKey, th.dataset.colKey);
492
+ }
493
+ emits("th-drop", th.dataset.colKey);
494
+ }
495
+ return {
496
+ onThDragStart,
497
+ onThDragOver,
498
+ onThDrop
499
+ };
500
+ }
501
+ function getCalcWidth(col) {
502
+ return parseInt(col.minWidth || col.width || Default_Col_Width);
503
+ }
504
+ const VUE2_SCROLL_TIMEOUT_MS = 200;
505
+ function useVirtualScroll({ props, tableContainer, dataSourceCopy, tableHeaderLast }) {
506
+ const virtualScroll = ref({
507
+ containerHeight: 0,
508
+ rowHeight: props.rowHeight,
509
+ pageSize: 10,
510
+ startIndex: 0,
511
+ endIndex: 0,
512
+ offsetTop: 0,
513
+ scrollTop: 0
514
+ });
515
+ const virtualScrollX = ref({
516
+ containerWidth: 0,
517
+ startIndex: 0,
518
+ endIndex: 0,
519
+ offsetLeft: 0,
520
+ scrollLeft: 0
521
+ });
522
+ const virtual_on = computed(() => {
523
+ return props.virtual && dataSourceCopy.value.length > virtualScroll.value.pageSize * 2;
524
+ });
525
+ const virtual_dataSourcePart = computed(() => {
526
+ if (!virtual_on.value)
527
+ return dataSourceCopy.value;
528
+ const { startIndex, endIndex } = virtualScroll.value;
529
+ return dataSourceCopy.value.slice(startIndex, endIndex);
530
+ });
531
+ const virtual_offsetBottom = computed(() => {
532
+ if (!virtual_on.value)
533
+ return 0;
534
+ const { startIndex, rowHeight } = virtualScroll.value;
535
+ return (dataSourceCopy.value.length - startIndex - virtual_dataSourcePart.value.length) * rowHeight;
536
+ });
537
+ const virtualX_on = computed(() => {
538
+ return props.virtualX && tableHeaderLast.value.reduce((sum, col) => sum += getCalcWidth(col), 0) > virtualScrollX.value.containerWidth + 100;
539
+ });
540
+ const virtualX_columnPart = computed(() => {
541
+ if (virtualX_on.value) {
542
+ const leftCols = [];
543
+ const rightCols = [];
544
+ const { startIndex, endIndex } = virtualScrollX.value;
545
+ for (let i = 0; i < startIndex; i++) {
546
+ const col = tableHeaderLast.value[i];
547
+ if (col.fixed === "left")
548
+ leftCols.push(col);
549
+ }
550
+ for (let i = endIndex; i < tableHeaderLast.value.length; i++) {
551
+ const col = tableHeaderLast.value[i];
552
+ if (col.fixed === "right")
553
+ rightCols.push(col);
554
+ }
555
+ const mainColumns = tableHeaderLast.value.slice(startIndex, endIndex);
556
+ return leftCols.concat(mainColumns).concat(rightCols);
557
+ }
558
+ return tableHeaderLast.value;
559
+ });
560
+ const virtualX_offsetRight = computed(() => {
561
+ if (!virtualX_on.value)
562
+ return 0;
563
+ let width = 0;
564
+ for (let i = virtualScrollX.value.endIndex; i < tableHeaderLast.value.length; i++) {
565
+ const col = tableHeaderLast.value[i];
566
+ if (col.fixed !== "right") {
567
+ width += getCalcWidth(col);
568
+ }
569
+ }
570
+ return width;
571
+ });
572
+ function initVirtualScrollY(height) {
573
+ if (!virtual_on.value)
574
+ return;
575
+ const { offsetHeight, scrollTop } = tableContainer.value || {};
576
+ const { rowHeight } = virtualScroll.value;
577
+ let containerHeight;
578
+ if (typeof height === "number") {
579
+ containerHeight = height;
580
+ } else {
581
+ containerHeight = offsetHeight || Default_Table_Height;
582
+ }
583
+ Object.assign(virtualScroll.value, {
584
+ containerHeight,
585
+ pageSize: Math.ceil(containerHeight / rowHeight) + 1
586
+ // 这里最终+1,因为headless=true无头时,需要上下各预渲染一行。
587
+ });
588
+ updateVirtualScrollY(scrollTop);
589
+ }
590
+ function initVirtualScrollX() {
591
+ if (!props.virtualX)
592
+ return;
593
+ const { offsetWidth, scrollLeft } = tableContainer.value || {};
594
+ virtualScrollX.value.containerWidth = offsetWidth || Default_Table_Width;
595
+ updateVirtualScrollX(scrollLeft);
596
+ }
597
+ function initVirtualScroll(height) {
598
+ initVirtualScrollY(height);
599
+ initVirtualScrollX();
600
+ }
601
+ let vue2ScrollYTimeout = null;
602
+ function updateVirtualScrollY(sTop = 0) {
603
+ const { rowHeight, pageSize, scrollTop, startIndex: oldStartIndex } = virtualScroll.value;
604
+ const startIndex = Math.floor(sTop / rowHeight);
605
+ const offsetTop = startIndex * rowHeight;
606
+ let endIndex = startIndex + pageSize;
607
+ if (endIndex > dataSourceCopy.value.length) {
608
+ endIndex = dataSourceCopy.value.length;
609
+ }
610
+ if (vue2ScrollYTimeout) {
611
+ window.clearTimeout(vue2ScrollYTimeout);
612
+ }
613
+ if (!props.optimizeVue2Scroll || sTop <= scrollTop || Math.abs(oldStartIndex - startIndex) >= pageSize) {
614
+ Object.assign(virtualScroll.value, {
615
+ startIndex,
616
+ offsetTop,
617
+ endIndex,
618
+ scrollTop: sTop
619
+ });
620
+ } else {
621
+ Object.assign(virtualScroll.value, { endIndex, scrollTop: sTop });
622
+ vue2ScrollYTimeout = window.setTimeout(() => {
623
+ Object.assign(virtualScroll.value, { startIndex, offsetTop });
624
+ }, VUE2_SCROLL_TIMEOUT_MS);
625
+ }
626
+ }
627
+ let vue2ScrollXTimeout = null;
628
+ function updateVirtualScrollX(sLeft = 0) {
629
+ var _a;
630
+ const headerLength = (_a = tableHeaderLast.value) == null ? void 0 : _a.length;
631
+ const { scrollLeft } = virtualScrollX.value;
632
+ if (!headerLength)
633
+ return;
634
+ let startIndex = 0;
635
+ let offsetLeft = 0;
636
+ let colWidthSum = 0;
637
+ for (let colIndex = 0; colIndex < headerLength; colIndex++) {
638
+ startIndex++;
639
+ const col = tableHeaderLast.value[colIndex];
640
+ if (col.fixed === "left")
641
+ continue;
642
+ const colWidth = getCalcWidth(col);
643
+ colWidthSum += colWidth;
644
+ if (colWidthSum >= sLeft) {
645
+ offsetLeft = colWidthSum - colWidth;
646
+ startIndex--;
647
+ break;
648
+ }
649
+ }
650
+ colWidthSum = 0;
651
+ let endIndex = headerLength;
652
+ for (let colIndex = startIndex + 1; colIndex < headerLength; colIndex++) {
653
+ const col = tableHeaderLast.value[colIndex];
654
+ colWidthSum += getCalcWidth(col);
655
+ if (colWidthSum >= virtualScrollX.value.containerWidth) {
656
+ endIndex = colIndex + 1;
657
+ break;
658
+ }
659
+ }
660
+ if (endIndex > headerLength) {
661
+ endIndex = headerLength;
662
+ }
663
+ if (vue2ScrollXTimeout) {
664
+ window.clearTimeout(vue2ScrollXTimeout);
665
+ }
666
+ if (!props.optimizeVue2Scroll || sLeft <= scrollLeft) {
667
+ Object.assign(virtualScrollX.value, { startIndex, endIndex, offsetLeft, scrollLeft: sLeft });
668
+ } else {
669
+ Object.assign(virtualScrollX.value, { endIndex, scrollLeft: sLeft });
670
+ vue2ScrollXTimeout = window.setTimeout(() => {
671
+ Object.assign(virtualScrollX.value, { startIndex, offsetLeft });
672
+ }, VUE2_SCROLL_TIMEOUT_MS);
673
+ }
674
+ }
675
+ return {
676
+ virtualScroll,
677
+ virtualScrollX,
678
+ virtual_on,
679
+ virtual_dataSourcePart,
680
+ virtual_offsetBottom,
681
+ virtualX_on,
682
+ virtualX_columnPart,
683
+ virtualX_offsetRight,
684
+ initVirtualScroll,
685
+ initVirtualScrollY,
686
+ initVirtualScrollX,
687
+ updateVirtualScrollY,
688
+ updateVirtualScrollX
689
+ };
690
+ }
691
+ function insertToOrderedArray(sortState, newItem, targetArray) {
692
+ const { dataIndex, order } = sortState;
693
+ let { sortType } = sortState;
694
+ if (!sortType)
695
+ sortType = typeof newItem[dataIndex];
696
+ const data = [...targetArray];
697
+ if (!order) {
698
+ data.unshift(newItem);
699
+ return data;
700
+ }
701
+ let sIndex = 0;
702
+ let eIndex = data.length - 1;
703
+ const targetVal = newItem[dataIndex];
704
+ while (sIndex <= eIndex) {
705
+ const midIndex = Math.floor((sIndex + eIndex) / 2);
706
+ const midVal = data[midIndex][dataIndex];
707
+ const compareRes = strCompare(midVal, targetVal, sortType);
708
+ if (compareRes === 0) {
709
+ sIndex = midIndex;
710
+ break;
711
+ } else if (compareRes === -1) {
712
+ if (order === "asc")
713
+ sIndex = midIndex + 1;
714
+ else
715
+ eIndex = midIndex - 1;
716
+ } else {
717
+ if (order === "asc")
718
+ eIndex = midIndex - 1;
719
+ else
720
+ sIndex = midIndex + 1;
721
+ }
722
+ }
723
+ data.splice(sIndex, 0, newItem);
724
+ return data;
725
+ }
726
+ function strCompare(a, b, type) {
727
+ if (type === "number") {
728
+ if (+a > +b)
729
+ return 1;
730
+ else if (+a === +b)
731
+ return 0;
732
+ else
733
+ return -1;
734
+ } else {
735
+ return String(a).localeCompare(b);
736
+ }
737
+ }
738
+ function tableSort(sortOption, order, dataSource) {
739
+ if (!(dataSource == null ? void 0 : dataSource.length))
740
+ return dataSource || [];
741
+ let targetDataSource = [...dataSource];
742
+ if (typeof sortOption.sorter === "function") {
743
+ const customSorterData = sortOption.sorter(targetDataSource, { order, column: sortOption });
744
+ if (customSorterData)
745
+ targetDataSource = customSorterData;
746
+ } else if (order) {
747
+ const sortField = sortOption.sortField || sortOption.dataIndex;
748
+ let { sortType } = sortOption;
749
+ if (!sortType)
750
+ sortType = typeof dataSource[0][sortField];
751
+ if (sortType === "number") {
752
+ const nanArr = [];
753
+ const numArr = [];
754
+ for (let i = 0; i < targetDataSource.length; i++) {
755
+ const row = targetDataSource[i];
756
+ if (row[sortField] === null || row[sortField] === "" || typeof row[sortField] === "boolean" || Number.isNaN(+row[sortField])) {
757
+ nanArr.push(row);
758
+ } else {
759
+ numArr.push(row);
760
+ }
761
+ }
762
+ if (order === "asc") {
763
+ numArr.sort((a, b) => +a[sortField] - +b[sortField]);
764
+ targetDataSource = [...nanArr, ...numArr];
765
+ } else {
766
+ numArr.sort((a, b) => +b[sortField] - +a[sortField]);
767
+ targetDataSource = [...numArr, ...nanArr];
768
+ }
769
+ } else {
770
+ if (order === "asc") {
771
+ targetDataSource.sort((a, b) => String(a[sortField]).localeCompare(b[sortField]));
772
+ } else {
773
+ targetDataSource.sort((a, b) => String(a[sortField]).localeCompare(b[sortField]) * -1);
774
+ }
775
+ }
776
+ }
777
+ return targetDataSource;
778
+ }
779
+ function howDeepTheHeader(arr, level = 1) {
780
+ const levels = [level];
781
+ arr.forEach((item) => {
782
+ var _a;
783
+ if ((_a = item.children) == null ? void 0 : _a.length) {
784
+ levels.push(howDeepTheHeader(item.children, level + 1));
785
+ }
786
+ });
787
+ return Math.max(...levels);
788
+ }
789
+ const _hoisted_1 = {
790
+ key: 0
791
+ };
792
+ const _hoisted_2 = ["data-col-key", "draggable", "rowspan", "colspan", "title", "onClick"];
793
+ const _hoisted_3 = {
794
+ class: "table-header-cell-wrapper"
795
+ };
796
+ const _hoisted_4 = {
797
+ class: "table-header-title"
798
+ };
799
+ const _hoisted_5 = {
800
+ key: 2,
801
+ class: "table-header-sorter"
802
+ };
803
+ const _hoisted_6 = /* @__PURE__ */ createElementVNode("svg", {
804
+ xmlns: "http://www.w3.org/2000/svg",
805
+ width: "16px",
806
+ height: "16px",
807
+ viewBox: "0 0 16 16"
808
+ }, [/* @__PURE__ */ createElementVNode("polygon", {
809
+ class: "arrow-up",
810
+ fill: "#757699",
811
+ points: "8 2 4.8 6 11.2 6"
812
+ }), /* @__PURE__ */ createElementVNode("polygon", {
813
+ class: "arrow-down",
814
+ transform: "translate(8, 12) rotate(-180) translate(-8, -12) ",
815
+ points: "8 10 4.8 14 11.2 14"
816
+ })], -1);
817
+ const _hoisted_7 = [_hoisted_6];
818
+ const _hoisted_8 = ["onMousedown"];
819
+ const _hoisted_9 = ["onMousedown"];
820
+ const _hoisted_10 = {
821
+ key: 0,
822
+ class: "virtual-x-left",
823
+ style: {
824
+ "padding": "0"
825
+ }
826
+ };
827
+ const _hoisted_11 = ["data-row-key", "onClick", "onDblclick", "onContextmenu", "onMouseover"];
828
+ const _hoisted_12 = {
829
+ key: 0,
830
+ class: "virtual-x-left",
831
+ style: {
832
+ "padding": "0"
833
+ }
834
+ };
835
+ const _hoisted_13 = ["data-index", "onClick"];
836
+ const _hoisted_14 = ["title"];
837
+ const _sfc_main = /* @__PURE__ */ defineComponent({
838
+ __name: "StkTable",
839
+ props: {
840
+ width: {
841
+ default: ""
842
+ },
843
+ minWidth: {
844
+ default: ""
845
+ },
846
+ maxWidth: {
847
+ default: ""
848
+ },
849
+ stripe: {
850
+ type: Boolean,
851
+ default: false
852
+ },
853
+ fixedMode: {
854
+ type: Boolean,
855
+ default: false
856
+ },
857
+ headless: {
858
+ type: Boolean,
859
+ default: false
860
+ },
861
+ theme: {
862
+ default: "light"
863
+ },
864
+ rowHeight: {
865
+ default: Default_Row_Height
866
+ },
867
+ headerRowHeight: {
868
+ default: null
869
+ },
870
+ virtual: {
871
+ type: Boolean,
872
+ default: false
873
+ },
874
+ virtualX: {
875
+ type: Boolean,
876
+ default: false
877
+ },
878
+ columns: {
879
+ default: () => []
880
+ },
881
+ dataSource: {
882
+ default: () => []
883
+ },
884
+ rowKey: {
885
+ type: [String, Function],
886
+ default: ""
887
+ },
888
+ colKey: {
889
+ type: [String, Function],
890
+ default: "dataIndex"
891
+ },
892
+ emptyCellText: {
893
+ default: "--"
894
+ },
895
+ noDataFull: {
896
+ type: Boolean,
897
+ default: false
898
+ },
899
+ showNoData: {
900
+ type: Boolean,
901
+ default: true
902
+ },
903
+ sortRemote: {
904
+ type: Boolean,
905
+ default: false
906
+ },
907
+ showHeaderOverflow: {
908
+ type: Boolean,
909
+ default: false
910
+ },
911
+ showOverflow: {
912
+ type: Boolean,
913
+ default: false
914
+ },
915
+ showTrHoverClass: {
916
+ type: Boolean,
917
+ default: false
918
+ },
919
+ headerDrag: {
920
+ type: Boolean,
921
+ default: false
922
+ },
923
+ rowClassName: {
924
+ type: Function,
925
+ default: () => ""
926
+ },
927
+ colResizable: {
928
+ type: Boolean,
929
+ default: false
930
+ },
931
+ colMinWidth: {
932
+ default: 10
933
+ },
934
+ bordered: {
935
+ type: [Boolean, String],
936
+ default: true
937
+ },
938
+ autoResize: {
939
+ type: [Boolean, Function],
940
+ default: true
941
+ },
942
+ fixedColShadow: {
943
+ type: Boolean,
944
+ default: false
945
+ },
946
+ optimizeVue2Scroll: {
947
+ type: Boolean,
948
+ default: false
949
+ }
950
+ },
951
+ emits: ["sort-change", "row-click", "current-change", "row-dblclick", "header-row-menu", "row-menu", "cell-click", "header-cell-click", "scroll", "scroll-x", "col-order-change", "th-drag-start", "th-drop", "update:columns"],
952
+ setup(__props, {
953
+ expose: __expose,
954
+ emit: __emit
955
+ }) {
956
+ const props = __props;
957
+ const emits = __emit;
958
+ const tableContainer = ref();
959
+ const colResizeIndicator = ref();
960
+ const currentItem = ref(null);
961
+ const currentItemKey = ref(null);
962
+ const currentHover = ref(null);
963
+ let sortCol = ref();
964
+ let sortOrderIndex = ref(0);
965
+ const sortSwitchOrder = [null, "desc", "asc"];
966
+ const tableHeaders = ref([]);
967
+ const tableHeaderLast = ref([]);
968
+ const dataSourceCopy = shallowRef([...props.dataSource]);
969
+ const rowKeyGenStore = /* @__PURE__ */ new WeakMap();
970
+ const {
971
+ isColResizing,
972
+ onThResizeMouseDown
973
+ } = useColResize({
974
+ props,
975
+ emits,
976
+ colKeyGen,
977
+ colResizeIndicator,
978
+ tableContainer,
979
+ tableHeaderLast
980
+ });
981
+ const {
982
+ onThDragStart,
983
+ onThDragOver,
984
+ onThDrop
985
+ } = useThDrag({
986
+ emits
987
+ });
988
+ const {
989
+ virtualScroll,
990
+ virtualScrollX,
991
+ virtual_on,
992
+ virtual_dataSourcePart,
993
+ virtual_offsetBottom,
994
+ virtualX_on,
995
+ virtualX_columnPart,
996
+ virtualX_offsetRight,
997
+ initVirtualScroll,
998
+ initVirtualScrollY,
999
+ initVirtualScrollX,
1000
+ updateVirtualScrollY,
1001
+ updateVirtualScrollX
1002
+ } = useVirtualScroll({
1003
+ tableContainer,
1004
+ props,
1005
+ dataSourceCopy,
1006
+ tableHeaderLast
1007
+ });
1008
+ const {
1009
+ getFixedStyle
1010
+ } = useFixedStyle({
1011
+ props,
1012
+ tableHeaderLast,
1013
+ virtualScroll,
1014
+ virtualScrollX,
1015
+ virtualX_on,
1016
+ virtualX_offsetRight
1017
+ });
1018
+ const {
1019
+ setHighlightDimCell,
1020
+ setHighlightDimRow
1021
+ } = useHighlight({
1022
+ props,
1023
+ tableContainer,
1024
+ rowKeyGen
1025
+ });
1026
+ if (props.autoResize) {
1027
+ useAutoResize({
1028
+ tableContainer,
1029
+ initVirtualScroll,
1030
+ scrollTo,
1031
+ props,
1032
+ debounceMs: 500
1033
+ });
1034
+ }
1035
+ useKeyboardArrowScroll(tableContainer, {
1036
+ props,
1037
+ scrollTo,
1038
+ virtualScroll,
1039
+ virtualScrollX,
1040
+ tableHeaders
1041
+ });
1042
+ const {
1043
+ getFixedColClass,
1044
+ dealFixedColShadow,
1045
+ updateFixedShadow
1046
+ } = useFixedCol({
1047
+ props,
1048
+ tableContainer,
1049
+ tableHeaderLast
1050
+ });
1051
+ watch(() => props.columns, () => {
1052
+ dealColumns();
1053
+ initVirtualScrollX();
1054
+ });
1055
+ dealColumns();
1056
+ watch(() => props.dataSource, (val) => {
1057
+ if (!val) {
1058
+ console.warn("invalid dataSource");
1059
+ return;
1060
+ }
1061
+ let needInitVirtualScrollY = false;
1062
+ if (dataSourceCopy.value.length !== val.length) {
1063
+ needInitVirtualScrollY = true;
1064
+ }
1065
+ dataSourceCopy.value = [...val];
1066
+ if (needInitVirtualScrollY)
1067
+ initVirtualScrollY();
1068
+ if (sortCol.value) {
1069
+ const column = tableHeaderLast.value.find((it) => it.dataIndex === sortCol.value);
1070
+ onColumnSort(column, false);
1071
+ }
1072
+ updateFixedShadow();
1073
+ }, {
1074
+ deep: false
1075
+ });
1076
+ watch(() => props.fixedColShadow, dealFixedColShadow);
1077
+ onMounted(() => {
1078
+ initVirtualScroll();
1079
+ updateFixedShadow();
1080
+ });
1081
+ function dealColumns() {
1082
+ tableHeaders.value = [];
1083
+ tableHeaderLast.value = [];
1084
+ const copyColumn = props.columns;
1085
+ const deep = howDeepTheHeader(copyColumn);
1086
+ const tempHeaderLast = [];
1087
+ if (deep > 1 && props.virtualX) {
1088
+ console.error("多级表头不支持横向虚拟滚动");
1089
+ }
1090
+ function flat(arr, parent, depth = 0) {
1091
+ if (!tableHeaders.value[depth]) {
1092
+ tableHeaders.value[depth] = [];
1093
+ }
1094
+ let allChildrenLen = 0;
1095
+ arr.forEach((col) => {
1096
+ col.__PARENT__ = parent;
1097
+ let colChildrenLen = 1;
1098
+ if (col.children) {
1099
+ colChildrenLen = flat(
1100
+ col.children,
1101
+ col,
1102
+ depth + 1
1103
+ /* , col.fixed */
1104
+ );
1105
+ } else {
1106
+ tempHeaderLast.push(col);
1107
+ }
1108
+ tableHeaders.value[depth].push(col);
1109
+ const rowSpan = col.children ? 1 : deep - depth;
1110
+ const colSpan = colChildrenLen;
1111
+ if (rowSpan !== 1) {
1112
+ col.rowSpan = rowSpan;
1113
+ }
1114
+ if (colSpan !== 1) {
1115
+ col.colSpan = colSpan;
1116
+ }
1117
+ allChildrenLen += colChildrenLen;
1118
+ });
1119
+ return allChildrenLen;
1120
+ }
1121
+ flat(copyColumn, null);
1122
+ tableHeaderLast.value = tempHeaderLast;
1123
+ dealFixedColShadow();
1124
+ }
1125
+ function rowKeyGen(row) {
1126
+ if (!row)
1127
+ return;
1128
+ let key = rowKeyGenStore.get(row);
1129
+ if (!key) {
1130
+ key = typeof props.rowKey === "function" ? props.rowKey(row) : row[props.rowKey];
1131
+ rowKeyGenStore.set(row, key);
1132
+ }
1133
+ return key;
1134
+ }
1135
+ function colKeyGen(col) {
1136
+ return typeof props.colKey === "function" ? props.colKey(col) : col[props.colKey];
1137
+ }
1138
+ function getColWidthStyle(col) {
1139
+ const style = {
1140
+ width: col.width,
1141
+ minWidth: col.minWidth,
1142
+ maxWidth: col.maxWidth
1143
+ };
1144
+ if (props.colResizable) {
1145
+ style.minWidth = col.width;
1146
+ style.maxWidth = col.width;
1147
+ } else {
1148
+ style.minWidth = col.minWidth === void 0 ? col.width : col.minWidth;
1149
+ style.maxWidth = col.maxWidth === void 0 ? col.width : col.maxWidth;
1150
+ }
1151
+ return style;
1152
+ }
1153
+ function getCellStyle(tagType, col, depth) {
1154
+ const style = {
1155
+ ...getColWidthStyle(col),
1156
+ ...getFixedStyle(tagType, col, depth)
1157
+ };
1158
+ if (tagType === 1) {
1159
+ style.textAlign = col.headerAlign;
1160
+ } else if (tagType === 2) {
1161
+ style.textAlign = col.align;
1162
+ }
1163
+ return style;
1164
+ }
1165
+ function onColumnSort(col, click = true, options = {}) {
1166
+ if (!(col == null ? void 0 : col.sorter))
1167
+ return;
1168
+ options = {
1169
+ force: false,
1170
+ emit: false,
1171
+ ...options
1172
+ };
1173
+ if (sortCol.value !== col.dataIndex) {
1174
+ sortCol.value = col.dataIndex;
1175
+ sortOrderIndex.value = 0;
1176
+ }
1177
+ if (click)
1178
+ sortOrderIndex.value++;
1179
+ sortOrderIndex.value = sortOrderIndex.value % 3;
1180
+ const order = sortSwitchOrder[sortOrderIndex.value];
1181
+ if (!props.sortRemote || options.force) {
1182
+ dataSourceCopy.value = tableSort(col, order, props.dataSource);
1183
+ }
1184
+ if (click || options.emit) {
1185
+ emits("sort-change", col, order, toRaw(dataSourceCopy.value));
1186
+ }
1187
+ }
1188
+ function onRowClick(e, row) {
1189
+ emits("row-click", e, row);
1190
+ if (props.rowKey ? currentItemKey.value === rowKeyGen(row) : currentItem.value === row)
1191
+ return;
1192
+ currentItem.value = row;
1193
+ currentItemKey.value = rowKeyGen(row);
1194
+ emits("current-change", e, row);
1195
+ }
1196
+ function onRowDblclick(e, row) {
1197
+ emits("row-dblclick", e, row);
1198
+ }
1199
+ function onHeaderMenu(e) {
1200
+ emits("header-row-menu", e);
1201
+ }
1202
+ function onRowMenu(e, row) {
1203
+ emits("row-menu", e, row);
1204
+ }
1205
+ function onCellClick(e, row, col) {
1206
+ emits("cell-click", e, row, col);
1207
+ }
1208
+ function onHeaderCellClick(e, col) {
1209
+ emits("header-cell-click", e, col);
1210
+ }
1211
+ function onTableWheel(e) {
1212
+ if (isColResizing.value) {
1213
+ e.preventDefault();
1214
+ e.stopPropagation();
1215
+ return;
1216
+ }
1217
+ }
1218
+ function onTableScroll(e) {
1219
+ if (!(e == null ? void 0 : e.target))
1220
+ return;
1221
+ const {
1222
+ scrollTop,
1223
+ scrollLeft
1224
+ } = e.target;
1225
+ const {
1226
+ scrollTop: vScrollTop
1227
+ } = virtualScroll.value;
1228
+ const {
1229
+ scrollLeft: vScrollLeft
1230
+ } = virtualScrollX.value;
1231
+ const isYScroll = scrollTop !== vScrollTop;
1232
+ const isXScroll = scrollLeft !== vScrollLeft;
1233
+ if (isYScroll && virtual_on.value) {
1234
+ updateVirtualScrollY(scrollTop);
1235
+ }
1236
+ if (isXScroll) {
1237
+ updateFixedShadow();
1238
+ if (virtualX_on.value) {
1239
+ updateVirtualScrollX(scrollLeft);
1240
+ }
1241
+ }
1242
+ const {
1243
+ startIndex,
1244
+ endIndex
1245
+ } = virtualScroll.value;
1246
+ const data = {
1247
+ startIndex,
1248
+ endIndex
1249
+ };
1250
+ if (isYScroll) {
1251
+ emits("scroll", e, data);
1252
+ }
1253
+ if (isXScroll) {
1254
+ emits("scroll-x", e);
1255
+ }
1256
+ }
1257
+ function onTrMouseOver(_e, row) {
1258
+ if (props.showTrHoverClass) {
1259
+ currentHover.value = rowKeyGen(row);
1260
+ }
1261
+ }
1262
+ function setCurrentRow(rowKey, option = {
1263
+ silent: false
1264
+ }) {
1265
+ if (!dataSourceCopy.value.length)
1266
+ return;
1267
+ currentItem.value = dataSourceCopy.value.find((it) => rowKeyGen(it) === rowKey);
1268
+ currentItemKey.value = rowKeyGen(currentItem.value);
1269
+ if (!option.silent) {
1270
+ emits("current-change", null, currentItem.value);
1271
+ }
1272
+ }
1273
+ function setSorter(dataIndex, order, option = {}) {
1274
+ var _a;
1275
+ const newOption = {
1276
+ silent: true,
1277
+ sortOption: null,
1278
+ sort: true,
1279
+ ...option
1280
+ };
1281
+ sortCol.value = dataIndex;
1282
+ sortOrderIndex.value = sortSwitchOrder.findIndex((it) => it === order);
1283
+ if (newOption.sort && ((_a = dataSourceCopy.value) == null ? void 0 : _a.length)) {
1284
+ const column = newOption.sortOption || tableHeaderLast.value.find((it) => it.dataIndex === sortCol.value);
1285
+ if (column)
1286
+ onColumnSort(column, false, {
1287
+ force: true,
1288
+ emit: !newOption.silent
1289
+ });
1290
+ else
1291
+ console.warn("Can not find column by dataIndex:", sortCol.value);
1292
+ }
1293
+ return dataSourceCopy.value;
1294
+ }
1295
+ function resetSorter() {
1296
+ sortCol.value = null;
1297
+ sortOrderIndex.value = 0;
1298
+ dataSourceCopy.value = [...props.dataSource];
1299
+ }
1300
+ function scrollTo(top = 0, left = 0) {
1301
+ if (!tableContainer.value)
1302
+ return;
1303
+ if (top !== null)
1304
+ tableContainer.value.scrollTop = top;
1305
+ if (left !== null)
1306
+ tableContainer.value.scrollLeft = left;
1307
+ }
1308
+ function getTableData() {
1309
+ return toRaw(dataSourceCopy.value);
1310
+ }
1311
+ __expose({
1312
+ /** 初始化横向纵向虚拟滚动 */
1313
+ initVirtualScroll,
1314
+ /** 初始化横向虚拟滚动 */
1315
+ initVirtualScrollX,
1316
+ /** 初始化纵向虚拟滚动 */
1317
+ initVirtualScrollY,
1318
+ /** 设置当前选中行 */
1319
+ setCurrentRow,
1320
+ /** 设置高亮渐暗单元格 */
1321
+ setHighlightDimCell,
1322
+ /** 设置高亮渐暗行 */
1323
+ setHighlightDimRow,
1324
+ /** 表格排序列dataIndex */
1325
+ sortCol,
1326
+ /** 设置排序 */
1327
+ setSorter,
1328
+ /** 重置排序 */
1329
+ resetSorter,
1330
+ /** 滚动至 */
1331
+ scrollTo,
1332
+ /** 获取表格数据 */
1333
+ getTableData
1334
+ });
1335
+ return (_ctx, _cache) => {
1336
+ return openBlock(), createElementBlock("div", {
1337
+ ref_key: "tableContainer",
1338
+ ref: tableContainer,
1339
+ class: normalizeClass(["stk-table", {
1340
+ virtual: _ctx.virtual,
1341
+ "virtual-x": _ctx.virtualX,
1342
+ dark: _ctx.theme === "dark",
1343
+ headless: _ctx.headless,
1344
+ "is-col-resizing": unref(isColResizing),
1345
+ "col-resizable": props.colResizable,
1346
+ border: props.bordered,
1347
+ "border-h": props.bordered === "h",
1348
+ "border-v": props.bordered === "v",
1349
+ "border-body-v": props.bordered === "body-v",
1350
+ stripe: props.stripe
1351
+ }]),
1352
+ style: normalizeStyle(_ctx.virtual && {
1353
+ "--row-height": unref(virtualScroll).rowHeight + "px",
1354
+ "--header-row-height": (props.headerRowHeight || props.rowHeight) + "px"
1355
+ }),
1356
+ onScroll: onTableScroll,
1357
+ onWheel: onTableWheel
1358
+ }, [withDirectives(createElementVNode("div", {
1359
+ ref_key: "colResizeIndicator",
1360
+ ref: colResizeIndicator,
1361
+ class: "column-resize-indicator"
1362
+ }, null, 512), [[vShow, _ctx.colResizable]]), createElementVNode("table", {
1363
+ class: normalizeClass(["stk-table-main", {
1364
+ "fixed-mode": props.fixedMode
1365
+ }]),
1366
+ style: normalizeStyle({
1367
+ width: _ctx.width,
1368
+ minWidth: _ctx.minWidth,
1369
+ maxWidth: _ctx.maxWidth
1370
+ })
1371
+ }, [!_ctx.headless ? (openBlock(), createElementBlock("thead", _hoisted_1, [(openBlock(true), createElementBlock(Fragment, null, renderList(tableHeaders.value, (row, rowIndex) => {
1372
+ return openBlock(), createElementBlock("tr", {
1373
+ key: rowIndex,
1374
+ onContextmenu: _cache[3] || (_cache[3] = (e) => onHeaderMenu(e))
1375
+ }, [unref(virtualX_on) ? (openBlock(), createElementBlock("th", {
1376
+ key: 0,
1377
+ class: "virtual-x-left",
1378
+ style: normalizeStyle({
1379
+ minWidth: unref(virtualScrollX).offsetLeft + "px",
1380
+ width: unref(virtualScrollX).offsetLeft + "px"
1381
+ })
1382
+ }, null, 4)) : createCommentVNode("", true), (openBlock(true), createElementBlock(Fragment, null, renderList(unref(virtualX_on) && rowIndex === tableHeaders.value.length - 1 ? unref(virtualX_columnPart) : row, (col, colIndex) => {
1383
+ return openBlock(), createElementBlock("th", {
1384
+ key: col.dataIndex,
1385
+ "data-col-key": colKeyGen(col),
1386
+ draggable: _ctx.headerDrag ? "true" : "false",
1387
+ rowspan: unref(virtualX_on) ? 1 : col.rowSpan,
1388
+ colspan: col.colSpan,
1389
+ style: normalizeStyle(getCellStyle(1, col, rowIndex)),
1390
+ title: col.title,
1391
+ class: normalizeClass([col.sorter ? "sortable" : "", col.dataIndex === unref(sortCol) && unref(sortOrderIndex) !== 0 && "sorter-" + sortSwitchOrder[unref(sortOrderIndex)], _ctx.showHeaderOverflow ? "text-overflow" : "", col.headerClassName, unref(getFixedColClass)(col)]),
1392
+ onClick: (e) => {
1393
+ onColumnSort(col);
1394
+ onHeaderCellClick(e, col);
1395
+ },
1396
+ onDragstart: _cache[0] || (_cache[0] = //@ts-ignore
1397
+ (...args) => unref(onThDragStart) && unref(onThDragStart)(...args)),
1398
+ onDrop: _cache[1] || (_cache[1] = //@ts-ignore
1399
+ (...args) => unref(onThDrop) && unref(onThDrop)(...args)),
1400
+ onDragover: _cache[2] || (_cache[2] = //@ts-ignore
1401
+ (...args) => unref(onThDragOver) && unref(onThDragOver)(...args))
1402
+ }, [createElementVNode("div", _hoisted_3, [col.customHeaderCell ? (openBlock(), createBlock(resolveDynamicComponent(col.customHeaderCell), {
1403
+ key: 0,
1404
+ col
1405
+ }, null, 8, ["col"])) : renderSlot(_ctx.$slots, "tableHeader", {
1406
+ key: 1,
1407
+ col
1408
+ }, () => [createElementVNode("span", _hoisted_4, toDisplayString(col.title), 1)]), col.sorter ? (openBlock(), createElementBlock("span", _hoisted_5, _hoisted_7)) : createCommentVNode("", true), _ctx.colResizable && colIndex > 0 ? (openBlock(), createElementBlock("div", {
1409
+ key: 3,
1410
+ class: "table-header-resizer left",
1411
+ onMousedown: (e) => unref(onThResizeMouseDown)(e, col, true)
1412
+ }, null, 40, _hoisted_8)) : createCommentVNode("", true), _ctx.colResizable ? (openBlock(), createElementBlock("div", {
1413
+ key: 4,
1414
+ class: "table-header-resizer right",
1415
+ onMousedown: (e) => unref(onThResizeMouseDown)(e, col)
1416
+ }, null, 40, _hoisted_9)) : createCommentVNode("", true)])], 46, _hoisted_2);
1417
+ }), 128)), unref(virtualX_on) ? (openBlock(), createElementBlock("th", {
1418
+ key: 1,
1419
+ class: "virtual-x-right",
1420
+ style: normalizeStyle({
1421
+ minWidth: unref(virtualX_offsetRight) + "px",
1422
+ width: unref(virtualX_offsetRight) + "px"
1423
+ })
1424
+ }, null, 4)) : createCommentVNode("", true)], 32);
1425
+ }), 128))])) : createCommentVNode("", true), createElementVNode("tbody", null, [unref(virtual_on) ? (openBlock(), createElementBlock("tr", {
1426
+ key: 0,
1427
+ style: normalizeStyle({
1428
+ height: `${unref(virtualScroll).offsetTop}px`
1429
+ }),
1430
+ class: "padding-top-tr"
1431
+ }, [unref(virtualX_on) && _ctx.fixedMode && _ctx.headless ? (openBlock(), createElementBlock("td", _hoisted_10)) : createCommentVNode("", true), _ctx.fixedMode && _ctx.headless ? (openBlock(true), createElementBlock(Fragment, {
1432
+ key: 1
1433
+ }, renderList(unref(virtualX_columnPart), (col) => {
1434
+ return openBlock(), createElementBlock("td", {
1435
+ key: col.dataIndex,
1436
+ style: normalizeStyle(getCellStyle(2, col))
1437
+ }, null, 4);
1438
+ }), 128)) : createCommentVNode("", true)], 4)) : createCommentVNode("", true), (openBlock(true), createElementBlock(Fragment, null, renderList(unref(virtual_dataSourcePart), (row, i) => {
1439
+ return openBlock(), createElementBlock("tr", {
1440
+ key: _ctx.rowKey ? rowKeyGen(row) : i,
1441
+ "data-row-key": _ctx.rowKey ? rowKeyGen(row) : i,
1442
+ class: normalizeClass({
1443
+ active: _ctx.rowKey ? rowKeyGen(row) === rowKeyGen(currentItem.value) : row === currentItem.value,
1444
+ hover: _ctx.rowKey ? rowKeyGen(row) === currentHover.value : row === currentHover.value,
1445
+ [_ctx.rowClassName(row, i)]: true
1446
+ }),
1447
+ style: normalizeStyle({
1448
+ backgroundColor: row._bgc
1449
+ }),
1450
+ onClick: (e) => onRowClick(e, row),
1451
+ onDblclick: (e) => onRowDblclick(e, row),
1452
+ onContextmenu: (e) => onRowMenu(e, row),
1453
+ onMouseover: (e) => onTrMouseOver(e, row)
1454
+ }, [unref(virtualX_on) ? (openBlock(), createElementBlock("td", _hoisted_12)) : createCommentVNode("", true), (openBlock(true), createElementBlock(Fragment, null, renderList(unref(virtualX_columnPart), (col) => {
1455
+ return openBlock(), createElementBlock("td", {
1456
+ key: col.dataIndex,
1457
+ "data-index": col.dataIndex,
1458
+ class: normalizeClass([col.className, _ctx.showOverflow ? "text-overflow" : "", unref(getFixedColClass)(col)]),
1459
+ style: normalizeStyle(getCellStyle(2, col)),
1460
+ onClick: (e) => onCellClick(e, row, col)
1461
+ }, [col.customCell ? (openBlock(), createBlock(resolveDynamicComponent(col.customCell), {
1462
+ key: 0,
1463
+ col,
1464
+ row,
1465
+ "cell-value": row[col.dataIndex]
1466
+ }, null, 8, ["col", "row", "cell-value"])) : (openBlock(), createElementBlock("div", {
1467
+ key: 1,
1468
+ class: "table-cell-wrapper",
1469
+ title: row[col.dataIndex]
1470
+ }, toDisplayString(row[col.dataIndex] ?? _ctx.emptyCellText), 9, _hoisted_14))], 14, _hoisted_13);
1471
+ }), 128))], 46, _hoisted_11);
1472
+ }), 128)), unref(virtual_on) ? (openBlock(), createElementBlock("tr", {
1473
+ key: 1,
1474
+ style: normalizeStyle({
1475
+ height: `${unref(virtual_offsetBottom)}px`
1476
+ })
1477
+ }, null, 4)) : createCommentVNode("", true)])], 6), (!dataSourceCopy.value || !dataSourceCopy.value.length) && _ctx.showNoData ? (openBlock(), createElementBlock("div", {
1478
+ key: 0,
1479
+ class: normalizeClass(["stk-table-no-data", {
1480
+ "no-data-full": _ctx.noDataFull
1481
+ }])
1482
+ }, [renderSlot(_ctx.$slots, "empty", {}, () => [createTextVNode("暂无数据")])], 2)) : createCommentVNode("", true)], 38);
1483
+ };
1484
+ }
1485
+ });
1486
+ export {
1487
+ _sfc_main as StkTable,
1488
+ insertToOrderedArray,
1489
+ tableSort
1490
+ };