stk-table-vue 0.6.16 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +211 -213
  2. package/lib/src/StkTable/StkTable.vue.d.ts +43 -24
  3. package/lib/src/StkTable/components/TriangleIcon.vue.d.ts +2 -0
  4. package/lib/src/StkTable/const.d.ts +0 -1
  5. package/lib/src/StkTable/types/highlightDimOptions.d.ts +1 -5
  6. package/lib/src/StkTable/types/index.d.ts +26 -6
  7. package/lib/src/StkTable/useHighlight.d.ts +1 -1
  8. package/lib/src/StkTable/useRowExpand.d.ts +17 -0
  9. package/lib/src/StkTable/useTree.d.ts +20 -0
  10. package/lib/stk-table-vue.js +321 -170
  11. package/lib/style.css +29 -20
  12. package/package.json +75 -75
  13. package/src/StkTable/StkTable.vue +1557 -1550
  14. package/src/StkTable/components/DragHandle.vue +9 -9
  15. package/src/StkTable/components/SortIcon.vue +6 -6
  16. package/src/StkTable/components/TriangleIcon.vue +3 -0
  17. package/src/StkTable/const.ts +37 -37
  18. package/src/StkTable/index.ts +4 -4
  19. package/src/StkTable/style.less +567 -553
  20. package/src/StkTable/types/highlightDimOptions.ts +26 -26
  21. package/src/StkTable/types/index.ts +260 -239
  22. package/src/StkTable/useAutoResize.ts +91 -91
  23. package/src/StkTable/useColResize.ts +216 -216
  24. package/src/StkTable/useFixedCol.ts +148 -148
  25. package/src/StkTable/useFixedStyle.ts +75 -75
  26. package/src/StkTable/useGetFixedColPosition.ts +65 -65
  27. package/src/StkTable/useHighlight.ts +320 -318
  28. package/src/StkTable/useKeyboardArrowScroll.ts +112 -112
  29. package/src/StkTable/useRowExpand.ts +78 -0
  30. package/src/StkTable/useThDrag.ts +102 -102
  31. package/src/StkTable/useTrDrag.ts +118 -118
  32. package/src/StkTable/useTree.ts +158 -0
  33. package/src/StkTable/useVirtualScroll.ts +462 -462
  34. package/src/StkTable/utils/constRefUtils.ts +29 -29
  35. package/src/StkTable/utils/index.ts +213 -212
  36. package/src/StkTable/utils/useTriggerRef.ts +33 -33
  37. package/src/VirtualTree.vue +622 -622
  38. package/src/VirtualTreeSelect.vue +367 -367
  39. package/src/vite-env.d.ts +10 -10
