stk-table-vue 0.6.17 → 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 +313 -163
  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,22 +60,23 @@ 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
- const targetVal = newItem[dataIndex];
73
+ const targetVal = newItem[field];
68
74
  if (sortConfig.emptyToBottom && isEmptyValue(targetVal)) {
69
75
  data.push(newItem);
70
76
  } else {
71
77
  const isNumber = sortType === "number";
72
78
  const sIndex = binarySearch(data, (midIndex) => {
73
- const midVal = data[midIndex][dataIndex];
79
+ const midVal = data[midIndex][field];
74
80
  const compareRes = strCompare(midVal, targetVal, isNumber, sortConfig.stringLocaleCompare);
75
81
  return order === "asc" ? compareRes : -compareRes;
76
82
  });
@@ -189,7 +195,6 @@ const HIGHLIGHT_COLOR = {
189
195
  dark: { from: "#1e4c99", to: "#181c21" }
190
196
  };
191
197
  const HIGHLIGHT_DURATION = 2e3;
192
- const HIGHLIGHT_FREQ = 1e3 / 30;
193
198
  const HIGHLIGHT_ROW_CLASS = "highlight-row";
194
199
  const HIGHLIGHT_CELL_CLASS = "highlight-cell";
195
200
  const _chromeVersion = getBrowsersVersion("chrome");
@@ -610,25 +615,21 @@ function useHighlight({ props, stkTableId, tableContainerRef }) {
610
615
  light: HIGHLIGHT_COLOR.light,
611
616
  dark: HIGHLIGHT_COLOR.dark
612
617
  };
613
- const highlightDuration = config.duration ? config.duration * 1e3 : HIGHLIGHT_DURATION;
614
- const highlightFrequency = config.fps && config.fps > 0 ? 1e3 / config.fps : null;
615
- 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);
616
621
  const highlightFrom = computed(() => highlightColor[props.theme].from);
617
- const highlightTo = computed(() => highlightColor[props.theme].to);
618
- const highlightInter = computed(() => interpolateRgb(highlightFrom.value, highlightTo.value));
619
- const highlightDimRowsJs = /* @__PURE__ */ new Map();
620
- let calcHighlightDimLoopJs = false;
621
622
  const highlightDimRowsAnimation = /* @__PURE__ */ new Map();
622
623
  let calcHighlightDimLoopAnimation = false;
623
624
  const highlightDimRowsTimeout = /* @__PURE__ */ new Map();
624
625
  const highlightDimCellsTimeout = /* @__PURE__ */ new Map();
