stk-table-vue 0.8.11 → 0.8.13

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.
@@ -56,11 +56,11 @@ declare function getSortColumns(): {
56
56
  }[];
57
57
  declare function __VLS_template(): {
58
58
  tableHeader?(_: {
59
- col: PrivateStkTableColumn<any>;
59
+ col: PrivateStkTableColumn<PrivateRowDT>;
60
60
  }): any;
61
61
  expand?(_: {
62
62
  row: any;
63
- col: any;
63
+ col: StkTableColumn<any> | undefined;
64
64
  }): any;
65
65
  empty?(_: {}): any;
66
66
  customBottom?(_: {}): any;
@@ -135,7 +135,7 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
135
135
  /** 单元格再次点击否可以取消选中 (cellActive=true)*/
136
136
  selectedCellRevokable?: boolean;
137
137
  /** 表头是否可拖动。支持回调函数。 */
138
- headerDrag?: boolean | HeaderDragConfig;
138
+ headerDrag?: boolean | HeaderDragConfig<DT>;
139
139
  /**
140
140
  * 给行附加className<br>
141
141
  * FIXME: 是否需要优化,因为不传此prop会使表格行一直执行空函数,是否有影响
@@ -157,7 +157,7 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
157
157
  * "v" - 仅展示竖线
158
158
  * "body-v" - 仅表体展示竖线
159
159
  */
160
- bordered?: boolean | "h" | "v" | "body-v";
160
+ bordered?: boolean | "h" | "v" | "body-v" | "body-h";
161
161
  /**
162
162
  * 自动重新计算虚拟滚动高度宽度。默认true
163
163
  * [非响应式]
@@ -212,7 +212,7 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
212
212
  headless: boolean;
213
213
  theme: string;
214
214
  rowHeight: number;
215
- autoRowHeight: boolean;
215
+ autoRowHeight: () => false;
216
216
  rowHover: boolean;
217
217
  rowActive: () => Required<RowActiveOption<any>>;
218
218
  rowCurrentRevokable: boolean;
@@ -233,9 +233,9 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
233
233
  cellHover: boolean;
234
234
  cellActive: boolean;
235
235
  selectedCellRevokable: boolean;
236
- headerDrag: boolean;
236
+ headerDrag: () => false;
237
237
  rowClassName: () => "";
238
- colResizable: boolean;
238
+ colResizable: () => false;
239
239
  colMinWidth: number;
240
240
  bordered: boolean;
241
241
  autoResize: boolean;
@@ -504,7 +504,7 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
504
504
  /** 单元格再次点击否可以取消选中 (cellActive=true)*/
505
505
  selectedCellRevokable?: boolean;
506
506
  /** 表头是否可拖动。支持回调函数。 */
507
- headerDrag?: boolean | HeaderDragConfig;
507
+ headerDrag?: boolean | HeaderDragConfig<DT>;
508
508
  /**
509
509
  * 给行附加className<br>
510
510
  * FIXME: 是否需要优化,因为不传此prop会使表格行一直执行空函数,是否有影响
@@ -526,7 +526,7 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
526
526
  * "v" - 仅展示竖线
527
527
  * "body-v" - 仅表体展示竖线
528
528
  */
529
- bordered?: boolean | "h" | "v" | "body-v";
529
+ bordered?: boolean | "h" | "v" | "body-v" | "body-h";
530
530
  /**
531
531
  * 自动重新计算虚拟滚动高度宽度。默认true
532
532
  * [非响应式]
@@ -581,7 +581,7 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
581
581
  headless: boolean;
582
582
  theme: string;
583
583
  rowHeight: number;
584
- autoRowHeight: boolean;
584
+ autoRowHeight: () => false;
585
585
  rowHover: boolean;
586
586
  rowActive: () => Required<RowActiveOption<any>>;
587
587
  rowCurrentRevokable: boolean;
@@ -602,9 +602,9 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
602
602
  cellHover: boolean;
603
603
  cellActive: boolean;
604
604
  selectedCellRevokable: boolean;
605
- headerDrag: boolean;
605
+ headerDrag: () => false;
606
606
  rowClassName: () => "";
607
- colResizable: boolean;
607
+ colResizable: () => false;
608
608
  colMinWidth: number;
609
609
  bordered: boolean;
610
610
  autoResize: boolean;
@@ -710,11 +710,11 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
710
710
  cellHover: boolean;
711
711
  cellActive: boolean;
712
712
  selectedCellRevokable: boolean;
713
- headerDrag: boolean | HeaderDragConfig;
713
+ headerDrag: boolean | HeaderDragConfig<DT>;
714
714
  rowClassName: (row: DT, i: number) => string | undefined;
715
715
  colResizable: boolean | ColResizableConfig<DT>;
716
716
  colMinWidth: number;
717
- bordered: boolean | "h" | "v" | "body-v";
717
+ bordered: boolean | "h" | "v" | "body-v" | "body-h";
718
718
  autoResize: boolean | (() => void);
719
719
  fixedColShadow: boolean;
720
720
  hideHeaderTitle: boolean | string[];
@@ -18,9 +18,9 @@ export type CustomCellProps<T extends Record<string, any>> = {
18
18
  * - 不展开: null
19
19
  * - 展开: 返回column配置
20
20
  */
21
- expanded: PrivateRowDT['__EXP__'];
21
+ expanded?: PrivateRowDT['__EXP__'];
22
22
  /** if tree expanded */
23
- treeExpanded: PrivateRowDT['__T_EXP__'];
23
+ treeExpanded?: PrivateRowDT['__T_EXP__'];
24
24
  };