@@ -1,5 +1,4 @@
1
- import { createElementBlock, openBlock, createElementVNode, watch, onMounted, onBeforeUnmount, ref, computed, shallowRef, defineComponent, nextTick, toRaw, normalizeStyle, normalizeClass, unref, createCommentVNode, renderSlot, Fragment, renderList, createBlock, resolveDynamicComponent, toDisplayString, createTextVNode, createVNode } from "vue";
2
- import { interpolateRgb } from "d3-interpolate";
1
+ import { createElementBlock, openBlock, createElementVNode, watch, onMounted, onBeforeUnmount, ref, computed, shallowRef, defineComponent, nextTick, toRaw, normalizeStyle, normalizeClass, unref, createCommentVNode, renderSlot, Fragment, renderList, createBlock, resolveDynamicComponent, toDisplayString, createTextVNode, withCtx, createVNode } from "vue";
3
2
  const _export_sfc = (sfc, props) => {
4
3
  const target = sfc.__vccOpts || sfc;
5
4
  for (const [key, val] of props) {
@@ -7,13 +6,13 @@ const _export_sfc = (sfc, props) => {
7
6
  }
8
7
  return target;
9
8
  };
10
- const _sfc_main$2 = {};
11
- const _hoisted_1$2 = {
9
+ const _sfc_main$3 = {};
10
+ const _hoisted_1$3 = {
12
11
  class: "drag-row-handle",
13
12
  draggable: "true"
14
13
  };
15
- function _sfc_render$1(_ctx, _cache) {
16
- return openBlock(), createElementBlock("span", _hoisted_1$2, _cache[0] || (_cache[0] = [
14
+ function _sfc_render$2(_ctx, _cache) {
15
+ return openBlock(), createElementBlock("span", _hoisted_1$3, _cache[0] || (_cache[0] = [
17
16
  createElementVNode("svg", {
18
17
  viewBox: "0 0 1024 1024",
19
18
  width: "16",
@@ -24,16 +23,16 @@ function _sfc_render$1(_ctx, _cache) {
24
23
  ], -1)
25
24
  ]));
26
25
  }
27
- const DragHandle = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["render", _sfc_render$1]]);
28
- const _sfc_main$1 = {};
29
- const _hoisted_1$1 = {
26
+ const DragHandle = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["render", _sfc_render$2]]);
27
+ const _sfc_main$2 = {};
28
+ const _hoisted_1$2 = {
30
29
  xmlns: "http://www.w3.org/2000/svg",
31
30
  width: "16px",
32
31
  height: "16px",
33
32
  viewBox: "0 0 16 16"
34
33
  };
35
- function _sfc_render(_ctx, _cache) {
36
- return openBlock(), createElementBlock("svg", _hoisted_1$1, _cache[0] || (_cache[0] = [
34
+ function _sfc_render$1(_ctx, _cache) {
35
+ return openBlock(), createElementBlock("svg", _hoisted_1$2, _cache[0] || (_cache[0] = [
37
36
  createElementVNode("polygon", {
38
37
  class: "arrow-up",
39
38
  fill: "#757699",
@@ -46,7 +45,13 @@ function _sfc_render(_ctx, _cache) {
46
45
  }, null, -1)
47
46
  ]));
48
47
  }
49
- const SortIcon = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["render", _sfc_render]]);
48
+ const SortIcon = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["render", _sfc_render$1]]);
49
+ const _sfc_main$1 = {};
50
+ const _hoisted_1$1 = { class: "stk-fold-icon" };
51
+ function _sfc_render(_ctx, _cache) {
52
+ return openBlock(), createElementBlock("div", _hoisted_1$1);
53
+ }
54
+ const TriangleIcon = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["render", _sfc_render]]);
50
55
  function isEmptyValue(val, isNumber) {
51
56
  let isEmpty = val === null || val === void 0;
52
57
  if (isNumber) {
@@ -55,26 +60,28 @@ function isEmptyValue(val, isNumber) {
55
60
  return isEmpty;
56
61
  }
57
62
  function insertToOrderedArray(sortState, newItem, targetArray, sortConfig = {}) {
58
- const { dataIndex, order } = sortState;
63
+ const { dataIndex, sortField, order } = sortState;
59
64
  sortConfig = { emptyToBottom: false, ...sortConfig };
60
65
  let { sortType } = sortState;
61
- if (!sortType) sortType = typeof newItem[dataIndex];
66
+ const field = sortField || dataIndex;
67
+ if (!sortType) sortType = typeof newItem[field];
62
68
  const data = targetArray.slice();
63
69
  if (!order || !data.length) {
64
70
  data.unshift(newItem);
65
71
  return data;
66
72
  }
67
- if (sortConfig.emptyToBottom && isEmptyValue(newItem)) {
73
+ const targetVal = newItem[field];
74
+ if (sortConfig.emptyToBottom && isEmptyValue(targetVal)) {
68
75
  data.push(newItem);
76
+ } else {
77
+ const isNumber = sortType === "number";
78
+ const sIndex = binarySearch(data, (midIndex) => {
79
+ const midVal = data[midIndex][field];
80
+ const compareRes = strCompare(midVal, targetVal, isNumber, sortConfig.stringLocaleCompare);
81
+ return order === "asc" ? compareRes : -compareRes;
82
+ });
83
+ data.splice(sIndex, 0, newItem);
69
84
  }
70
- const isNumber = sortType === "number";
71
- const targetVal = newItem[dataIndex];
72
- const sIndex = binarySearch(data, (midIndex) => {
73
- const midVal = data[midIndex][dataIndex];
74
- const compareRes = strCompare(midVal, targetVal, isNumber, sortConfig.stringLocaleCompare);
75
- return order === "asc" ? compareRes : -compareRes;
76
- });
77
- data.splice(sIndex, 0, newItem);
78
85
  return data;
79
86
  }
80
87
  function binarySearch(searchArray, compareCallback) {
@@ -188,7 +195,6 @@ const HIGHLIGHT_COLOR = {
188
195
  dark: { from: "#1e4c99", to: "#181c21" }
189
196
  };
190
197
  const HIGHLIGHT_DURATION = 2e3;
191
- const HIGHLIGHT_FREQ = 1e3 / 30;
192
198
  const HIGHLIGHT_ROW_CLASS = "highlight-row";
193
199
  const HIGHLIGHT_CELL_CLASS = "highlight-cell";
194
200
  const _chromeVersion = getBrowsersVersion("chrome");
@@ -609,25 +615,21 @@ function useHighlight({ props, stkTableId, tableContainerRef }) {
609
615
  light: HIGHLIGHT_COLOR.light,
610
616
  dark: HIGHLIGHT_COLOR.dark
611
617
  };
612
- const highlightDuration = config.duration ? config.duration * 1e3 : HIGHLIGHT_DURATION;
613
- const highlightFrequency = config.fps && config.fps > 0 ? 1e3 / config.fps : null;
614
- const highlightSteps = highlightFrequency ? Math.round(highlightDuration / highlightFrequency) : null;
618
+ const highlightDuration = computed(() => config.duration ? config.duration * 1e3 : HIGHLIGHT_DURATION);
619
+ const highlightFrequency = computed(() => config.fps && config.fps > 0 ? 1e3 / config.fps : null);
620
+ const highlightSteps = computed(() => highlightFrequency.value ? Math.round(highlightDuration.value / highlightFrequency.value) : null);
615
621
  const highlightFrom = computed(() => highlightColor[props.theme].from);
616
- const highlightTo = computed(() => highlightColor[props.theme].to);
617
- const highlightInter = computed(() => interpolateRgb(highlightFrom.value, highlightTo.value));
618
- const highlightDimRowsJs = /* @__PURE__ */ new Map();
619
- let calcHighlightDimLoopJs = false;
620
622
  const highlightDimRowsAnimation = /* @__PURE__ */ new Map();
621
623
  let calcHighlightDimLoopAnimation = false;
622
624
  const highlightDimRowsTimeout = /* @__PURE__ */ new Map();
623
625
  const highlightDimCellsTimeout = /* @__PURE__ */ new Map();
624
- const defaultHighlightDimOption = (() => {
626
+ const defaultHighlightDimOption = computed(() => {
625
627
  const keyframe = { backgroundColor: [highlightFrom.value, ""] };
626
- if (highlightSteps) {
627
- keyframe.easing = `steps(${highlightSteps})`;
628
+ if (highlightSteps.value) {
629
+ keyframe.easing = `steps(${highlightSteps.value})`;
628
630
  }
629
- return { duration: highlightDuration, keyframe };
630
- })();
631
+ return { duration: highlightDuration.value, keyframe };
632
+ });
631
633
  function calcRowHighlightLoop() {
632
634
  if (calcHighlightDimLoopAnimation) return;
633
635
  calcHighlightDimLoopAnimation = true;
@@ -655,39 +657,13 @@ function useHighlight({ props, stkTableId, tableContainerRef }) {
655
657
  };
656
658
  recursion();
657
659
  }
658
- function calcRowHighlightLoopJs() {
659
- if (calcHighlightDimLoopJs) return;
660
- calcHighlightDimLoopJs = true;
661
- const recursion = () => {
662
- window.setTimeout(() => {
663
- const nowTs = Date.now();
664
- highlightDimRowsJs.forEach((highlightStart, rowKeyValue) => {
665
- const progress = (nowTs - highlightStart) / highlightDuration;
666
- let bgc = "";
667
- if (0 <= progress && progress <= 1) {
668
- bgc = highlightInter.value(progress);
669
- } else {
670
- highlightDimRowsJs.delete(rowKeyValue);
671
- }
672
- updateRowBgcJs(rowKeyValue, bgc);
673
- });
674
- if (highlightDimRowsJs.size > 0) {
675
- recursion();
676
- } else {
677
- calcHighlightDimLoopJs = false;
678
- highlightDimRowsJs.clear();
679
- }
680
- }, highlightFrequency || HIGHLIGHT_FREQ);
681
- };
682
- recursion();
683
- }
684
660
  function setHighlightDimCell(rowKeyValue, colKeyValue, option = {}) {
685
661
  var _a;
686
662
  const cellEl = (_a = tableContainerRef.value) == null ? void 0 : _a.querySelector(`[data-cell-key="${rowKeyValue}--${colKeyValue}"]`);
687
663
  const { className, method, duration, keyframe } = {
688
664
  className: HIGHLIGHT_CELL_CLASS,
689
665
  method: "animation",
690
- ...defaultHighlightDimOption,
666
+ ...defaultHighlightDimOption.value,
691
667
  ...option
692
668
  };
693
669
  if (!cellEl) return;
@@ -702,7 +678,7 @@ function useHighlight({ props, stkTableId, tableContainerRef }) {
702
678
  const { className, method, keyframe, duration } = {
703
679
  className: HIGHLIGHT_ROW_CLASS,
704
680
  method: "animation",
705
- ...defaultHighlightDimOption,
681
+ ...defaultHighlightDimOption.value,
706
682
  ...option
707
683
  };
708
684
  if (method === "css") {
@@ -724,14 +700,6 @@ function useHighlight({ props, stkTableId, tableContainerRef }) {
724
700
  rowEl.animate(keyframe, duration);
725
701
  }
726
702
  }
727
- } else if (method === "js") {
728
- const nowTs = Date.now();
729
- for (let i = 0; i < rowKeyValues.length; i++) {
730
- const rowKeyValue = rowKeyValues[i];
731
- highlightDimRowsJs.set(rowKeyValue, nowTs);
732
- updateRowBgcJs(rowKeyValue, highlightFrom.value);
733
- }
734
- calcRowHighlightLoopJs();
735
703
  }
736
704
  }
737
705
  function highlightRowsInCssKeyframe(rowKeyValues, className, duration) {
@@ -797,11 +765,6 @@ function useHighlight({ props, stkTableId, tableContainerRef }) {
797
765
  });
798
766
  }
799
767
  }
800
- function updateRowBgcJs(rowKeyValue, color) {
801
- const rowEl = document.getElementById(stkTableId + "-" + String(rowKeyValue));
802
- if (!rowEl) return;
803
- rowEl.style.backgroundColor = color;
804
- }
805
768
  return {
806
769
  highlightSteps,
807
770
  setHighlightDimRow,
@@ -883,6 +846,57 @@ function useKeyboardArrowScroll(targetElement, { props, scrollTo, virtualScroll,
883
846
  if (!isMouseOver) isMouseOver = true;
884
847
  }
885
848
  }
849
+ function useRowExpand({ dataSourceCopy, rowKeyGen, emits }) {
850
+ function toggleExpandRow(row, col) {
851
+ const isExpand = (row == null ? void 0 : row.__EXPANDED__) === col ? !(row == null ? void 0 : row.__EXPANDED__) : true;
852
+ setRowExpand(row, isExpand, { col });
853
+ }
854
+ function setRowExpand(rowKeyOrRow, expand, data) {
855
+ let rowKey;
856
+ if (typeof rowKeyOrRow === "string") {
857
+ rowKey = rowKeyOrRow;
858
+ } else {
859
+ rowKey = rowKeyGen(rowKeyOrRow);
860
+ }
861
+ const tempData = dataSourceCopy.value.slice();
862
+ const index = tempData.findIndex((it) => rowKeyGen(it) === rowKey);
863
+ if (index === -1) {
864
+ console.warn("expandRow failed.rowKey:", rowKey);
865
+ return;
866
+ }
867
+ for (let i = index + 1; i < tempData.length; i++) {
868
+ const item = tempData[i];
869
+ const rowKey2 = item.__ROW_KEY__;
870
+ if (rowKey2 == null ? void 0 : rowKey2.startsWith(EXPANDED_ROW_KEY_PREFIX)) {
871
+ tempData.splice(i, 1);
872
+ i--;
873
+ } else {
874
+ break;
875
+ }
876
+ }
877
+ const row = tempData[index];
878
+ const col = (data == null ? void 0 : data.col) || null;
879
+ if (expand) {
880
+ const newExpandRow = {
881
+ __ROW_KEY__: EXPANDED_ROW_KEY_PREFIX + rowKey,
882
+ __EXPANDED_ROW__: row,
883
+ __EXPANDED_COL__: col
884
+ };
885
+ tempData.splice(index + 1, 0, newExpandRow);
886
+ }
887
+ if (row) {
888
+ row.__EXPANDED__ = expand ? col : null;
889
+ }
890
+ dataSourceCopy.value = tempData;
891
+ if (!(data == null ? void 0 : data.silent)) {
892
+ emits("toggle-row-expand", { expanded: Boolean(expand), row, col });
893
+ }
894
+ }
895
+ return {
896
+ toggleExpandRow,
897
+ setRowExpand
898
+ };
899
+ }
886
900
  function useThDrag({ props, emits, colKeyGen }) {
887
901
  const findParentTH = (e) => e.target.closest("th");
888
902
  const dragConfig = computed(() => {
@@ -1363,6 +1377,125 @@ function useVirtualScroll({
1363
1377
  clearAllAutoHeight
1364
1378
  };
1365
1379
  }
1380
+ function useTree({ props, dataSourceCopy, rowKeyGen, emits }) {
1381
+ const { defaultExpandAll, defaultExpandKeys, defaultExpandLevel } = props.treeConfig;
1382
+ function toggleTreeNode(row, col) {
1383
+ const expand = row ? !row.__T_EXPANDED__ : false;
1384
+ privateSetTreeExpand(row, { expand, col, isClick: true });
1385
+ }
1386
+ function privateSetTreeExpand(row, option) {
1387
+ const rowKeyOrRowArr = Array.isArray(row) ? row : [row];
1388
+ const tempData = dataSourceCopy.value.slice();
1389
+ for (let i = 0; i < rowKeyOrRowArr.length; i++) {
1390
+ const rowKeyOrRow = rowKeyOrRowArr[i];
1391
+ let rowKey;
1392
+ if (typeof rowKeyOrRow === "string") {
1393
+ rowKey = rowKeyOrRow;
1394
+ } else {
1395
+ rowKey = rowKeyGen(rowKeyOrRow);
1396
+ }
1397
+ const index = tempData.findIndex((it) => rowKeyGen(it) === rowKey);
1398
+ if (index === -1) {
1399
+ console.warn("treeExpandRow failed.rowKey:", rowKey);
1400
+ return;
1401
+ }
1402
+ const row2 = tempData[index];
1403
+ const level = row2.__T_LV__ || 0;
1404
+ let expanded = option == null ? void 0 : option.expand;
1405
+ if (expanded === void 0) {
1406
+ expanded = !row2.__T_EXPANDED__;
1407
+ }
1408
+ if (expanded) {
1409
+ const children = expandNode(row2, level);
1410
+ tempData.splice(index + 1, 0, ...children);
1411
+ } else {
1412
+ const deleteCount = foldNode(index, tempData, level);
1413
+ tempData.splice(index + 1, deleteCount);
1414
+ }
1415
+ setNodeExpanded(row2, expanded, level);
1416
+ if (option.isClick) {
1417
+ emits("toggle-tree-expand", { expanded: Boolean(expanded), row: row2, col: option.col });
1418
+ }
1419
+ }
1420
+ dataSourceCopy.value = tempData;
1421
+ }
1422
+ function setTreeExpand(row, option) {
1423
+ privateSetTreeExpand(row, { ...option, isClick: false });
1424
+ }
1425
+ function setNodeExpanded(row, expanded, level, parent) {
1426
+ row.__T_EXPANDED__ = expanded;
1427
+ if (level !== void 0) {
1428
+ row.__T_LV__ = level;
1429
+ }
1430
+ if (parent) {
1431
+ row.__T_PARENT_K__ = rowKeyGen(parent);
1432
+ }
1433
+ }
1434
+ function flatTreeData(data) {
1435
+ const result = [];
1436
+ (function recursion(data2, level, parent) {
1437
+ if (!data2) return;
1438
+ for (let i = 0; i < data2.length; i++) {
1439
+ const item = data2[i];
1440
+ result.push(item);
1441
+ const isExpanded = Boolean(item.__T_EXPANDED__);
1442
+ setNodeExpanded(item, isExpanded, level, parent);
1443
+ if (!isExpanded) {
1444
+ if (defaultExpandAll) {
1445
+ setNodeExpanded(item, true);
1446
+ } else {
1447
+ if (defaultExpandLevel) {
1448
+ if (level < defaultExpandLevel) {
1449
+ setNodeExpanded(item, true);
1450
+ }
1451
+ }
1452
+ if (defaultExpandKeys) {
1453
+ if (defaultExpandKeys.includes(rowKeyGen(item))) {
1454
+ setNodeExpanded(item, true);
1455
+ }
1456
+ }
1457
+ if (!item.__T_EXPANDED__) {
1458
+ continue;
1459
+ }
1460
+ }
1461
+ }
1462
+ recursion(item.children, level + 1, item);
1463
+ }
1464
+ })(data, 0);
1465
+ return result;
1466
+ }
1467
+ function expandNode(row, level) {
1468
+ let result = [];
1469
+ row.children && row.children.forEach((child) => {
1470
+ result.push(child);
1471
+ const childLv = level + 1;
1472
+ if (child.__T_EXPANDED__ && child.children) {
1473
+ const res = expandNode(child, childLv);
1474
+ result = result.concat(res);
1475
+ } else {
1476
+ setNodeExpanded(child, false, childLv, row);
1477
+ }
1478
+ });
1479
+ return result;
1480
+ }
1481
+ function foldNode(index, tempData, level) {
1482
+ let deleteCount = 0;
1483
+ for (let i = index + 1; i < tempData.length; i++) {
1484
+ const child = tempData[i];
1485
+ if (child.__T_LV__ && child.__T_LV__ > level) {
1486
+ deleteCount++;
1487
+ } else {
1488
+ break;
1489
+ }
1490
+ }
1491
+ return deleteCount;
1492
+ }
1493
+ return {
1494
+ toggleTreeNode,
1495
+ setTreeExpand,
1496
+ flatTreeData
1497
+ };
1498
+ }
1366
1499
  const _hoisted_1 = ["data-col-key", "draggable", "rowspan", "colspan", "title", "onClick"];
1367
1500
  const _hoisted_2 = ["onMousedown"];
1368
1501
  const _hoisted_3 = { class: "table-header-title" };
@@ -1380,7 +1513,7 @@ const _hoisted_8 = ["colspan"];
1380
1513
  const _hoisted_9 = { class: "table-cell-wrapper" };
1381
1514
  const _hoisted_10 = ["data-cell-key", "onClick", "onMousedown", "onMouseenter", "onMouseleave", "onMouseover"];
1382
1515
  const _hoisted_11 = ["title"];
1383
- const _hoisted_12 = { key: 1 };
1516
+ const _hoisted_12 = ["title"];
1384
1517
  const _sfc_main = /* @__PURE__ */ defineComponent({
1385
1518
  __name: "StkTable",
1386
1519
  props: {
@@ -1402,7 +1535,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1402
1535
  columns: { default: () => [] },
1403
1536
  dataSource: { default: () => [] },
1404
1537
  rowKey: { type: [String, Number, Function], default: "" },
1405
- colKey: { type: [String, Number, Function], default: "dataIndex" },
1538
+ colKey: {},
1406
1539
  emptyCellText: { type: [String, Function], default: "--" },
1407
1540
  noDataFull: { type: Boolean, default: false },
1408
1541
  showNoData: { type: Boolean, default: true },
@@ -1413,7 +1546,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1413
1546
  cellHover: { type: Boolean, default: false },
1414
1547
  cellActive: { type: Boolean, default: false },
1415
1548
  selectedCellRevokable: { type: Boolean, default: true },
1416
- headerDrag: { default: false },
1549
+ headerDrag: { type: Boolean, default: false },
1417
1550
  rowClassName: { type: Function, default: () => "" },
1418
1551
  colResizable: { type: Boolean, default: false },
1419
1552
  colMinWidth: { default: 10 },
@@ -1430,11 +1563,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1430
1563
  seqConfig: { default: () => ({}) },
1431
1564
  expandConfig: { default: () => ({}) },
1432
1565
  dragRowConfig: { default: () => ({}) },
1566
+ treeConfig: { default: () => ({}) },
1433
1567
  cellFixedMode: { default: "sticky" },
1434
1568
  smoothScroll: { type: Boolean, default: DEFAULT_SMOOTH_SCROLL },
1435
1569
  scrollRowByRow: { type: Boolean, default: false }
1436
1570
  },
1437
- emits: ["sort-change", "row-click", "current-change", "cell-selected", "row-dblclick", "header-row-menu", "row-menu", "cell-click", "cell-mouseenter", "cell-mouseleave", "cell-mouseover", "cell-mousedown", "header-cell-click", "scroll", "scroll-x", "col-order-change", "th-drag-start", "th-drop", "row-order-change", "col-resize", "toggle-row-expand", "update:columns"],
1571
+ emits: ["sort-change", "row-click", "current-change", "cell-selected", "row-dblclick", "header-row-menu", "row-menu", "cell-click", "cell-mouseenter", "cell-mouseleave", "cell-mouseover", "cell-mousedown", "header-cell-click", "scroll", "scroll-x", "col-order-change", "th-drag-start", "th-drop", "row-order-change", "col-resize", "toggle-row-expand", "toggle-tree-expand", "update:columns"],
1438
1572
  setup(__props, { expose: __expose, emit: __emit }) {
1439
1573
  const stkTableId = createStkTableId();
1440
1574
  const props = __props;
@@ -1455,7 +1589,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1455
1589
  const tableHeaders = shallowRef([]);
1456
1590
  const tableHeadersForCalc = shallowRef([]);
1457
1591
  const tableHeaderLast = computed(() => tableHeadersForCalc.value.slice(-1)[0] || []);
1458
- const dataSourceCopy = shallowRef(props.dataSource.slice());
1592
+ const isTreeData = computed(() => {
1593
+ return props.columns.some((col) => col.type === "tree-node");
1594
+ });
1595
+ const dataSourceCopy = shallowRef([]);
1459
1596
  const rowKeyGenComputed = computed(() => {
1460
1597
  const { rowKey } = props;
1461
1598
  if (typeof rowKey === "function") {
@@ -1466,7 +1603,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1466
1603
  });
1467
1604
  const colKeyGen = computed(() => {
1468
1605
  const { colKey } = props;
1469
- if (typeof colKey === "function") {
1606
+ if (colKey === void 0) {
1607
+ return (col) => col.key || col.dataIndex;
1608
+ } else if (typeof colKey === "function") {
1470
1609
  return (col) => colKey(col);
1471
1610
  } else {
1472
1611
  return (col) => col[colKey];
@@ -1480,7 +1619,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1480
1619
  return (col, row) => emptyCellText({ row, col });
1481
1620
  }
1482
1621
  });
1483
- const rowKeyGenStore = /* @__PURE__ */ new WeakMap();
1622
+ const rowKeyGenCache = /* @__PURE__ */ new WeakMap();
1484
1623
  const { onThDragStart, onThDragOver, onThDrop, isHeaderDraggable } = useThDrag({ props, emits, colKeyGen });
1485
1624
  const { onTrDragStart, onTrDrop, onTrDragOver, onTrDragEnd, onTrDragEnter } = useTrDrag({ props, emits, dataSourceCopy });
1486
1625
  const {
@@ -1539,6 +1678,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1539
1678
  tableHeaderLast,
1540
1679
  fixedCols
1541
1680
  });
1681
+ const { toggleExpandRow, setRowExpand } = useRowExpand({ dataSourceCopy, rowKeyGen, emits });
1682
+ const { toggleTreeNode, setTreeExpand, flatTreeData } = useTree({ props, dataSourceCopy, rowKeyGen, emits });
1542
1683
  watch(
1543
1684
  () => props.columns,
1544
1685
  () => {
@@ -1557,6 +1698,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1557
1698
  });
1558
1699
  }
1559
1700
  );
1701
+ watch(
1702
+ () => props.rowHeight,
1703
+ () => {
1704
+ initVirtualScrollY();
1705
+ }
1706
+ );
1560
1707
  watch(
1561
1708
  () => props.virtualX,
1562
1709
  () => {
@@ -1570,7 +1717,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1570
1717
  watch(
1571
1718
  () => props.dataSource,
1572
1719
  (val) => {
1573
- if (!val) {
1720
+ if (!Array.isArray(val)) {
1574
1721
  console.warn("invalid dataSource");
1575
1722
  return;
1576
1723
  }
@@ -1578,7 +1725,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1578
1725
  if (dataSourceCopy.value.length !== val.length) {
1579
1726
  needInitVirtualScrollY = true;
1580
1727
  }
1581
- dataSourceCopy.value = val.slice();
1728
+ initDataSource(val);
1582
1729
  if (needInitVirtualScrollY) {
1583
1730
  nextTick(() => initVirtualScrollY());
1584
1731
  }
@@ -1595,11 +1742,19 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1595
1742
  () => updateFixedShadow()
1596
1743
  );
1597
1744
  dealColumns();
1745
+ initDataSource();
1598
1746
  onMounted(() => {
1599
1747
  initVirtualScroll();
1600
1748
  updateFixedShadow();
1601
1749
  dealDefaultSorter();
1602
1750
  });
1751
+ function initDataSource(v = props.dataSource) {
1752
+ let dataSourceTemp = v.slice();
1753
+ if (isTreeData.value) {
1754
+ dataSourceTemp = flatTreeData(dataSourceTemp);
1755
+ }
1756
+ dataSourceCopy.value = dataSourceTemp;
1757
+ }
1603
1758
  function dealDefaultSorter() {
1604
1759
  if (!props.sortConfig.defaultSort) return;
1605
1760
  const { key, dataIndex, order, silent } = { silent: false, ...props.sortConfig.defaultSort };
@@ -1676,13 +1831,13 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1676
1831
  }
1677
1832
  function rowKeyGen(row) {
1678
1833
  if (!row) return row;
1679
- let key = rowKeyGenStore.get(row) || row.__ROW_KEY__;
1834
+ let key = rowKeyGenCache.get(row) || row.__ROW_KEY__;
1680
1835
  if (!key) {
1681
1836
  key = rowKeyGenComputed.value(row);
1682
1837
  if (key === void 0) {
1683
1838
  key = Math.random().toString();
1684
1839
  }
1685
- rowKeyGenStore.set(row, key);
1840
+ rowKeyGenCache.set(row, key);
1686
1841
  }
1687
1842
  return key;
1688
1843
  }
@@ -1803,10 +1958,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1803
1958
  function onRowMenu(e, row, rowIndex) {
1804
1959
  emits("row-menu", e, row, { rowIndex });
1805
1960
  }
1806
- function onCellClick(e, row, col, rowIndex) {
1961
+ function triangleClick(e, row, col) {
1807
1962
  if (col.type === "expand") {
1808
1963
  toggleExpandRow(row, col);
1964
+ } else if (col.type === "tree-node") {
1965
+ toggleTreeNode(row, col);
1809
1966
  }
1967
+ }
1968
+ function onCellClick(e, row, col, rowIndex) {
1810
1969
  if (props.cellActive) {
1811
1970
  const cellKey = cellKeyGen(row, col);
1812
1971
  const result = { row, col, select: false, rowIndex };
@@ -1965,51 +2124,6 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1965
2124
  if (!sortOrder) return [];
1966
2125
  return [{ key: sortCol.value, order: sortOrder }];
1967
2126
  }
1968
- function toggleExpandRow(row, col) {
1969
- const isExpand = (row == null ? void 0 : row.__EXPANDED__) === col ? !(row == null ? void 0 : row.__EXPANDED__) : true;
1970
- setRowExpand(row, isExpand, { col });
1971
- }
1972
- function setRowExpand(rowKeyOrRow, expand, data) {
1973
- let rowKey;
1974
- if (typeof rowKeyOrRow === "string") {
1975
- rowKey = rowKeyOrRow;
1976
- } else {
1977
- rowKey = rowKeyGen(rowKeyOrRow);
1978
- }
1979
- const tempData = dataSourceCopy.value.slice();
1980
- const index = tempData.findIndex((it) => rowKeyGen(it) === rowKey);
1981
- if (index === -1) {
1982
- console.warn("expandRow failed.rowKey:", rowKey);
1983
- return;
1984
- }
1985
- for (let i = index + 1; i < tempData.length; i++) {
1986
- const item = tempData[i];
1987
- const rowKey2 = item.__ROW_KEY__;
1988
- if (rowKey2 == null ? void 0 : rowKey2.startsWith(EXPANDED_ROW_KEY_PREFIX)) {
1989
- tempData.splice(i, 1);
1990
- i--;
1991
- } else {
1992
- break;
1993
- }
1994
- }
1995
- const row = tempData[index];
1996
- const col = (data == null ? void 0 : data.col) || null;
1997
- if (expand) {
1998
- const newExpandRow = {
1999
- __ROW_KEY__: EXPANDED_ROW_KEY_PREFIX + rowKey,
2000
- __EXPANDED_ROW__: row,
2001
- __EXPANDED_COL__: col
2002
- };
2003
- tempData.splice(index + 1, 0, newExpandRow);
2004
- }
2005
- if (row) {
2006
- row.__EXPANDED__ = expand ? col : null;
2007
- }
2008
- dataSourceCopy.value = tempData;
2009
- if (!(data == null ? void 0 : data.silent)) {
2010
- emits("toggle-row-expand", { expanded: Boolean(expand), row, col });
2011
- }
2012
- }
2013
2127
  __expose({
2014
2128
  /**
2015
2129
  * 重新计算虚拟列表宽高
@@ -2121,7 +2235,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
2121
2235
  * en: Clear all row heights
2122
2236
  * @see {@link clearAllAutoHeight}
2123
2237
  */
2124
- clearAllAutoHeight
2238
+ clearAllAutoHeight,
2239
+ /**
2240
+ * 设置树节点展开状态
2241
+ *
2242
+ * en: Set tree node expand state
2243
+ * @see {@link setTreeExpand}
2244
+ */
2245
+ setTreeExpand
2125
2246
  });
2126
2247
  return (_ctx, _cache) => {
2127
2248
  return openBlock(), createElementBlock("div", {
@@ -2185,7 +2306,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
2185
2306
  (openBlock(true), createElementBlock(Fragment, null, renderList(tableHeaders.value, (row, rowIndex) => {
2186
2307
  return openBlock(), createElementBlock("tr", {
2187
2308
  key: rowIndex,
2188
- onContextmenu: _cache[3] || (_cache[3] = (e) => onHeaderMenu(e))
2309
+ onContextmenu: _cache[3] || (_cache[3] = ($event) => onHeaderMenu($event))
2189
2310
  }, [
2190
2311
  unref(virtualX_on) ? (openBlock(), createElementBlock("th", {
2191
2312
  key: 0,
@@ -2221,7 +2342,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
2221
2342
  unref(colResizeOn)(col) && colIndex > 0 ? (openBlock(), createElementBlock("div", {
2222
2343
  key: 0,
2223
2344
  class: "table-header-resizer left",
2224
- onMousedown: (e) => unref(onThResizeMouseDown)(e, col, true)
2345
+ onMousedown: ($event) => unref(onThResizeMouseDown)($event, col, true)
2225
2346
  }, null, 40, _hoisted_2)) : createCommentVNode("", true),
2226
2347
  createElementVNode("div", {
2227
2348
  class: "table-header-cell-wrapper",
@@ -2246,7 +2367,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
2246
2367
  unref(colResizeOn)(col) ? (openBlock(), createElementBlock("div", {
2247
2368
  key: 1,
2248
2369
  class: "table-header-resizer right",
2249
- onMousedown: (e) => unref(onThResizeMouseDown)(e, col)
2370
+ onMousedown: ($event) => unref(onThResizeMouseDown)($event, col)
2250
2371
  }, null, 40, _hoisted_4)) : createCommentVNode("", true)
2251
2372
  ], 46, _hoisted_1);
2252
2373
  }), 128)),
@@ -2299,11 +2420,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
2299
2420
  style: normalizeStyle({
2300
2421
  "--row-height": row && row.__EXPANDED_ROW__ && props.virtual && ((_a = props.expandConfig) == null ? void 0 : _a.height) && ((_b = props.expandConfig) == null ? void 0 : _b.height) + "px"
2301
2422
  }),
2302
- onClick: (e) => onRowClick(e, row, getRowIndex(rowIndex)),
2303
- onDblclick: (e) => onRowDblclick(e, row, getRowIndex(rowIndex)),
2304
- onContextmenu: (e) => onRowMenu(e, row, getRowIndex(rowIndex)),
2305
- onMouseover: (e) => onTrMouseOver(e, row),
2306
- onDrop: (e) => unref(onTrDrop)(e, getRowIndex(rowIndex))
2423
+ onClick: ($event) => onRowClick($event, row, getRowIndex(rowIndex)),
2424
+ onDblclick: ($event) => onRowDblclick($event, row, getRowIndex(rowIndex)),
2425
+ onContextmenu: ($event) => onRowMenu($event, row, getRowIndex(rowIndex)),
2426
+ onMouseover: ($event) => onTrMouseOver($event, row),
2427
+ onDrop: ($event) => unref(onTrDrop)($event, getRowIndex(rowIndex))
2307
2428
  }, [
2308
2429
  unref(virtualX_on) ? (openBlock(), createElementBlock("td", _hoisted_7)) : createCommentVNode("", true),
2309
2430
  row && row.__EXPANDED_ROW__ ? (openBlock(), createElementBlock("td", {
@@ -2332,42 +2453,72 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
2332
2453
  {
2333
2454
  "seq-column": col.type === "seq",
2334
2455
  active: currentSelectedCellKey.value === cellKeyGen(row, col),
2335
- "expand-cell": col.type === "expand",
2336
2456
  expanded: col.type === "expand" && (row.__EXPANDED__ ? colKeyGen.value(row.__EXPANDED__) === colKeyGen.value(col) : false),
2457
+ "tree-expanded": col.type === "tree-node" && row.__T_EXPANDED__,
2337
2458
  "drag-row-cell": col.type === "dragRow"
2338
2459
  }
2339
2460
  ]),
2340
- onClick: (e) => onCellClick(e, row, col, getRowIndex(rowIndex)),
2341
- onMousedown: (e) => onCellMouseDown(e, row, col, getRowIndex(rowIndex)),
2342
- onMouseenter: (e) => onCellMouseEnter(e, row, col),
2343
- onMouseleave: (e) => onCellMouseLeave(e, row, col),
2344
- onMouseover: (e) => onCellMouseOver(e, row, col)
2461
+ onClick: ($event) => onCellClick($event, row, col, getRowIndex(rowIndex)),
2462
+ onMousedown: ($event) => onCellMouseDown($event, row, col, getRowIndex(rowIndex)),
2463
+ onMouseenter: ($event) => onCellMouseEnter($event, row, col),
2464
+ onMouseleave: ($event) => onCellMouseLeave($event, row, col),
2465
+ onMouseover: ($event) => onCellMouseOver($event, row, col)
2345
2466
  }, [
2346
- col.customCell ? (openBlock(), createBlock(resolveDynamicComponent(col.customCell), {
2467
+ col.type === "expand" || col.type === "tree-node" ? (openBlock(), createElementBlock("div", {
2347
2468
  key: 0,
2348
2469
  class: "table-cell-wrapper",
2349
- col,
2350
- row,
2351
- rowIndex: getRowIndex(rowIndex),
2352
- colIndex,
2353
- cellValue: row && row[col.dataIndex],
2354
- expanded: row && row.__EXPANDED__ || null
2355
- }, null, 8, ["col", "row", "rowIndex", "colIndex", "cellValue", "expanded"])) : (openBlock(), createElementBlock("div", {
2356
- key: 1,
2357
- class: normalizeClass(["table-cell-wrapper", { "expanded-cell-wrapper": col.type === "expand" }]),
2358
- title: col.type !== "seq" ? row == null ? void 0 : row[col.dataIndex] : ""
2470
+ title: row == null ? void 0 : row[col.dataIndex],
2471
+ style: normalizeStyle({ paddingLeft: row.__T_LV__ && row.__T_LV__ * 16 + "px" })
2359
2472
  }, [
2360
- col.type === "seq" ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
2361
- createTextVNode(toDisplayString((props.seqConfig.startIndex || 0) + getRowIndex(rowIndex) + 1), 1)
2362
- ], 64)) : col.type === "expand" ? (openBlock(), createElementBlock("span", _hoisted_12, toDisplayString((row == null ? void 0 : row[col.dataIndex]) ?? ""), 1)) : col.type === "dragRow" ? (openBlock(), createElementBlock(Fragment, { key: 2 }, [
2363
- createVNode(DragHandle, {
2364
- onDragstart: (e) => unref(onTrDragStart)(e, getRowIndex(rowIndex))
2365
- }, null, 8, ["onDragstart"]),
2366
- createElementVNode("span", null, toDisplayString((row == null ? void 0 : row[col.dataIndex]) ?? ""), 1)
2367
- ], 64)) : (openBlock(), createElementBlock(Fragment, { key: 3 }, [
2368
- createTextVNode(toDisplayString((row == null ? void 0 : row[col.dataIndex]) ?? getEmptyCellText.value(col, row)), 1)
2473
+ col.customCell ? (openBlock(), createBlock(resolveDynamicComponent(col.customCell), {
2474
+ key: 0,
2475
+ col,
2476
+ row,
2477
+ rowIndex: getRowIndex(rowIndex),
2478
+ colIndex,
2479
+ cellValue: row && row[col.dataIndex],
2480
+ expanded: row && row.__EXPANDED__ || null,
2481
+ "tree-expanded": row && row.__T_EXPANDED__ || null
2482
+ }, {
2483
+ foldIcon: withCtx(() => [
2484
+ createVNode(TriangleIcon)
2485
+ ]),
2486
+ _: 2
2487
+ }, 1032, ["col", "row", "rowIndex", "colIndex", "cellValue", "expanded", "tree-expanded"])) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
2488
+ col.type === "expand" || col.type === "tree-node" && row.children !== void 0 ? (openBlock(), createBlock(TriangleIcon, {
2489
+ key: 0,
2490
+ onClick: ($event) => triangleClick($event, row, col)
2491
+ }, null, 8, ["onClick"])) : createCommentVNode("", true),
2492
+ createElementVNode("span", {
2493
+ style: normalizeStyle(col.type === "tree-node" && !row.children ? "padding-left: 16px;" : "")
2494
+ }, toDisplayString((row == null ? void 0 : row[col.dataIndex]) ?? ""), 5)
2369
2495
  ], 64))
2370
- ], 10, _hoisted_11))
2496
+ ], 12, _hoisted_11)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
2497
+ col.customCell ? (openBlock(), createBlock(resolveDynamicComponent(col.customCell), {
2498
+ key: 0,
2499
+ class: "table-cell-wrapper",
2500
+ col,
2501
+ row,
2502
+ rowIndex: getRowIndex(rowIndex),
2503
+ colIndex,
2504
+ cellValue: row && row[col.dataIndex]
2505
+ }, null, 8, ["col", "row", "rowIndex", "colIndex", "cellValue"])) : (openBlock(), createElementBlock("div", {
2506
+ key: 1,
2507
+ class: "table-cell-wrapper",
2508
+ title: col.type !== "seq" ? row == null ? void 0 : row[col.dataIndex] : ""
2509
+ }, [
2510
+ col.type === "seq" ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
2511
+ createTextVNode(toDisplayString((props.seqConfig.startIndex || 0) + getRowIndex(rowIndex) + 1), 1)
2512
+ ], 64)) : col.type === "dragRow" ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [
2513
+ createVNode(DragHandle, {
2514
+ onDragstart: ($event) => unref(onTrDragStart)($event, getRowIndex(rowIndex))
2515
+ }, null, 8, ["onDragstart"]),
2516
+ createElementVNode("span", null, toDisplayString((row == null ? void 0 : row[col.dataIndex]) ?? ""), 1)
2517
+ ], 64)) : (openBlock(), createElementBlock(Fragment, { key: 2 }, [
2518
+ createTextVNode(toDisplayString((row == null ? void 0 : row[col.dataIndex]) ?? getEmptyCellText.value(col, row)), 1)
2519
+ ], 64))
2520
+ ], 8, _hoisted_12))
2521
+ ], 64))
2371
2522
  ], 46, _hoisted_10);
2372
2523
  }), 128))
2373
2524
  ], 46, _hoisted_6);