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