25
25
  export type CustomHeaderCellProps<T extends Record<string, any>> = {
26
26
  col: StkTableColumn<T>;
@@ -144,7 +144,7 @@ export type PrivateRowDT = {
144
144
  * if row expanded
145
145
  * @private
146
146
  */
147
- __EXP__?: StkTableColumn<any> | null;
147
+ __EXP__?: StkTableColumn<any>;
148
148
  /**
149
149
  * if tree node row expanded
150
150
  * @private
@@ -160,6 +160,11 @@ export type PrivateRowDT = {
160
160
  * @private
161
161
  */
162
162
  __T_LV__?: number;
163
+ /** expanded row */
164
+ __EXP_R__?: any;
165
+ /** expanded col */
166
+ __EXP_C__?: StkTableColumn<any>;
167
+ children?: any[];
163
168
  };
164
169
  export type SortOption<T extends Record<string, any>> = Pick<StkTableColumn<T>, 'sorter' | 'dataIndex' | 'sortField' | 'sortType'>;
165
170
  export type SortState<T extends Record<string, any>> = Pick<StkTableColumn<T>, 'dataIndex' | 'sortField' | 'sortType'> & {
@@ -227,10 +232,6 @@ export type ExpandConfig = {
227
232
  /** worked in virtual mode */
228
233
  height?: number;
229
234
  };
230
- export type ExpandedRow = PrivateRowDT & {
231
- __EXPANDED_ROW__: any;
232
- __EXPANDED_COL__: any;
233
- };
234
235
  /** drag row config */
235
236
  export type DragRowConfig = {
236
237
  mode?: 'none' | 'insert' | 'swap';
@@ -1,13 +1,13 @@
1
1
  import { Ref, ShallowRef } from 'vue';
2
- import { PrivateStkTableColumn, RowKeyGen, UniqKey } from './types';
2
+ import { PrivateRowDT, PrivateStkTableColumn, RowKeyGen, UniqKey } from './types';
3
3
 
4
4
  type Option<DT extends Record<string, any>> = {
5
5
  props: any;
6
6
  tableContainerRef: Ref<HTMLElement | undefined>;
7
7
  trRef: Ref<HTMLTableRowElement[] | undefined>;
8
- dataSourceCopy: ShallowRef<DT[]>;
9
- tableHeaderLast: ShallowRef<PrivateStkTableColumn<DT>[]>;
10
- tableHeaders: ShallowRef<PrivateStkTableColumn<DT>[][]>;
8
+ dataSourceCopy: ShallowRef<PrivateRowDT[]>;
9
+ tableHeaderLast: ShallowRef<PrivateStkTableColumn<PrivateRowDT>[]>;
10
+ tableHeaders: ShallowRef<PrivateStkTableColumn<PrivateRowDT>[][]>;
11
11
  rowKeyGen: RowKeyGen;
12
12
  maxRowSpan: Map<UniqKey, number>;
13
13
  };
@@ -86,10 +86,10 @@ export declare function useVirtualScroll<DT extends Record<string, any>>({ props
86
86
  scrollLeft: number;
87
87
  }>;
88
88
  virtual_on: import('vue').ComputedRef<any>;
89
- virtual_dataSourcePart: import('vue').ComputedRef<DT[]>;
89
+ virtual_dataSourcePart: import('vue').ComputedRef<PrivateRowDT[]>;
90
90
  virtual_offsetBottom: import('vue').ComputedRef<number>;
91
91
  virtualX_on: import('vue').ComputedRef<any>;
92
- virtualX_columnPart: import('vue').ComputedRef<PrivateStkTableColumn<DT>[]>;
92
+ virtualX_columnPart: import('vue').ComputedRef<PrivateStkTableColumn<PrivateRowDT>[]>;
93
93
  virtualX_offsetRight: import('vue').ComputedRef<number>;
94
94
  tableHeaderHeight: import('vue').ComputedRef<number>;
95
95
  initVirtualScroll: (height?: number) => void;
@@ -12,7 +12,7 @@ const _hoisted_1$3 = {
12
12
  draggable: "true"
13
13
  };
14
14
  function _sfc_render$2(_ctx, _cache) {
15
- return openBlock(), createElementBlock("span", _hoisted_1$3, _cache[0] || (_cache[0] = [
15
+ return openBlock(), createElementBlock("span", _hoisted_1$3, [..._cache[0] || (_cache[0] = [
16
16
  createElementVNode("svg", {
17
17
  viewBox: "0 0 1024 1024",
18
18
  width: "16",
@@ -21,7 +21,7 @@ function _sfc_render$2(_ctx, _cache) {
21
21
  }, [
22
22
  createElementVNode("path", { d: "M640 853.3a85.3 85.3 0 1 1 85.3-85.3 85.3 85.3 0 0 1-85.3 85.3z m-256 0a85.3 85.3 0 1 1 85.3-85.3 85.3 85.3 0 0 1-85.3 85.3z m256-256a85.3 85.3 0 1 1 85.3-85.3 85.3 85.3 0 0 1-85.3 85.3z m-256 0a85.3 85.3 0 1 1 85.3-85.3 85.3 85.3 0 0 1-85.3 85.3z m256-256a85.3 85.3 0 1 1 85.3-85.3 85.3 85.3 0 0 1-85.3 85.3zM384 341.3a85.3 85.3 0 1 1 85.3-85.3 85.3 85.3 0 0 1-85.3 85.3z" })
23
23
  ], -1)
24
- ]));
24
+ ])]);
25
25
  }
26
26
  const DragHandle = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["render", _sfc_render$2]]);
27
27
  const _sfc_main$2 = {};
@@ -32,7 +32,7 @@ const _hoisted_1$2 = {
32
32
  viewBox: "0 0 16 16"
33
33
  };
34
34
  function _sfc_render$1(_ctx, _cache) {
35
- return openBlock(), createElementBlock("svg", _hoisted_1$2, _cache[0] || (_cache[0] = [
35
+ return openBlock(), createElementBlock("svg", _hoisted_1$2, [..._cache[0] || (_cache[0] = [
36
36
  createElementVNode("polygon", {
37
37
  class: "arrow-up",
38
38
  fill: "#757699",
@@ -43,7 +43,7 @@ function _sfc_render$1(_ctx, _cache) {
43
43
  transform: "translate(8, 12) rotate(-180) translate(-8, -12) ",
44
44
  points: "8 10 4.8 14 11.2 14"
45
45
  }, null, -1)
46
- ]));
46
+ ])]);
47
47
  }
48
48
  const SortIcon = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["render", _sfc_render$1]]);
49
49
  const _sfc_main$1 = {};
@@ -227,9 +227,9 @@ const DEFAULT_SORT_CONFIG = {
227
227
  sortChildren: false
228
228
  };
229
229
  const DEFAULT_ROW_ACTIVE_CONFIG = {
230
- enabled: false,
230
+ enabled: true,
231
231
  disabled: () => false,
232
- revokable: false
232
+ revokable: true
233
233
  };
234
234
  var TagType = /* @__PURE__ */ ((TagType2) => {
235
235
  TagType2[TagType2["TH"] = 0] = "TH";
@@ -917,17 +917,21 @@ function useMergeCells({ rowActiveProp, tableHeaderLast, rowKeyGen, colKeyGen, v
917
917
  hiddenCellMap.value = {};
918
918
  hoverRowMap.value = {};
919
919
  });
920
- function hideCells(rowKey, startIndex, count, isSelfRow = false, mergeCellKey) {
921
- for (let i = startIndex; i < startIndex + count; i++) {
922
- if (!isSelfRow || i !== startIndex) {
923
- const nextCol = tableHeaderLast.value[i];
924
- if (!nextCol) break;
925
- const nextColKey = colKeyGen.value(nextCol);
926
- if (!hiddenCellMap.value[rowKey]) hiddenCellMap.value[rowKey] = /* @__PURE__ */ new Set();
927
- hiddenCellMap.value[rowKey].add(nextColKey);
920
+ function hideCells(rowKey, colKey, colspan, isSelfRow = false, mergeCellKey) {
921
+ const startIndex = tableHeaderLast.value.findIndex((item) => colKeyGen.value(item) === colKey);
922
+ for (let i = startIndex; i < startIndex + colspan; i++) {
923
+ if (!isSelfRow) {
924
+ if (!hoverRowMap.value[rowKey]) hoverRowMap.value[rowKey] = /* @__PURE__ */ new Set();
925
+ hoverRowMap.value[rowKey].add(mergeCellKey);
926
+ }
927
+ if (isSelfRow && i === startIndex) {
928
+ continue;
928
929
  }
929
- if (!hoverRowMap.value[rowKey]) hoverRowMap.value[rowKey] = /* @__PURE__ */ new Set();
930
- hoverRowMap.value[rowKey].add(mergeCellKey);
930
+ const nextCol = tableHeaderLast.value[i];
931
+ if (!nextCol) break;
932
+ const nextColKey = colKeyGen.value(nextCol);
933
+ if (!hiddenCellMap.value[rowKey]) hiddenCellMap.value[rowKey] = /* @__PURE__ */ new Set();
934
+ hiddenCellMap.value[rowKey].add(nextColKey);
931
935
  }
932
936
  }
933
937
  function mergeCellsWrapper(row, col, rowIndex, colIndex) {
@@ -937,21 +941,20 @@ function useMergeCells({ rowActiveProp, tableHeaderLast, rowKeyGen, colKeyGen, v
937
941
  rowspan = rowspan || 1;
938
942
  if (colspan === 1 && rowspan === 1) return;
939
943
  const rowKey = rowKeyGen(row);
940
- const colKey = colKeyGen.value(col);
941
- const curColIndex = tableHeaderLast.value.findIndex((item) => colKeyGen.value(item) === colKey);
942
944
  const curRowIndex = virtual_dataSourcePart.value.findIndex((item) => rowKeyGen(item) === rowKey);
943
- const mergedCellKey = pureCellKeyGen(rowKey, colKey);
944
945
  if (curRowIndex === -1) return;
946
+ const colKey = colKeyGen.value(col);
947
+ const mergedCellKey = pureCellKeyGen(rowKey, colKey);
945
948
  for (let i = curRowIndex; i < curRowIndex + rowspan; i++) {
946
949
  const row2 = virtual_dataSourcePart.value[i];
947
950
  if (!row2) break;
948
- hideCells(rowKeyGen(row2), curColIndex, colspan, i === curRowIndex, mergedCellKey);
951
+ hideCells(rowKeyGen(row2), colKey, colspan, i === curRowIndex, mergedCellKey);
949
952
  }
950
953
  return { colspan, rowspan };
951
954
  }
955
+ const emptySet = /* @__PURE__ */ new Set();
952
956
  function updateHoverMergedCells(rowKey) {
953
- const set = rowKey === void 0 ? null : hoverRowMap.value[rowKey];
954
- hoverMergedCells.value = set || /* @__PURE__ */ new Set();
957
+ hoverMergedCells.value = rowKey === void 0 ? emptySet : hoverRowMap.value[rowKey] || emptySet;
955
958
  }
956
959
  function updateActiveMergedCells(clear, rowKey) {
957
960
  if (!rowActiveProp.value.enabled) return;
@@ -1003,20 +1006,20 @@ function useRowExpand({ dataSourceCopy, rowKeyGen, emits }) {
1003
1006
  }
1004
1007
  }
1005
1008
  const row = tempData[index];
1006
- const col = (data == null ? void 0 : data.col) || null;
1009
+ const col = data == null ? void 0 : data.col;
1007
1010
  if (expand == null) {
1008
1011
  expand = isExpanded(row, col);
1009
1012
  }
1010
1013
  if (expand) {
1011
1014
  const newExpandRow = {
1012
1015
  __ROW_K__: EXPANDED_ROW_KEY_PREFIX + rowKey,
1013
- __EXPANDED_ROW__: row,
1014
- __EXPANDED_COL__: col
1016
+ __EXP_R__: row,
1017
+ __EXP_C__: col
1015
1018
  };
1016
1019
  tempData.splice(index + 1, 0, newExpandRow);
1017
1020
  }
1018
1021
  if (row) {
1019
- row.__EXP__ = expand ? col : null;
1022
+ row[expandedKey] = expand ? col : void 0;
1020
1023
  }
1021
1024
  dataSourceCopy.value = tempData;
1022
1025
  if (!(data == null ? void 0 : data.silent)) {
@@ -1252,6 +1255,7 @@ function useTrDrag({ props, emits, dataSourceCopy }) {
1252
1255
  }
1253
1256
  function useTree({ props, dataSourceCopy, rowKeyGen, emits }) {
1254
1257
  const { defaultExpandAll, defaultExpandKeys, defaultExpandLevel } = props.treeConfig;
1258
+ let isFirstLoad = true;
1255
1259
  function toggleTreeNode(row, col) {
1256
1260
  const expand = row ? !row.__T_EXP__ : false;
1257
1261
  privateSetTreeExpand(row, { expand, col, isClick: true });
@@ -1301,33 +1305,36 @@ function useTree({ props, dataSourceCopy, rowKeyGen, emits }) {
1301
1305
  row.__T_LV__ = level;
1302
1306
  }
1303
1307
  }
1304
- function flatTreeData(data) {
1305
- const result = [];
1306
- (function recursion(data2, level, parent) {
1307
- if (!data2) return;
1308
- for (let i = 0; i < data2.length; i++) {
1309
- const item = data2[i];
1310
- result.push(item);
1311
- const isExpanded = Boolean(item.__T_EXP__);
1312
- setNodeExpanded(item, isExpanded, level);
1313
- if (!isExpanded) {
1314
- if (defaultExpandAll) {
1308
+ function recursionFlat(data, level, parent) {
1309
+ if (!data) return [];
1310
+ let result = [];
1311
+ for (let i = 0; i < data.length; i++) {
1312
+ const item = data[i];
1313
+ result.push(item);
1314
+ const isExpanded = Boolean(item.__T_EXP__);
1315
+ setNodeExpanded(item, isExpanded, level);
1316
+ if (isFirstLoad && !isExpanded) {
1317
+ if (defaultExpandAll) {
1318
+ setNodeExpanded(item, true);
1319
+ } else {
1320
+ if (defaultExpandLevel && level < defaultExpandLevel) {
1321
+ setNodeExpanded(item, true);
1322
+ }
1323
+ if (defaultExpandKeys == null ? void 0 : defaultExpandKeys.includes(rowKeyGen(item))) {
1315
1324
  setNodeExpanded(item, true);
1316
- } else {
1317
- if (defaultExpandLevel && level < defaultExpandLevel) {
1318
- setNodeExpanded(item, true);
1319
- }
1320
- if (defaultExpandKeys == null ? void 0 : defaultExpandKeys.includes(rowKeyGen(item))) {
1321
- setNodeExpanded(item, true);
1322
- }
1323
- if (!item.__T_EXP__) {
1324
- continue;
1325
- }
1326
1325
  }
1327
1326
  }
1328
- recursion(item.children, level + 1);
1329
1327
  }
1330
- })(data, 0);
1328
+ if (item.__T_EXP__) {
1329
+ const res = recursionFlat(item.children, level + 1);
1330
+ result = result.concat(res);
1331
+ }
1332
+ }
1333
+ return result;
1334
+ }
1335
+ function flatTreeData(data) {
1336
+ const result = recursionFlat(data, 0);
1337
+ isFirstLoad = false;
1331
1338
  return result;
1332
1339
  }
1333
1340
  function expandNode(row, level) {
@@ -1462,7 +1469,7 @@ function useVirtualScroll({
1462
1469
  if (hasExpandCol.value) {
1463
1470
  const expandedRowHeight = (_a = props.expandConfig) == null ? void 0 : _a.height;
1464
1471
  const tempRowHeightFn = rowHeightFn;
1465
- rowHeightFn = (row) => row && row.__EXPANDED_ROW__ && expandedRowHeight || tempRowHeightFn(row);
1472
+ rowHeightFn = (row) => row && row.__EXP_R__ && expandedRowHeight || tempRowHeightFn(row);
1466
1473
  }
1467
1474
  return rowHeightFn;
1468
1475
  });
@@ -1717,7 +1724,7 @@ const _hoisted_8 = {
1717
1724
  };
1718
1725
  const _hoisted_9 = ["colspan"];
1719
1726
  const _hoisted_10 = { class: "table-cell-wrapper" };
1720
- const _hoisted_11 = ["data-cell-key", "onClick", "onMousedown", "onMouseenter", "onMouseleave", "onMouseover"];
1727
+ const _hoisted_11 = ["onClick", "onMousedown", "onMouseenter", "onMouseleave", "onMouseover"];
1721
1728
  const _hoisted_12 = ["title"];
1722
1729
  const _sfc_main = /* @__PURE__ */ defineComponent({
1723
1730
  __name: "StkTable",
@@ -1730,9 +1737,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1730
1737
  headless: { type: Boolean, default: false },
1731
1738
  theme: { default: "light" },
1732
1739
  rowHeight: { default: DEFAULT_ROW_HEIGHT },
1733
- autoRowHeight: { type: Boolean, default: false },
1740
+ autoRowHeight: { type: [Boolean, Object], default: () => false },
1734
1741
  rowHover: { type: Boolean, default: true },
1735
- rowActive: { type: Boolean, default: () => DEFAULT_ROW_ACTIVE_CONFIG },
1742
+ rowActive: { type: [Boolean, Object], default: () => DEFAULT_ROW_ACTIVE_CONFIG },
1736
1743
  rowCurrentRevokable: { type: Boolean, default: true },
1737
1744
  headerRowHeight: { default: DEFAULT_ROW_HEIGHT },
1738
1745
  virtual: { type: Boolean, default: false },
@@ -1751,9 +1758,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1751
1758
  cellHover: { type: Boolean, default: false },
1752
1759
  cellActive: { type: Boolean, default: false },
1753
1760
  selectedCellRevokable: { type: Boolean, default: true },
1754
- headerDrag: { type: Boolean, default: false },
1761
+ headerDrag: { type: [Boolean, Object], default: () => false },
1755
1762
  rowClassName: { type: Function, default: () => "" },
1756
- colResizable: { type: Boolean, default: false },
1763
+ colResizable: { type: [Boolean, Object], default: () => false },
1757
1764
  colMinWidth: { default: 10 },
1758
1765
  bordered: { type: [Boolean, String], default: true },
1759
1766
  autoResize: { type: [Boolean, Function], default: true },
@@ -2119,6 +2126,41 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
2119
2126
  }
2120
2127
  return col.title || "";
2121
2128
  }
2129
+ function getTDProps(row, col) {
2130
+ const colKey = colKeyGen.value(col);
2131
+ if (!row) {
2132
+ return {
2133
+ style: cellStyleMap.value[TagType.TD].get(colKey)
2134
+ };
2135
+ }
2136
+ const cellKey = cellKeyGen(row, col);
2137
+ const classList = [col.className, fixedColClassMap.value.get(colKeyGen.value(col))];
2138
+ if (col.mergeCells) {
2139
+ if (hoverMergedCells.value.has(cellKey)) {
2140
+ classList.push("cell-hover");
2141
+ }
2142
+ if (activeMergedCells.value.has(cellKey)) {
2143
+ classList.push("cell-active");
2144
+ }
2145
+ }
2146
+ if (props.cellActive && currentSelectedCellKey.value === cellKey) {
2147
+ classList.push("active");
2148
+ }
2149
+ if (col.type === "seq") {
2150
+ classList.push("seq-column");
2151
+ } else if (col.type === "expand" && (row.__EXP__ ? colKeyGen.value(row.__EXP__) === colKeyGen.value(col) : false)) {
2152
+ classList.push("expanded");
2153
+ } else if (col.type === "tree-node" && row.__T_EXP__) {
2154
+ classList.push("tree-expanded");
2155
+ } else if (col.type === "dragRow") {
2156
+ classList.push("drag-row-cell");
2157
+ }
2158
+ return {
2159
+ "data-cell-key": cellKey,
2160
+ style: cellStyleMap.value[TagType.TD].get(colKey),
2161
+ class: classList
2162
+ };
2163
+ }
2122
2164
  function onColumnSort(col, click = true, options = {}) {
2123
2165
  if (!col) {
2124
2166
  console.warn("onColumnSort: not found col:", col);
@@ -2530,18 +2572,16 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
2530
2572
  ref_key: "tableContainerRef",
2531
2573
  ref: tableContainerRef,
2532
2574
  class: normalizeClass(["stk-table", {
2533
- virtual: _ctx.virtual,
2534
- "virtual-x": _ctx.virtualX,
2575
+ virtual: __props.virtual,
2576
+ "virtual-x": __props.virtualX,
2535
2577
  "vt-on": unref(virtual_on),
2536
- light: _ctx.theme === "light",
2537
- dark: _ctx.theme === "dark",
2538
- headless: _ctx.headless,
2578
+ light: __props.theme === "light",
2579
+ dark: __props.theme === "dark",
2580
+ headless: __props.headless,
2539
2581
  "is-col-resizing": unref(isColResizing),
2540
2582
  "col-resizable": props.colResizable,
2541
2583
  bordered: props.bordered,
2542
- "bordered-h": props.bordered === "h",
2543
- "bordered-v": props.bordered === "v",
2544
- "bordered-body-v": props.bordered === "body-v",
2584
+ [`bordered-${props.bordered}`]: typeof props.bordered === "string",
2545
2585
  stripe: props.stripe,
2546
2586
  "cell-hover": props.cellHover,
2547
2587
  "cell-active": props.cellActive,
@@ -2567,7 +2607,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
2567
2607
  class: "row-by-row-table-height",
2568
2608
  style: normalizeStyle(`height: ${SRBRTotalHeight.value}px`)
2569
2609
  }, null, 4)) : createCommentVNode("", true),
2570
- _ctx.colResizable ? (openBlock(), createElementBlock("div", {
2610
+ __props.colResizable ? (openBlock(), createElementBlock("div", {
2571
2611
  key: 1,
2572
2612
  ref_key: "colResizeIndicatorRef",
2573
2613
  ref: colResizeIndicatorRef,
@@ -2577,9 +2617,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
2577
2617
  class: normalizeClass(["stk-table-main", {
2578
2618
  "fixed-mode": props.fixedMode
2579
2619
  }]),
2580
- style: normalizeStyle({ width: _ctx.width, minWidth: _ctx.minWidth, maxWidth: _ctx.maxWidth })
2620
+ style: normalizeStyle({ width: __props.width, minWidth: __props.minWidth, maxWidth: __props.maxWidth })
2581
2621
  }, [
2582
- !_ctx.headless ? (openBlock(), createElementBlock("thead", _hoisted_1, [
2622
+ !__props.headless ? (openBlock(), createElementBlock("thead", _hoisted_1, [
2583
2623
  (openBlock(true), createElementBlock(Fragment, null, renderList(tableHeaders.value, (row, rowIndex) => {
2584
2624
  return openBlock(), createElementBlock("tr", {
2585
2625
  key: rowIndex,
@@ -2670,8 +2710,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
2670
2710
  style: normalizeStyle(`height:${unref(virtualScroll).offsetTop}px`),
2671
2711
  class: "padding-top-tr"
2672
2712
  }, [
2673
- unref(virtualX_on) && _ctx.fixedMode && _ctx.headless ? (openBlock(), createElementBlock("td", _hoisted_6)) : createCommentVNode("", true),
2674
- _ctx.fixedMode && _ctx.headless ? (openBlock(true), createElementBlock(Fragment, { key: 1 }, renderList(unref(virtualX_columnPart), (col) => {
2713
+ unref(virtualX_on) && __props.fixedMode && __props.headless ? (openBlock(), createElementBlock("td", _hoisted_6)) : createCommentVNode("", true),
2714
+ __props.fixedMode && __props.headless ? (openBlock(true), createElementBlock(Fragment, { key: 1 }, renderList(unref(virtualX_columnPart), (col) => {
2675
2715
  return openBlock(), createElementBlock("td", {
2676
2716
  key: colKeyGen.value(col),
2677
2717
  style: normalizeStyle(cellStyleMap.value[unref(TagType).TD].get(colKeyGen.value(col)))
@@ -2681,21 +2721,21 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
2681
2721
  (openBlock(true), createElementBlock(Fragment, null, renderList(unref(virtual_dataSourcePart), (row, rowIndex) => {
2682
2722
  var _a, _b;
2683
2723
  return openBlock(), createElementBlock("tr", {
2684
- id: unref(stkTableId) + "-" + (_ctx.rowKey ? rowKeyGen(row) : getRowIndex(rowIndex)),
2724
+ id: unref(stkTableId) + "-" + (__props.rowKey ? rowKeyGen(row) : getRowIndex(rowIndex)),
2685
2725
  ref_for: true,
2686
2726
  ref_key: "trRef",
2687
2727
  ref: trRef,
2688
- key: _ctx.rowKey ? rowKeyGen(row) : getRowIndex(rowIndex),
2689
- "data-row-key": _ctx.rowKey ? rowKeyGen(row) : getRowIndex(rowIndex),
2728
+ key: __props.rowKey ? rowKeyGen(row) : getRowIndex(rowIndex),
2729
+ "data-row-key": __props.rowKey ? rowKeyGen(row) : getRowIndex(rowIndex),
2690
2730
  class: normalizeClass({
2691
- active: _ctx.rowKey ? rowKeyGen(row) === currentRowKey.value : row === currentRow.value,
2692
- hover: props.showTrHoverClass && (_ctx.rowKey ? rowKeyGen(row) === currentHoverRowKey.value : row === currentHoverRowKey.value),
2693
- [_ctx.rowClassName(row, getRowIndex(rowIndex)) || ""]: true,
2694
- expanded: row == null ? void 0 : row.__EXP__,
2695
- "expanded-row": row && row.__EXPANDED_ROW__
2731
+ active: __props.rowKey ? rowKeyGen(row) === currentRowKey.value : row === currentRow.value,
2732
+ hover: props.showTrHoverClass && (__props.rowKey ? rowKeyGen(row) === currentHoverRowKey.value : row === currentHoverRowKey.value),
2733
+ [__props.rowClassName(row, getRowIndex(rowIndex)) || ""]: true,
2734
+ expanded: row && row.__EXP__,
2735
+ "expanded-row": row && row.__EXP_R__
2696
2736
  }),
2697
2737
  style: normalizeStyle({
2698
- "--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"
2738
+ "--row-height": row && row.__EXP_R__ && props.virtual && ((_a = props.expandConfig) == null ? void 0 : _a.height) && ((_b = props.expandConfig) == null ? void 0 : _b.height) + "px"
2699
2739
  }),
2700
2740
  onClick: ($event) => onRowClick($event, row, getRowIndex(rowIndex)),
2701
2741
  onDblclick: ($event) => onRowDblclick($event, row, getRowIndex(rowIndex)),
@@ -2705,18 +2745,18 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
2705
2745
  onDrop: ($event) => unref(onTrDrop)($event, getRowIndex(rowIndex))
2706
2746
  }, [
2707
2747
  unref(virtualX_on) ? (openBlock(), createElementBlock("td", _hoisted_8)) : createCommentVNode("", true),
2708
- row && row.__EXPANDED_ROW__ ? (openBlock(), createElementBlock("td", {
2748
+ row && row.__EXP_R__ ? (openBlock(), createElementBlock("td", {
2709
2749
  key: 1,
2710
2750
  colspan: unref(virtualX_columnPart).length
2711
2751
  }, [
2712
2752
  createElementVNode("div", _hoisted_10, [
2713
2753
  renderSlot(_ctx.$slots, "expand", {
2714
- row: row.__EXPANDED_ROW__,
2715
- col: row.__EXPANDED_COL__
2754
+ row: row.__EXP_R__,
2755
+ col: row.__EXP_C__
2716
2756
  }, () => {
2717
2757
  var _a2;
2718
2758
  return [
2719
- createTextVNode(toDisplayString(((_a2 = row.__EXPANDED_ROW__) == null ? void 0 : _a2[row.__EXPANDED_COL__.dataIndex]) ?? ""), 1)
2759
+ createTextVNode(toDisplayString(((_a2 = row.__EXP_R__) == null ? void 0 : _a2[row.__EXP_C__.dataIndex]) ?? ""), 1)
2720
2760
  ];
2721
2761
  })
2722
2762
  ])
@@ -2724,23 +2764,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
2724
2764
  var _a2;
2725
2765
  return openBlock(), createElementBlock(Fragment, null, [
2726
2766
  !((_a2 = unref(hiddenCellMap)[rowKeyGen(row)]) == null ? void 0 : _a2.has(colKeyGen.value(col))) ? (openBlock(), createElementBlock("td", mergeProps({
2727
- key: colKeyGen.value(col),
2728
- "data-cell-key": cellKeyGen(row, col),
2729
- style: cellStyleMap.value[unref(TagType).TD].get(colKeyGen.value(col)),
2730
- class: [
2731
- col.className,
2732
- unref(fixedColClassMap).get(colKeyGen.value(col)),
2733
- {
2734
- "cell-hover": col.mergeCells && unref(hoverMergedCells).has(cellKeyGen(row, col)),
2735
- "cell-active": col.mergeCells && unref(activeMergedCells).has(cellKeyGen(row, col)),
2736
- "seq-column": col.type === "seq",
2737
- active: props.cellActive && currentSelectedCellKey.value === cellKeyGen(row, col),
2738
- expanded: col.type === "expand" && (row.__EXP__ ? colKeyGen.value(row.__EXP__) === colKeyGen.value(col) : false),
2739
- "tree-expanded": col.type === "tree-node" && row.__T_EXP__,
2740
- "drag-row-cell": col.type === "dragRow"
2741
- }
2742
- ]
2743
- }, { ref_for: true }, unref(mergeCellsWrapper)(row, col, rowIndex, colIndex), {
2767
+ key: colKeyGen.value(col)
2768
+ }, { ref_for: true }, {
2769
+ ...getTDProps(row, col),
2770
+ ...unref(mergeCellsWrapper)(row, col, rowIndex, colIndex)
2771
+ }, {
2744
2772
  onClick: ($event) => onCellClick($event, row, col, getRowIndex(rowIndex)),
2745
2773
  onMousedown: ($event) => onCellMouseDown($event, row, col, getRowIndex(rowIndex)),
2746
2774
  onMouseenter: ($event) => onCellMouseEnter($event, row, col),
@@ -2755,8 +2783,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
2755
2783
  rowIndex: getRowIndex(rowIndex),
2756
2784
  colIndex,
2757
2785
  cellValue: row && row[col.dataIndex],
2758
- expanded: row ? row.__EXP_ : null,
2759
- "tree-expanded": row ? row.__T_EXP__ : null
2786
+ expanded: row && row.__EXP__,
2787
+ "tree-expanded": row && row.__T_EXP__
2760
2788
  }, {
2761
2789
  stkFoldIcon: withCtx(() => [
2762
2790
  createVNode(TriangleIcon, {
@@ -2809,12 +2837,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
2809
2837
  }, null, 4)) : createCommentVNode("", true)
2810
2838
  ], 32)
2811
2839
  ], 6),
2812
- (!dataSourceCopy.value || !dataSourceCopy.value.length) && _ctx.showNoData ? (openBlock(), createElementBlock("div", {
2840
+ (!dataSourceCopy.value || !dataSourceCopy.value.length) && __props.showNoData ? (openBlock(), createElementBlock("div", {
2813
2841
  key: 2,
2814
- class: normalizeClass(["stk-table-no-data", { "no-data-full": _ctx.noDataFull }])
2842
+ class: normalizeClass(["stk-table-no-data", { "no-data-full": __props.noDataFull }])
2815
2843
  }, [
2816
2844
  renderSlot(_ctx.$slots, "empty", {}, () => [
2817
- _cache[8] || (_cache[8] = createTextVNode("暂无数据"))
2845
+ _cache[8] || (_cache[8] = createTextVNode("暂无数据", -1))
2818
2846
  ])
2819
2847
  ], 2)) : createCommentVNode("", true),
2820
2848
  renderSlot(_ctx.$slots, "customBottom")
package/lib/style.css CHANGED
@@ -102,6 +102,9 @@
102
102
  .stk-table.bordered-body-v tbody{
103
103
  --bg-border-bottom:linear-gradient(transparent, transparent);
104
104
  }
105
+ .stk-table.bordered-body-h tbody{
106
+ --bg-border-right:linear-gradient(transparent, transparent);
107
+ }
105
108
  .stk-table.stripe:not(.vt-on) .stk-tbody-main tr:nth-child(even){
106
109
  background-color:var(--stripe-bgc);
107
110
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stk-table-vue",
3
- "version": "0.8.11",
3
+ "version": "0.8.13",
4
4
  "description": "High performance realtime virtual table for vue3 and vue2.7",
5
5
  "main": "./lib/stk-table-vue.js",
6
6
  "types": "./lib/src/StkTable/index.d.ts",
@@ -41,10 +41,10 @@
41
41
  "license": "MIT",
42
42
  "devDependencies": {
43
43
  "@types/mockjs": "^1.0.10",
44
- "@types/node": "^20.12.10",
44
+ "@types/node": "^22.18.10",
45
45
  "@typescript-eslint/eslint-plugin": "^7.7.0",
46
46
  "@typescript-eslint/parser": "^7.7.0",
47
- "@vitejs/plugin-vue": "^6.0.0",
47
+ "@vitejs/plugin-vue": "^6.0.2",
48
48
  "@vue/test-utils": "^2.4.6",
49
49
  "eslint": "^8.57.0",
50
50
  "eslint-config-prettier": "^9.1.0",
@@ -61,7 +61,7 @@
61
61
  "prettier": "^3.2.5",
62
62
  "stk-table-vue": "^0.8.7",
63
63
  "typescript": "^5.8.3",
64
- "vite": "^7.1.7",
64
+ "vite": "^7.2.2",
65
65
  "vite-plugin-dts": "3.9.1",
66
66
  "vitepress": "^1.6.4",
67
67
  "vitepress-demo-plugin": "^1.4.7",
@@ -13,9 +13,7 @@
13
13
  'is-col-resizing': isColResizing,
14
14
  'col-resizable': props.colResizable,
15
15
  bordered: props.bordered,
16
- 'bordered-h': props.bordered === 'h',
17
- 'bordered-v': props.bordered === 'v',
18
- 'bordered-body-v': props.bordered === 'body-v',
16
+ [`bordered-${props.bordered}`]: typeof props.bordered === 'string',
19
17
  stripe: props.stripe,
20
18
  'cell-hover': props.cellHover,
21
19
  'cell-active': props.cellActive,
@@ -115,12 +113,11 @@
115
113
  active: rowKey ? rowKeyGen(row) === currentRowKey : row === currentRow,
116
114
  hover: props.showTrHoverClass && (rowKey ? rowKeyGen(row) === currentHoverRowKey : row === currentHoverRowKey),
117
115
  [rowClassName(row, getRowIndex(rowIndex)) || '']: true,
118
- expanded: row?.__EXP__,
119
- 'expanded-row': row && row.__EXPANDED_ROW__,
116
+ expanded: row && row.__EXP__,
117
+ 'expanded-row': row && row.__EXP_R__,
120
118
  }"
121
119
  :style="{
122
- '--row-height':
123
- row && row.__EXPANDED_ROW__ && props.virtual && props.expandConfig?.height && props.expandConfig?.height + 'px',
120
+ '--row-height': row && row.__EXP_R__ && props.virtual && props.expandConfig?.height && props.expandConfig?.height + 'px',
124
121
  }"
125
122
  @click="onRowClick($event, row, getRowIndex(rowIndex))"
126
123
  @dblclick="onRowDblclick($event, row, getRowIndex(rowIndex))"
@@ -130,10 +127,10 @@
130
127
  @drop="onTrDrop($event, getRowIndex(rowIndex))"
131
128
  >
132
129
  <td v-if="virtualX_on" class="vt-x-left"></td>
133
- <td v-if="row && row.__EXPANDED_ROW__" :colspan="virtualX_columnPart.length">
130
+ <td v-if="row && row.__EXP_R__" :colspan="virtualX_columnPart.length">
134
131
  <div class="table-cell-wrapper">
135
- <slot name="expand" :row="row.__EXPANDED_ROW__" :col="row.__EXPANDED_COL__">
136
- {{ row.__EXPANDED_ROW__?.[row.__EXPANDED_COL__.dataIndex] ?? '' }}
132
+ <slot name="expand" :row="row.__EXP_R__" :col="row.__EXP_C__">
133
+ {{ row.__EXP_R__?.[row.__EXP_C__!.dataIndex] ?? '' }}
137
134
  </slot>
138
135
  </div>
139
136
  </td>
@@ -142,22 +139,10 @@
142
139
  <td
143
140
  v-if="!hiddenCellMap[rowKeyGen(row)]?.has(colKeyGen(col))"
144
141
  :key="colKeyGen(col)"
145
- :data-cell-key="cellKeyGen(row, col)"
146
- :style="cellStyleMap[TagType.TD].get(colKeyGen(col))"
147
- :class="[
148
- col.className,
149
- fixedColClassMap.get(colKeyGen(col)),
150
- {
151
- 'cell-hover': col.mergeCells && hoverMergedCells.has(cellKeyGen(row, col)),
152
- 'cell-active': col.mergeCells && activeMergedCells.has(cellKeyGen(row, col)),
153
- 'seq-column': col.type === 'seq',
154
- active: props.cellActive && currentSelectedCellKey === cellKeyGen(row, col),
155
- expanded: col.type === 'expand' && (row.__EXP__ ? colKeyGen(row.__EXP__) === colKeyGen(col) : false),
156
- 'tree-expanded': col.type === 'tree-node' && row.__T_EXP__,
157
- 'drag-row-cell': col.type === 'dragRow',
158
- },
159
- ]"
160
- v-bind="mergeCellsWrapper(row, col, rowIndex, colIndex)"
142
+ v-bind="{
143
+ ...getTDProps(row, col),
144
+ ...mergeCellsWrapper(row, col, rowIndex, colIndex),
145
+ }"
161
146
  @click="onCellClick($event, row, col, getRowIndex(rowIndex))"
162
147
  @mousedown="onCellMouseDown($event, row, col, getRowIndex(rowIndex))"
163
148
  @mouseenter="onCellMouseEnter($event, row, col)"
@@ -173,8 +158,8 @@
173
158
  :rowIndex="getRowIndex(rowIndex)"
174
159
  :colIndex="colIndex"
175
160
  :cellValue="row && row[col.dataIndex]"
176
- :expanded="row ? row.__EXP_ : null"
177
- :tree-expanded="row ? row.__T_EXP__ : null"
161
+ :expanded="row && row.__EXP__"
162
+ :tree-expanded="row && row.__T_EXP__"
178
163
  >
179
164
  <template #stkFoldIcon>
180
165
  <TriangleIcon @click="triangleClick($event, row, col)"></TriangleIcon>
@@ -357,7 +342,7 @@ const props = withDefaults(
357
342
  /** 单元格再次点击否可以取消选中 (cellActive=true)*/
358
343
  selectedCellRevokable?: boolean;
359
344
  /** 表头是否可拖动。支持回调函数。 */
360
- headerDrag?: boolean | HeaderDragConfig;
345
+ headerDrag?: boolean | HeaderDragConfig<DT>;
361
346
  /**
362
347
  * 给行附加className<br>
363
348
  * FIXME: 是否需要优化,因为不传此prop会使表格行一直执行空函数,是否有影响
@@ -379,7 +364,7 @@ const props = withDefaults(
379
364
  * "v" - 仅展示竖线
380
365
  * "body-v" - 仅表体展示竖线
381
366
  */
382
- bordered?: boolean | 'h' | 'v' | 'body-v';
367
+ bordered?: boolean | 'h' | 'v' | 'body-v' | 'body-h';
383
368
  /**
384
369
  * 自动重新计算虚拟滚动高度宽度。默认true
385
370
  * [非响应式]
@@ -435,7 +420,7 @@ const props = withDefaults(
435
420
  headless: false,
436
421
  theme: 'light',
437
422
  rowHeight: DEFAULT_ROW_HEIGHT,
438
- autoRowHeight: false,
423
+ autoRowHeight: () => false,
439
424
  rowHover: true,
440
425
  rowActive: () => DEFAULT_ROW_ACTIVE_CONFIG,
441
426
  rowCurrentRevokable: true,
@@ -456,9 +441,9 @@ const props = withDefaults(
456
441
  cellHover: false,
457
442
  cellActive: false,
458
443
  selectedCellRevokable: true,
459
- headerDrag: false,
444
+ headerDrag: () => false,
460
445
  rowClassName: () => '',
461
- colResizable: false,
446
+ colResizable: () => false,
462
447
  colMinWidth: 10,
463
448
  bordered: true,
464
449
  autoResize: true,
@@ -668,7 +653,7 @@ const sortSwitchOrder: Order[] = [null, 'desc', 'asc'];
668
653
  * ]
669
654
  * ```
670
655
  */
671
- const tableHeaders = shallowRef<PrivateStkTableColumn<DT>[][]>([]);
656
+ const tableHeaders = shallowRef<PrivateStkTableColumn<PrivateRowDT>[][]>([]);
672
657
 
673
658
  /**
674
659
  * 用于计算多级表头的tableHeaders。模拟rowSpan 位置的辅助数组。用于计算固定列。
@@ -688,7 +673,7 @@ const tableHeaders = shallowRef<PrivateStkTableColumn<DT>[][]>([]);
688
673
  * ]
689
674
  * ```
690
675
  */
691
- const tableHeadersForCalc = shallowRef<PrivateStkTableColumn<DT>[][]>([]);
676
+ const tableHeadersForCalc = shallowRef<PrivateStkTableColumn<PrivateRowDT>[][]>([]);
692
677
 
693
678
  /** 最后一行的tableHeaders.内容是 props.columns 的引用集合 */
694
679
  const tableHeaderLast = computed(() => tableHeadersForCalc.value.slice(-1)[0] || []);
@@ -924,14 +909,14 @@ function dealDefaultSorter() {
924
909
  */
925
910
  function dealColumns() {
926
911
  // reset
927
- const tableHeadersTemp: StkTableColumn<DT>[][] = [];
928
- const tableHeadersForCalcTemp: StkTableColumn<DT>[][] = [];
929
- let copyColumn = props.columns; // do not deep clone
912
+ const tableHeadersTemp: StkTableColumn<PrivateRowDT>[][] = [];
913
+ const tableHeadersForCalcTemp: StkTableColumn<PrivateRowDT>[][] = [];
914
+ let copyColumn: StkTableColumn<PrivateRowDT>[] = props.columns; // do not deep clone
930
915
  // relative 模式下不支持sticky列。因此就放在左右两侧。
931
916
  if (isRelativeMode.value) {
932
- let leftCol: StkTableColumn<DT>[] = [];
933
- let centerCol: StkTableColumn<DT>[] = [];
934
- let rightCol: StkTableColumn<DT>[] = [];
917
+ let leftCol: StkTableColumn<PrivateRowDT>[] = [];
918
+ let centerCol: StkTableColumn<PrivateRowDT>[] = [];
919
+ let rightCol: StkTableColumn<PrivateRowDT>[] = [];
935
920
  copyColumn.forEach(col => {
936
921
  if (col.fixed === 'left') {
937
922
  leftCol.push(col);
@@ -962,8 +947,8 @@ function dealColumns() {
962
947
  * @param parentFixed 父节点固定列继承。
963
948
  */
964
949
  function flat(
965
- arr: PrivateStkTableColumn<DT>[],
966
- parent: PrivateStkTableColumn<DT> | null,
950
+ arr: PrivateStkTableColumn<PrivateRowDT>[],
951
+ parent: PrivateStkTableColumn<PrivateRowDT> | null,
967
952
  depth = 0 /* , parentFixed: 'left' | 'right' | null = null */,
968
953
  ) {
969
954
  /** 所有子节点数量 */
@@ -1015,7 +1000,7 @@ function dealColumns() {
1015
1000
  tableHeadersForCalc.value = tableHeadersForCalcTemp;
1016
1001
  }
1017
1002
 
1018
- function updateDataSource(val:DT[]) {
1003
+ function updateDataSource(val: DT[]) {
1019
1004
  if (!Array.isArray(val)) {
1020
1005
  console.warn('invalid dataSource');
1021
1006
  return;
@@ -1041,7 +1026,6 @@ function updateDataSource(val:DT[]) {
1041
1026
  }
1042
1027
  }
1043
1028
 
1044
-
1045
1029
  /**
1046
1030
  * 行唯一值生成
1047
1031
  */
@@ -1109,6 +1093,47 @@ function getHeaderTitle(col: StkTableColumn<DT>): string {
1109
1093
  return col.title || '';
1110
1094
  }
1111
1095
 
1096
+ function getTDProps(row: PrivateRowDT | null | undefined, col: StkTableColumn<PrivateRowDT>) {
1097
+ const colKey = colKeyGen.value(col);
1098
+ if (!row) {
1099
+ return {
1100
+ style: cellStyleMap.value[TagType.TD].get(colKey),
1101
+ };
1102
+ }
1103
+
1104
+ const cellKey = cellKeyGen(row, col);
1105
+
1106
+ const classList = [col.className, fixedColClassMap.value.get(colKeyGen.value(col))];
1107
+ if (col.mergeCells) {
1108
+ if (hoverMergedCells.value.has(cellKey)) {
1109
+ classList.push('cell-hover');
1110
+ }
1111
+ if (activeMergedCells.value.has(cellKey)) {
1112
+ classList.push('cell-active');
1113
+ }
1114
+ }
1115
+
1116
+ if (props.cellActive && currentSelectedCellKey.value === cellKey) {
1117
+ classList.push('active');
1118
+ }
1119
+
1120
+ if (col.type === 'seq') {
1121
+ classList.push('seq-column');
1122
+ } else if (col.type === 'expand' && (row.__EXP__ ? colKeyGen.value(row.__EXP__) === colKeyGen.value(col) : false)) {
1123
+ classList.push('expanded');
1124
+ } else if (col.type === 'tree-node' && row.__T_EXP__) {
1125
+ classList.push('tree-expanded');
1126
+ } else if (col.type === 'dragRow') {
1127
+ classList.push('drag-row-cell');
1128
+ }
1129
+
1130
+ return {
1131
+ 'data-cell-key': cellKey,
1132
+ style: cellStyleMap.value[TagType.TD].get(colKey),
1133
+ class: classList,
1134
+ };
1135
+ }
1136
+
1112
1137
  /**
1113
1138
  * 表头点击排序
1114
1139
  * @param click 是否为点击表头触发
@@ -1136,7 +1161,7 @@ function onColumnSort(col: StkTableColumn<DT> | undefined | null, click = true,
1136
1161
  sortOrderIndex.value = sortOrderIndex.value % 3;
1137
1162
 
1138
1163
  let order = sortSwitchOrder[sortOrderIndex.value];
1139
- const sortConfig: SortConfig<any> = { ...DEFAULT_SORT_CONFIG, ...props.sortConfig, ...col.sortConfig };
1164
+ const sortConfig: SortConfig<DT> = { ...DEFAULT_SORT_CONFIG, ...props.sortConfig, ...col.sortConfig };
1140
1165
  const { defaultSort } = sortConfig;
1141
1166
  const colKeyGenValue = colKeyGen.value;
1142
1167
 
@@ -1163,7 +1188,7 @@ function onColumnSort(col: StkTableColumn<DT> | undefined | null, click = true,
1163
1188
  }
1164
1189
  }
1165
1190
  }
1166
- let dataSourceTemp: any[] = props.dataSource.slice();
1191
+ let dataSourceTemp: DT[] = props.dataSource.slice();
1167
1192
  if (!props.sortRemote || options.force) {
1168
1193
  const sortOption = col || defaultSort;
1169
1194
  if (sortOption) {
@@ -44,7 +44,7 @@ export const DEFAULT_SORT_CONFIG = {
44
44
  } satisfies SortConfig<any>;
45
45
 
46
46
  export const DEFAULT_ROW_ACTIVE_CONFIG: Required<RowActiveOption<any>> = {
47
- enabled: false,
47
+ enabled: true,
48
48
  disabled: () => false,
49
- revokable: false,
49
+ revokable: true,
50
50
  };
@@ -151,6 +151,12 @@
151
151
  }
152
152
  }
153
153
 
154
+ &.bordered-body-h {
155
+ tbody {
156
+ --bg-border-right: linear-gradient(transparent, transparent);
157
+ }
158
+ }
159
+
154
160
  &.stripe {
155
161
  &:not(.vt-on) .stk-tbody-main tr:nth-child(even) {
156
162
  background-color: var(--stripe-bgc);
@@ -17,9 +17,9 @@ export type CustomCellProps<T extends Record<string, any>> = {
17
17
  * - 不展开: null
18
18
  * - 展开: 返回column配置
19
19
  */
20
- expanded: PrivateRowDT['__EXP__'];
20
+ expanded?: PrivateRowDT['__EXP__'];
21
21
  /** if tree expanded */
22
- treeExpanded: PrivateRowDT['__T_EXP__']
22
+ treeExpanded?: PrivateRowDT['__T_EXP__']
23
23
  };
24
24
 
25
25
  export type CustomHeaderCellProps<T extends Record<string, any>> = {
@@ -149,7 +149,7 @@ export type PrivateRowDT = {
149
149
  * if row expanded
150
150
  * @private
151
151
  */
152
- __EXP__?: StkTableColumn<any> | null;
152
+ __EXP__?: StkTableColumn<any>;
153
153
  /**
154
154
  * if tree node row expanded
155
155
  * @private
@@ -165,6 +165,11 @@ export type PrivateRowDT = {
165
165
  * @private
166
166
  */
167
167
  __T_LV__?: number;
168
+ /** expanded row */
169
+ __EXP_R__?: any;
170
+ /** expanded col */
171
+ __EXP_C__?: StkTableColumn<any>;
172
+ children?: any[]
168
173
  };
169
174
 
170
175
  export type SortOption<T extends Record<string, any>> = Pick<StkTableColumn<T>, 'sorter' | 'dataIndex' | 'sortField' | 'sortType'>;
@@ -241,10 +246,6 @@ export type ExpandConfig = {
241
246
  height?: number;
242
247
  };
243
248
 
244
- export type ExpandedRow = PrivateRowDT & {
245
- __EXPANDED_ROW__: any;
246
- __EXPANDED_COL__: any;
247
- };
248
249
 
249
250
  /** drag row config */
250
251
  export type DragRowConfig = {
@@ -35,20 +35,25 @@ export function useMergeCells({ rowActiveProp, tableHeaderLast, rowKeyGen, colKe
35
35
  /**
36
36
  * abstract the logic of hiding cells
37
37
  */
38
- function hideCells(rowKey: UniqKey, startIndex: number, count: number, isSelfRow = false, mergeCellKey: string) {
39
- for (let i = startIndex; i < startIndex + count; i++) {
40
- if (!isSelfRow || i !== startIndex) {
41
- // self row does not need to be hidden
42
- const nextCol = tableHeaderLast.value[i];
43
- if (!nextCol) break;
44
- const nextColKey = colKeyGen.value(nextCol);
45
- if (!hiddenCellMap.value[rowKey]) hiddenCellMap.value[rowKey] = new Set();
46
- hiddenCellMap.value[rowKey].add(nextColKey);
38
+ function hideCells(rowKey: UniqKey, colKey: UniqKey, colspan: number, isSelfRow = false, mergeCellKey: string) {
39
+ const startIndex = tableHeaderLast.value.findIndex(item => colKeyGen.value(item) === colKey);
40
+
41
+ for (let i = startIndex; i < startIndex + colspan; i++) {
42
+ if(!isSelfRow) {
43
+ // if other row hovered, the rowspan cell need to be highlight
44
+ if (!hoverRowMap.value[rowKey]) hoverRowMap.value[rowKey] = new Set();
45
+ hoverRowMap.value[rowKey].add(mergeCellKey);
47
46
  }
47
+ if (isSelfRow && i === startIndex) {
48
+ // self row start cell does not need to be hidden
49
+ continue;
50
+ }
51
+ const nextCol = tableHeaderLast.value[i];
52
+ if (!nextCol) break;
53
+ const nextColKey = colKeyGen.value(nextCol);
54
+ if (!hiddenCellMap.value[rowKey]) hiddenCellMap.value[rowKey] = new Set();
55
+ hiddenCellMap.value[rowKey].add(nextColKey);
48
56
 
49
- // if other row hovered, the rowspan cell need to be highlight
50
- if (!hoverRowMap.value[rowKey]) hoverRowMap.value[rowKey] = new Set();
51
- hoverRowMap.value[rowKey].add(mergeCellKey);
52
57
  }
53
58
  }
54
59
 
@@ -78,25 +83,24 @@ export function useMergeCells({ rowActiveProp, tableHeaderLast, rowKeyGen, colKe
78
83
 
79
84
  const rowKey = rowKeyGen(row);
80
85
 
81
- const colKey = colKeyGen.value(col);
82
- const curColIndex = tableHeaderLast.value.findIndex(item => colKeyGen.value(item) === colKey);
83
86
  const curRowIndex = virtual_dataSourcePart.value.findIndex(item => rowKeyGen(item) === rowKey);
84
- const mergedCellKey = pureCellKeyGen(rowKey, colKey);
85
-
86
87
  if (curRowIndex === -1) return;
87
88
 
89
+ const colKey = colKeyGen.value(col);
90
+ const mergedCellKey = pureCellKeyGen(rowKey, colKey);
91
+
88
92
  for (let i = curRowIndex; i < curRowIndex + rowspan; i++) {
89
93
  const row = virtual_dataSourcePart.value[i];
90
94
  if (!row) break;
91
- hideCells(rowKeyGen(row), curColIndex, colspan, i === curRowIndex, mergedCellKey);
95
+ hideCells(rowKeyGen(row), colKey, colspan, i === curRowIndex, mergedCellKey);
92
96
  }
93
97
 
94
98
  return { colspan, rowspan };
95
99
  }
96
100
 
101
+ const emptySet = new Set<string>();
97
102
  function updateHoverMergedCells(rowKey: UniqKey | undefined) {
98
- const set = rowKey === void 0 ? null : hoverRowMap.value[rowKey];
99
- hoverMergedCells.value = set || new Set();
103
+ hoverMergedCells.value = rowKey === void 0 ? emptySet : hoverRowMap.value[rowKey] || emptySet;
100
104
  }
101
105
 
102
106
  function updateActiveMergedCells(clear?: boolean, rowKey?: UniqKey) {
@@ -1,6 +1,6 @@
1
1
  import { ShallowRef } from 'vue';
2
- import { ExpandedRow, PrivateRowDT, RowKeyGen, StkTableColumn, UniqKey } from './types';
3
2
  import { EXPANDED_ROW_KEY_PREFIX } from './const';
3
+ import { PrivateRowDT, RowKeyGen, StkTableColumn, UniqKey } from './types';
4
4
  type DT = PrivateRowDT;
5
5
  type Option<DT extends Record<string, any>> = {
6
6
  rowKeyGen: RowKeyGen;
@@ -11,7 +11,7 @@ type Option<DT extends Record<string, any>> = {
11
11
  export function useRowExpand({ dataSourceCopy, rowKeyGen, emits }: Option<DT>) {
12
12
  const expandedKey = '__EXP__';
13
13
 
14
- function isExpanded(row: DT, col?: StkTableColumn<DT> | null) {
14
+ function isExpanded(row: DT, col?: StkTableColumn<DT>) {
15
15
  return row?.[expandedKey] === col ? !row?.[expandedKey] : true;
16
16
  }
17
17
  /** click expended icon to toggle expand row */
@@ -55,7 +55,7 @@ export function useRowExpand({ dataSourceCopy, rowKeyGen, emits }: Option<DT>) {
55
55
  }
56
56
 
57
57
  const row = tempData[index];
58
- const col = data?.col || null;
58
+ const col = data?.col;
59
59
 
60
60
  if (expand == null) {
61
61
  expand = isExpanded(row, col);
@@ -63,16 +63,16 @@ export function useRowExpand({ dataSourceCopy, rowKeyGen, emits }: Option<DT>) {
63
63
 
64
64
  if (expand) {
65
65
  // insert new expanded row
66
- const newExpandRow: ExpandedRow = {
66
+ const newExpandRow: PrivateRowDT = {
67
67
  __ROW_K__: EXPANDED_ROW_KEY_PREFIX + rowKey,
68
- __EXPANDED_ROW__: row,
69
- __EXPANDED_COL__: col,
68
+ __EXP_R__: row,
69
+ __EXP_C__: col,
70
70
  };
71
71
  tempData.splice(index + 1, 0, newExpandRow);
72
72
  }
73
73
 
74
74
  if (row) {
75
- row.__EXP__ = expand ? col : null;
75
+ row[expandedKey] = expand ? col : void 0;
76
76
  }
77
77
 
78
78
  dataSourceCopy.value = tempData;
@@ -11,7 +11,8 @@ type Option<DT extends Record<string, any>> = {
11
11
 
12
12
  export function useTree({ props, dataSourceCopy, rowKeyGen, emits }: Option<DT>) {
13
13
  const { defaultExpandAll, defaultExpandKeys, defaultExpandLevel }: TreeConfig = props.treeConfig;
14
-
14
+ /** It used to check if it is first load. To execute defaultExpandXXX */
15
+ let isFirstLoad = true;
15
16
  /** click expended icon to toggle expand row */
16
17
  function toggleTreeNode(row: DT, col: any) {
17
18
  const expand = row ? !row.__T_EXP__ : false;
@@ -82,38 +83,44 @@ export function useTree({ props, dataSourceCopy, rowKeyGen, emits }: Option<DT>)
82
83
  // }
83
84
  }
84
85
 
86
+ function recursionFlat(data: DT[] | undefined, level: number, parent?: DT): DT[] {
87
+ if (!data) return [];
88
+ let result: DT[] = []
89
+ for (let i = 0; i < data.length; i++) {
90
+ const item = data[i];
91
+ result.push(item);
92
+ const isExpanded = Boolean(item.__T_EXP__);
93
+ setNodeExpanded(item, isExpanded, level, parent);
94
+ if (isFirstLoad && !isExpanded) {
95
+ // first load will expand all node if defaultExpandAll is true
96
+ if (defaultExpandAll) {
97
+ setNodeExpanded(item, true);
98
+ } else {
99
+ if (defaultExpandLevel && level < defaultExpandLevel) {
100
+ setNodeExpanded(item, true);
101
+ }
102
+ if (defaultExpandKeys?.includes(rowKeyGen(item))) {
103
+ setNodeExpanded(item, true);
104
+ }
105
+ }
106
+ }
107
+ if (item.__T_EXP__) {
108
+ const res = recursionFlat(item.children, level + 1, item);
109
+ result = result.concat(res);
110
+ }
111
+ }
112
+ return result;
113
+ };
114
+
85
115
  /**
86
116
  * 根据保存的展开状态,深度遍历,展平树形数据。
117
+ * en: flatten tree data by saved expand state.
87
118
  * @param data
88
119
  * @returns
89
120
  */
90
121
  function flatTreeData(data: DT[]) {
91
- const result: DT[] = [];
92
- (function recursion(data: DT[] | undefined, level: number, parent?: DT) {
93
- if (!data) return;
94
- for (let i = 0; i < data.length; i++) {
95
- const item = data[i];
96
- result.push(item);
97
- const isExpanded = Boolean(item.__T_EXP__);
98
- setNodeExpanded(item, isExpanded, level, parent);
99
- if (!isExpanded) {
100
- if (defaultExpandAll) {
101
- setNodeExpanded(item, true);
102
- } else {
103
- if (defaultExpandLevel && level < defaultExpandLevel) {
104
- setNodeExpanded(item, true);
105
- }
106
- if (defaultExpandKeys?.includes(rowKeyGen(item))) {
107
- setNodeExpanded(item, true);
108
- }
109
- if (!item.__T_EXP__) {
110
- continue;
111
- }
112
- }
113
- }
114
- recursion(item.children, level + 1, item);
115
- }
116
- })(data, 0);
122
+ const result = recursionFlat(data, 0);
123
+ isFirstLoad = false;
117
124
  return result;
118
125
  }
119
126
 
@@ -1,15 +1,15 @@
1
1
  import { Ref, ShallowRef, computed, ref } from 'vue';
2
2
  import { DEFAULT_ROW_HEIGHT, DEFAULT_TABLE_HEIGHT, DEFAULT_TABLE_WIDTH } from './const';
3
- import { AutoRowHeightConfig, PrivateStkTableColumn, RowKeyGen, StkTableColumn, UniqKey } from './types';
3
+ import { AutoRowHeightConfig, PrivateRowDT, PrivateStkTableColumn, RowKeyGen, StkTableColumn, UniqKey } from './types';
4
4
  import { getCalculatedColWidth } from './utils/constRefUtils';
5
5
 
6
6
  type Option<DT extends Record<string, any>> = {
7
7
  props: any;
8
8
  tableContainerRef: Ref<HTMLElement | undefined>;
9
9
  trRef: Ref<HTMLTableRowElement[] | undefined>;
10
- dataSourceCopy: ShallowRef<DT[]>;
11
- tableHeaderLast: ShallowRef<PrivateStkTableColumn<DT>[]>;
12
- tableHeaders: ShallowRef<PrivateStkTableColumn<DT>[][]>;
10
+ dataSourceCopy: ShallowRef<PrivateRowDT[]>;
11
+ tableHeaderLast: ShallowRef<PrivateStkTableColumn<PrivateRowDT>[]>;
12
+ tableHeaders: ShallowRef<PrivateStkTableColumn<PrivateRowDT>[][]>;
13
13
  rowKeyGen: RowKeyGen;
14
14
  maxRowSpan: Map<UniqKey, number>;
15
15
  };
@@ -135,8 +135,8 @@ export function useVirtualScroll<DT extends Record<string, any>>({
135
135
  const tableHeaderLastValue = tableHeaderLast.value;
136
136
  if (virtualX_on.value) {
137
137
  // 虚拟横向滚动,固定列要一直保持存在
138
- const leftCols: PrivateStkTableColumn<DT>[] = [];
139
- const rightCols: PrivateStkTableColumn<DT>[] = [];
138
+ const leftCols: PrivateStkTableColumn<PrivateRowDT>[] = [];
139
+ const rightCols: PrivateStkTableColumn<PrivateRowDT>[] = [];
140
140
  /**
141
141
  * 存在问题:
142
142
  * table columns 从多到少时。比方原来的start=5,end=10,现在start=4,end=8。这时候endIndex就超出数组范围了。
@@ -176,15 +176,15 @@ export function useVirtualScroll<DT extends Record<string, any>>({
176
176
  });
177
177
 
178
178
  const getRowHeightFn = computed(() => {
179
- let rowHeightFn: (row?: DT) => number = () => props.rowHeight || DEFAULT_ROW_HEIGHT;
179
+ let rowHeightFn: (row?: PrivateRowDT) => number = () => props.rowHeight || DEFAULT_ROW_HEIGHT;
180
180
  if (props.autoRowHeight) {
181
181
  const tempRowHeightFn = rowHeightFn;
182
- rowHeightFn = (row?: DT) => getAutoRowHeight(row) || tempRowHeightFn(row);
182
+ rowHeightFn = (row?: PrivateRowDT) => getAutoRowHeight(row) || tempRowHeightFn(row);
183
183
  }
184
184
  if (hasExpandCol.value) {
185
185
  const expandedRowHeight = props.expandConfig?.height;
186
186
  const tempRowHeightFn = rowHeightFn;
187
- rowHeightFn = (row?: DT) => (row && row.__EXPANDED_ROW__ && expandedRowHeight) || tempRowHeightFn(row);
187
+ rowHeightFn = (row?: PrivateRowDT) => (row && row.__EXP_R__ && expandedRowHeight) || tempRowHeightFn(row);
188
188
  }
189
189
  return rowHeightFn;
190
190
  });
@@ -252,14 +252,14 @@ export function useVirtualScroll<DT extends Record<string, any>>({
252
252
  autoRowHeightMap.clear();
253
253
  }
254
254
 
255
- function getAutoRowHeight(row?: DT) {
255
+ function getAutoRowHeight(row?: PrivateRowDT) {
256
256
  if (!row) return;
257
257
  const rowKey = rowKeyGen(row);
258
258
  const storedHeight = autoRowHeightMap.get(String(rowKey));
259
259
  if (storedHeight) {
260
260
  return storedHeight;
261
261
  }
262
- const expectedHeight: AutoRowHeightConfig<DT>['expectedHeight'] = props.autoRowHeight?.expectedHeight;
262
+ const expectedHeight: AutoRowHeightConfig<PrivateRowDT>['expectedHeight'] = props.autoRowHeight?.expectedHeight;
263
263
  if (expectedHeight) {
264
264
  if (typeof expectedHeight === 'function') {
265
265
  return expectedHeight(row);