625
- const defaultHighlightDimOption = (() => {
626
+ const defaultHighlightDimOption = computed(() => {
626
627
  const keyframe = { backgroundColor: [highlightFrom.value, ""] };
627
- if (highlightSteps) {
628
- keyframe.easing = `steps(${highlightSteps})`;
628
+ if (highlightSteps.value) {
629
+ keyframe.easing = `steps(${highlightSteps.value})`;
629
630
  }
630
- return { duration: highlightDuration, keyframe };
631
- })();
631
+ return { duration: highlightDuration.value, keyframe };
632
+ });
632
633
  function calcRowHighlightLoop() {
633
634
  if (calcHighlightDimLoopAnimation) return;
634
635
  calcHighlightDimLoopAnimation = true;
@@ -656,39 +657,13 @@ function useHighlight({ props, stkTableId, tableContainerRef }) {
656
657
  };
657
658
  recursion();
658
659
  }
659
- function calcRowHighlightLoopJs() {
660
- if (calcHighlightDimLoopJs) return;
661
- calcHighlightDimLoopJs = true;
662
- const recursion = () => {
663
- window.setTimeout(() => {
664
- const nowTs = Date.now();
665
- highlightDimRowsJs.forEach((highlightStart, rowKeyValue) => {
666
- const progress = (nowTs - highlightStart) / highlightDuration;
667
- let bgc = "";
668
- if (0 <= progress && progress <= 1) {
669
- bgc = highlightInter.value(progress);
670
- } else {
671
- highlightDimRowsJs.delete(rowKeyValue);
672
- }
673
- updateRowBgcJs(rowKeyValue, bgc);
674
- });
675
- if (highlightDimRowsJs.size > 0) {
676
- recursion();
677
- } else {
678
- calcHighlightDimLoopJs = false;
679
- highlightDimRowsJs.clear();
680
- }
681
- }, highlightFrequency || HIGHLIGHT_FREQ);
682
- };
683
- recursion();
684
- }
685
660
  function setHighlightDimCell(rowKeyValue, colKeyValue, option = {}) {
686
661
  var _a;
687
662
  const cellEl = (_a = tableContainerRef.value) == null ? void 0 : _a.querySelector(`[data-cell-key="${rowKeyValue}--${colKeyValue}"]`);
688
663
  const { className, method, duration, keyframe } = {
689
664
  className: HIGHLIGHT_CELL_CLASS,
690
665
  method: "animation",
691
- ...defaultHighlightDimOption,
666
+ ...defaultHighlightDimOption.value,
692
667
  ...option
693
668
  };
694
669
  if (!cellEl) return;
@@ -703,7 +678,7 @@ function useHighlight({ props, stkTableId, tableContainerRef }) {
703
678
  const { className, method, keyframe, duration } = {
704
679
  className: HIGHLIGHT_ROW_CLASS,
705
680
  method: "animation",
706
- ...defaultHighlightDimOption,
681
+ ...defaultHighlightDimOption.value,
707
682
  ...option
708
683
  };
709
684
  if (method === "css") {
@@ -725,14 +700,6 @@ function useHighlight({ props, stkTableId, tableContainerRef }) {
725
700
  rowEl.animate(keyframe, duration);
726
701
  }
727
702
  }
728
- } else if (method === "js") {
729
- const nowTs = Date.now();
730
- for (let i = 0; i < rowKeyValues.length; i++) {
731
- const rowKeyValue = rowKeyValues[i];
732
- highlightDimRowsJs.set(rowKeyValue, nowTs);
733
- updateRowBgcJs(rowKeyValue, highlightFrom.value);
734
- }
735
- calcRowHighlightLoopJs();
736
703
  }
737
704
  }
738
705
  function highlightRowsInCssKeyframe(rowKeyValues, className, duration) {
@@ -798,11 +765,6 @@ function useHighlight({ props, stkTableId, tableContainerRef }) {
798
765
  });
799
766
  }
800
767
  }
