stk-table-vue 0.2.0 → 0.2.1

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