801
- function updateRowBgcJs(rowKeyValue, color) {
802
- const rowEl = document.getElementById(stkTableId + "-" + String(rowKeyValue));
803
- if (!rowEl) return;
804
- rowEl.style.backgroundColor = color;
805
- }
806
768
  return {
807
769
  highlightSteps,
808
770
  setHighlightDimRow,
@@ -884,6 +846,57 @@ function useKeyboardArrowScroll(targetElement, { props, scrollTo, virtualScroll,
884
846
  if (!isMouseOver) isMouseOver = true;
885
847
  }
886
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
+ }
887
900
  function useThDrag({ props, emits, colKeyGen }) {
888
901
  const findParentTH = (e) => e.target.closest("th");
889
902
  const dragConfig = computed(() => {
@@ -1364,6 +1377,125 @@ function useVirtualScroll({
1364
1377
  clearAllAutoHeight
1365
1378
  };
1366
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
+ }
1367
1499
  const _hoisted_1 = ["data-col-key", "draggable", "rowspan", "colspan", "title", "onClick"];
1368
1500
  const _hoisted_2 = ["onMousedown"];
1369
1501
  const _hoisted_3 = { class: "table-header-title" };
@@ -1381,7 +1513,7 @@ const _hoisted_8 = ["colspan"];
1381
1513
  const _hoisted_9 = { class: "table-cell-wrapper" };
1382
1514
  const _hoisted_10 = ["data-cell-key", "onClick", "onMousedown", "onMouseenter", "onMouseleave", "onMouseover"];
1383
1515
  const _hoisted_11 = ["title"];
1384
- const _hoisted_12 = { key: 1 };
1516
+ const _hoisted_12 = ["title"];
1385
1517
  const _sfc_main = /* @__PURE__ */ defineComponent({
1386
1518
  __name: "StkTable",
1387
1519
  props: {
@@ -1403,7 +1535,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1403
1535
  columns: { default: () => [] },
1404
1536
  dataSource: { default: () => [] },
1405
1537
  rowKey: { type: [String, Number, Function], default: "" },
1406
- colKey: { type: [String, Number, Function], default: "dataIndex" },
1538
+ colKey: {},
1407
1539
  emptyCellText: { type: [String, Function], default: "--" },
1408
1540
  noDataFull: { type: Boolean, default: false },
1409
1541
  showNoData: { type: Boolean, default: true },
@@ -1414,7 +1546,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1414
1546
  cellHover: { type: Boolean, default: false },
1415
1547
  cellActive: { type: Boolean, default: false },
1416
1548
  selectedCellRevokable: { type: Boolean, default: true },
1417
- headerDrag: { default: false },
1549
+ headerDrag: { type: Boolean, default: false },
1418
1550
  rowClassName: { type: Function, default: () => "" },
1419
1551
  colResizable: { type: Boolean, default: false },
1420
1552
  colMinWidth: { default: 10 },
@@ -1431,11 +1563,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1431
1563
  seqConfig: { default: () => ({}) },
1432
1564
  expandConfig: { default: () => ({}) },
1433
1565
  dragRowConfig: { default: () => ({}) },
1566
+ treeConfig: { default: () => ({}) },
1434
1567
  cellFixedMode: { default: "sticky" },
1435
1568
  smoothScroll: { type: Boolean, default: DEFAULT_SMOOTH_SCROLL },
1436
1569
  scrollRowByRow: { type: Boolean, default: false }
1437
1570
  },
1438
- 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"],
1439
1572
  setup(__props, { expose: __expose, emit: __emit }) {
1440
1573
  const stkTableId = createStkTableId();
1441
1574
  const props = __props;
@@ -1456,7 +1589,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1456
1589
  const tableHeaders = shallowRef([]);
1457
1590
  const tableHeadersForCalc = shallowRef([]);
1458
1591
  const tableHeaderLast = computed(() => tableHeadersForCalc.value.slice(-1)[0] || []);
1459
- 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([]);
1460
1596
  const rowKeyGenComputed = computed(() => {
1461
1597
  const { rowKey } = props;
1462
1598
  if (typeof rowKey === "function") {
@@ -1467,7 +1603,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1467
1603
  });
1468
1604
  const colKeyGen = computed(() => {
1469
1605
  const { colKey } = props;
1470
- if (typeof colKey === "function") {
1606
+ if (colKey === void 0) {
1607
+ return (col) => col.key || col.dataIndex;
1608
+ } else if (typeof colKey === "function") {
1471
1609
  return (col) => colKey(col);
1472
1610
  } else {
1473
1611
  return (col) => col[colKey];
@@ -1481,7 +1619,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1481
1619
  return (col, row) => emptyCellText({ row, col });
1482
1620
  }
1483
1621
  });
1484
- const rowKeyGenStore = /* @__PURE__ */ new WeakMap();
1622
+ const rowKeyGenCache = /* @__PURE__ */ new WeakMap();
1485
1623
  const { onThDragStart, onThDragOver, onThDrop, isHeaderDraggable } = useThDrag({ props, emits, colKeyGen });
1486
1624
  const { onTrDragStart, onTrDrop, onTrDragOver, onTrDragEnd, onTrDragEnter } = useTrDrag({ props, emits, dataSourceCopy });
1487
1625
  const {
@@ -1540,6 +1678,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1540
1678
  tableHeaderLast,
1541
1679
  fixedCols
1542
1680
  });
1681
+ const { toggleExpandRow, setRowExpand } = useRowExpand({ dataSourceCopy, rowKeyGen, emits });
1682
+ const { toggleTreeNode, setTreeExpand, flatTreeData } = useTree({ props, dataSourceCopy, rowKeyGen, emits });
1543
1683
  watch(
1544
1684
  () => props.columns,
1545
1685
  () => {
@@ -1558,6 +1698,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1558
1698
  });
1559
1699
  }
1560
1700
  );
1701
+ watch(
1702
+ () => props.rowHeight,
1703
+ () => {
1704
+ initVirtualScrollY();
1705
+ }
1706
+ );
1561
1707
  watch(
1562
1708
  () => props.virtualX,
1563
1709
  () => {
@@ -1571,7 +1717,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1571
1717
  watch(
1572
1718
  () => props.dataSource,
1573
1719
  (val) => {
1574
- if (!val) {
1720
+ if (!Array.isArray(val)) {
1575
1721
  console.warn("invalid dataSource");
1576
1722
  return;
1577
1723
  }
@@ -1579,7 +1725,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1579
1725
  if (dataSourceCopy.value.length !== val.length) {
1580
1726
  needInitVirtualScrollY = true;
1581
1727
  }
1582
- dataSourceCopy.value = val.slice();
1728
+ initDataSource(val);
1583
1729
  if (needInitVirtualScrollY) {
1584
1730
  nextTick(() => initVirtualScrollY());
1585
1731
  }
@@ -1596,11 +1742,19 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1596
1742
  () => updateFixedShadow()
1597
1743
  );
1598
1744
  dealColumns();
1745
+ initDataSource();
1599
1746
  onMounted(() => {
1600
1747
  initVirtualScroll();
1601
1748
  updateFixedShadow();
1602
1749
  dealDefaultSorter();
1603
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
+ }
1604
1758
  function dealDefaultSorter() {
1605
1759
  if (!props.sortConfig.defaultSort) return;
1606
1760
  const { key, dataIndex, order, silent } = { silent: false, ...props.sortConfig.defaultSort };
@@ -1677,13 +1831,13 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1677
1831
  }
1678
1832
  function rowKeyGen(row) {
1679
1833
  if (!row) return row;
1680
- let key = rowKeyGenStore.get(row) || row.__ROW_KEY__;
1834
+ let key = rowKeyGenCache.get(row) || row.__ROW_KEY__;
1681
1835
  if (!key) {
1682
1836
  key = rowKeyGenComputed.value(row);
1683
1837
  if (key === void 0) {
1684
1838
  key = Math.random().toString();
1685
1839
  }
1686
- rowKeyGenStore.set(row, key);
1840
+ rowKeyGenCache.set(row, key);
1687
1841
  }
1688
1842
  return key;
1689
1843
  }
@@ -1804,10 +1958,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1804
1958
  function onRowMenu(e, row, rowIndex) {
1805
1959
  emits("row-menu", e, row, { rowIndex });
1806
1960
  }
1807
- function onCellClick(e, row, col, rowIndex) {
1961
+ function triangleClick(e, row, col) {
1808
1962
  if (col.type === "expand") {
1809
1963
  toggleExpandRow(row, col);
1964
+ } else if (col.type === "tree-node") {
1965
+ toggleTreeNode(row, col);
1810
1966
  }
1967
+ }
1968
+ function onCellClick(e, row, col, rowIndex) {
1811
1969
  if (props.cellActive) {
1812
1970
  const cellKey = cellKeyGen(row, col);
1813
1971
  const result = { row, col, select: false, rowIndex };
@@ -1966,51 +2124,6 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1966
2124
  if (!sortOrder) return [];
1967
2125
  return [{ key: sortCol.value, order: sortOrder }];
1968
2126
  }
1969
- function toggleExpandRow(row, col) {
1970
- const isExpand = (row == null ? void 0 : row.__EXPANDED__) === col ? !(row == null ? void 0 : row.__EXPANDED__) : true;
1971
- setRowExpand(row, isExpand, { col });
1972
- }
1973
- function setRowExpand(rowKeyOrRow, expand, data) {
1974
- let rowKey;
1975
- if (typeof rowKeyOrRow === "string") {
1976
- rowKey = rowKeyOrRow;
1977
- } else {
1978
- rowKey = rowKeyGen(rowKeyOrRow);
1979
- }
1980
- const tempData = dataSourceCopy.value.slice();
1981
- const index = tempData.findIndex((it) => rowKeyGen(it) === rowKey);
1982
- if (index === -1) {
1983
- console.warn("expandRow failed.rowKey:", rowKey);
1984
- return;
1985
- }
1986
- for (let i = index + 1; i < tempData.length; i++) {
1987
- const item = tempData[i];
1988
- const rowKey2 = item.__ROW_KEY__;
1989
- if (rowKey2 == null ? void 0 : rowKey2.startsWith(EXPANDED_ROW_KEY_PREFIX)) {
1990
- tempData.splice(i, 1);
1991
- i--;
1992
- } else {
1993
- break;
1994
- }
1995
- }
1996
- const row = tempData[index];
1997
- const col = (data == null ? void 0 : data.col) || null;
1998
- if (expand) {
1999
- const newExpandRow = {
2000
- __ROW_KEY__: EXPANDED_ROW_KEY_PREFIX + rowKey,
2001
- __EXPANDED_ROW__: row,
2002
- __EXPANDED_COL__: col
2003
- };
2004
- tempData.splice(index + 1, 0, newExpandRow);
2005
- }
2006
- if (row) {
2007
- row.__EXPANDED__ = expand ? col : null;
2008
- }
2009
- dataSourceCopy.value = tempData;
2010
- if (!(data == null ? void 0 : data.silent)) {
2011
- emits("toggle-row-expand", { expanded: Boolean(expand), row, col });
2012
- }
2013
- }
2014
2127
  __expose({
2015
2128
  /**
2016
2129
  * 重新计算虚拟列表宽高
@@ -2122,7 +2235,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
2122
2235
  * en: Clear all row heights
2123
2236
  * @see {@link clearAllAutoHeight}
2124
2237
  */
2125
- clearAllAutoHeight
2238
+ clearAllAutoHeight,
2239
+ /**
2240
+ * 设置树节点展开状态
2241
+ *
2242
+ * en: Set tree node expand state
2243
+ * @see {@link setTreeExpand}
2244
+ */
2245
+ setTreeExpand
2126
2246
  });
2127
2247
  return (_ctx, _cache) => {
2128
2248
  return openBlock(), createElementBlock("div", {
@@ -2186,7 +2306,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
2186
2306
  (openBlock(true), createElementBlock(Fragment, null, renderList(tableHeaders.value, (row, rowIndex) => {
2187
2307
  return openBlock(), createElementBlock("tr", {
2188
2308
  key: rowIndex,
2189
- onContextmenu: _cache[3] || (_cache[3] = (e) => onHeaderMenu(e))
2309
+ onContextmenu: _cache[3] || (_cache[3] = ($event) => onHeaderMenu($event))
2190
2310
  }, [
2191
2311
  unref(virtualX_on) ? (openBlock(), createElementBlock("th", {
2192
2312
  key: 0,
@@ -2222,7 +2342,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
2222
2342
  unref(colResizeOn)(col) && colIndex > 0 ? (openBlock(), createElementBlock("div", {
2223
2343
  key: 0,
2224
2344
  class: "table-header-resizer left",
2225
- onMousedown: (e) => unref(onThResizeMouseDown)(e, col, true)
2345
+ onMousedown: ($event) => unref(onThResizeMouseDown)($event, col, true)
2226
2346
  }, null, 40, _hoisted_2)) : createCommentVNode("", true),
2227
2347
  createElementVNode("div", {
2228
2348
  class: "table-header-cell-wrapper",
@@ -2247,7 +2367,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
2247
2367
  unref(colResizeOn)(col) ? (openBlock(), createElementBlock("div", {
2248
2368
  key: 1,
2249
2369
  class: "table-header-resizer right",
2250
- onMousedown: (e) => unref(onThResizeMouseDown)(e, col)
2370
+ onMousedown: ($event) => unref(onThResizeMouseDown)($event, col)
2251
2371
  }, null, 40, _hoisted_4)) : createCommentVNode("", true)
2252
2372
  ], 46, _hoisted_1);
2253
2373
  }), 128)),
@@ -2300,11 +2420,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
2300
2420
  style: normalizeStyle({
2301
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"
2302
2422
  }),
2303
- onClick: (e) => onRowClick(e, row, getRowIndex(rowIndex)),
2304
- onDblclick: (e) => onRowDblclick(e, row, getRowIndex(rowIndex)),
2305
- onContextmenu: (e) => onRowMenu(e, row, getRowIndex(rowIndex)),
2306
- onMouseover: (e) => onTrMouseOver(e, row),
2307
- 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))
2308
2428
  }, [
2309
2429
  unref(virtualX_on) ? (openBlock(), createElementBlock("td", _hoisted_7)) : createCommentVNode("", true),
2310
2430
  row && row.__EXPANDED_ROW__ ? (openBlock(), createElementBlock("td", {
@@ -2333,42 +2453,72 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
2333
2453
  {
2334
2454
  "seq-column": col.type === "seq",
2335
2455
  active: currentSelectedCellKey.value === cellKeyGen(row, col),
2336
- "expand-cell": col.type === "expand",
2337
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__,
2338
2458
  "drag-row-cell": col.type === "dragRow"
2339
2459
  }
2340
2460
  ]),
2341
- onClick: (e) => onCellClick(e, row, col, getRowIndex(rowIndex)),
2342
- onMousedown: (e) => onCellMouseDown(e, row, col, getRowIndex(rowIndex)),
2343
- onMouseenter: (e) => onCellMouseEnter(e, row, col),
2344
- onMouseleave: (e) => onCellMouseLeave(e, row, col),
2345
- 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)
2346
2466
  }, [
2347
- col.customCell ? (openBlock(), createBlock(resolveDynamicComponent(col.customCell), {
2467
+ col.type === "expand" || col.type === "tree-node" ? (openBlock(), createElementBlock("div", {
2348
2468
  key: 0,
2349
2469
  class: "table-cell-wrapper",
2350
- col,
2351
- row,
2352
- rowIndex: getRowIndex(rowIndex),
2353
- colIndex,
2354
- cellValue: row && row[col.dataIndex],
2355
- expanded: row && row.__EXPANDED__ || null
2356
- }, null, 8, ["col", "row", "rowIndex", "colIndex", "cellValue", "expanded"])) : (openBlock(), createElementBlock("div", {
2357
- key: 1,
2358
- class: normalizeClass(["table-cell-wrapper", { "expanded-cell-wrapper": col.type === "expand" }]),
2359
- 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" })
2360
2472
  }, [
2361
- col.type === "seq" ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
2362
- createTextVNode(toDisplayString((props.seqConfig.startIndex || 0) + getRowIndex(rowIndex) + 1), 1)
2363
- ], 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 }, [
2364
- createVNode(DragHandle, {
2365
- onDragstart: (e) => unref(onTrDragStart)(e, getRowIndex(rowIndex))
2366
- }, null, 8, ["onDragstart"]),
2367
- createElementVNode("span", null, toDisplayString((row == null ? void 0 : row[col.dataIndex]) ?? ""), 1)
2368
- ], 64)) : (openBlock(), createElementBlock(Fragment, { key: 3 }, [
2369
- 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)
2370
2495
  ], 64))
2371
- ], 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))
2372
2522
  ], 46, _hoisted_10);
2373
2523
  }), 128))
2374
2524
  ], 46, _hoisted_6);