stk-table-vue 1.0.2 → 1.0.4

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.
package/README.md CHANGED
@@ -12,13 +12,26 @@
12
12
  </p>
13
13
  </p>
14
14
 
15
- Stk Table Vue(Sticky Table) is a high-performance virtual list component based on Vue.
16
-
17
- Smooth performance with tens of thousands of rows
18
-
19
- Used for real-time data display, with data highlighting and dynamic effects.
20
-
21
- Support Vue3 and Vue2.7
15
+ Stk Table Vue(Sticky Table) is a high-performance virtual scrolling table component based on Vue 3 / Vue 2.7.
16
+
17
+ Smooth performance with tens of thousands of rows. Designed for real-time data display with built-in highlighting and animation effects.
18
+
19
+ - Vue 3 & Vue 2.7 support
20
+ - Virtual scrolling (X & Y axis)
21
+ - CSS `sticky` based fixed columns & fixed header
22
+ - Multi-level header with horizontal virtual scroll
23
+ - Tree table & expandable rows
24
+ - Area selection with keyboard navigation
25
+ - Cell highlighting with Animation API
26
+ - Built-in custom cells: Filter, Editable, Checkbox, Number, Change
27
+ - Column resize, header drag, row drag
28
+ - Merge cells (virtual mode supported)
29
+ - Custom scrollbar
30
+ - Sortable & filterable
31
+ - Theme support (dark / light)
32
+ - CSS variables for easy customization
33
+ - Based on native `<table>` element
34
+ - Zero third-party runtime dependencies
22
35
 
23
36
 
24
37
  ## Documentation
@@ -172,5 +185,5 @@ const dataSource = [
172
185
  Compare performance with other vue table [vue-table-compare](https://github.com/ja-plus/vue-table-compare)
173
186
 
174
187
 
175
- ## Other
176
- * `$*$`
188
+ ## License
189
+ [MIT](LICENSE)
@@ -1,12 +1,12 @@
1
1
  /**
2
2
  * name: stk-table-vue
3
- * version: v1.0.2
3
+ * version: v1.0.4
4
4
  * description: High performance realtime virtual table for vue3 and vue2.7
5
5
  * author: japlus
6
6
  * homepage: https://ja-plus.github.io/stk-table-vue/
7
7
  * license: MIT
8
8
  */
9
- import { t as StkTable_default } from "./StkTable-Deyo4iqb.js";
9
+ import { t as StkTable_default } from "./StkTable-DuT_ezDm.js";
10
10
  import { createElementBlock, createElementVNode, createVNode, defineComponent, h, nextTick, normalizeClass, normalizeStyle, onMounted, onUnmounted, openBlock, reactive, ref, withModifiers } from "vue";
11
11
  //#region src/StkTable/custom-cells/FilterCell/Dropdown/index.vue?vue&type=script&setup=true&lang.ts
12
12
  var DROPDOWN_DEFAULT_WIDTH = 300;
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * name: stk-table-vue
3
- * version: v1.0.2
3
+ * version: v1.0.4
4
4
  * description: High performance realtime virtual table for vue3 and vue2.7
5
5
  * author: japlus
6
6
  * homepage: https://ja-plus.github.io/stk-table-vue/
@@ -2170,7 +2170,7 @@ function useRowExpand(emits, dataSourceCopy, rowKeyGen, onDataSourceChange) {
2170
2170
  */
2171
2171
  function setRowExpand(rowKeyOrRow, expand, data) {
2172
2172
  let rowKey;
2173
- if (typeof rowKeyOrRow === "string") rowKey = rowKeyOrRow;
2173
+ if (typeof rowKeyOrRow === "string" || typeof rowKeyOrRow === "number") rowKey = rowKeyOrRow;
2174
2174
  else rowKey = rowKeyGen(rowKeyOrRow);
2175
2175
  const tempData = dataSourceCopy.value.slice();
2176
2176
  const index = tempData.findIndex((it) => rowKeyGen(it) === rowKey);
@@ -2929,6 +2929,8 @@ function useTree(props, dataSourceCopy, rowKeyGen, emits, onDataSourceChange) {
2929
2929
  * @param row rowKey or row
2930
2930
  * @param option
2931
2931
  * @param option.expand expand or collapse
2932
+ * @param option.all expand all descendants
2933
+ * @param option.level expand to the nth level
2932
2934
  * @param option.silent if set true, not emit `toggle-tree-expand`, default:false
2933
2935
  */
2934
2936
  function privateSetTreeExpand(row, option) {
@@ -2937,7 +2939,7 @@ function useTree(props, dataSourceCopy, rowKeyGen, emits, onDataSourceChange) {
2937
2939
  for (let i = 0; i < rowKeyOrRowArr.length; i++) {
2938
2940
  const rowKeyOrRow = rowKeyOrRowArr[i];
2939
2941
  let rowKey;
2940
- if (typeof rowKeyOrRow === "string") rowKey = rowKeyOrRow;
2942
+ if (typeof rowKeyOrRow === "string" || typeof rowKeyOrRow === "number") rowKey = rowKeyOrRow;
2941
2943
  else rowKey = rowKeyGen(rowKeyOrRow);
2942
2944
  const index = tempData.findIndex((it) => rowKeyGen(it) === rowKey);
2943
2945
  if (index === -1) {
@@ -2946,12 +2948,22 @@ function useTree(props, dataSourceCopy, rowKeyGen, emits, onDataSourceChange) {
2946
2948
  }
2947
2949
  const row = tempData[index];
2948
2950
  const level = row.__T_LV__ || 0;
2951
+ const wasExpanded = Boolean(row.__T_EXP__);
2949
2952
  let expanded = option === null || option === void 0 ? void 0 : option.expand;
2950
2953
  if (expanded === void 0) expanded = !row.__T_EXP__;
2951
- if (expanded) {
2954
+ if (option.all || option.level !== void 0) {
2955
+ const targetLevel = option.all ? Infinity : option.level || 0;
2956
+ setDescendantsToLevel(row, level + 1, targetLevel, expanded);
2957
+ }
2958
+ if (expanded) if (wasExpanded) {
2959
+ const deleteCount = foldNode(index, tempData, level);
2952
2960
  const children = expandNode(row, level);
2953
- tempData.splice(index + 1, 0, ...children);
2961
+ tempData.splice(index + 1, deleteCount, ...children);
2954
2962
  } else {
2963
+ const children = expandNode(row, level);
2964
+ tempData.splice(index + 1, 0, ...children);
2965
+ }
2966
+ else {
2955
2967
  const deleteCount = foldNode(index, tempData, level);
2956
2968
  tempData.splice(index + 1, deleteCount);
2957
2969
  }
@@ -3006,6 +3018,17 @@ function useTree(props, dataSourceCopy, rowKeyGen, emits, onDataSourceChange) {
3006
3018
  isFirstLoad = false;
3007
3019
  return result;
3008
3020
  }
3021
+ /**
3022
+ * 递归设置目标节点后代到指定层级的展开/折叠状态
3023
+ * en: Recursively set expand/collapse state for descendants up to the target level
3024
+ */
3025
+ function setDescendantsToLevel(row, currentLevel, targetLevel, expanded) {
3026
+ if (!row.children || currentLevel > targetLevel) return;
3027
+ for (const child of row.children) {
3028
+ setNodeExpanded(child, expanded, currentLevel, row);
3029
+ setDescendantsToLevel(child, currentLevel + 1, targetLevel, expanded);
3030
+ }
3031
+ }
3009
3032
  function expandNode(row, level) {
3010
3033
  let result = [];
3011
3034
  row.children && row.children.forEach((child) => {
@@ -3575,33 +3598,34 @@ function useWheeling(resetDelay = 500) {
3575
3598
  var _hoisted_1 = ["tabindex"];
3576
3599
  var _hoisted_2 = { class: "stk-table-scroll-container" };
3577
3600
  var _hoisted_3 = { key: 0 };
3578
- var _hoisted_4 = ["onClick"];
3579
- var _hoisted_5 = ["onMousedown"];
3580
- var _hoisted_6 = { class: "table-header-title" };
3581
- var _hoisted_7 = ["onMousedown"];
3582
- var _hoisted_8 = ["colspan"];
3583
- var _hoisted_9 = ["title"];
3584
- var _hoisted_10 = { key: 0 };
3585
- var _hoisted_11 = ["colspan"];
3601
+ var _hoisted_4 = { key: 1 };
3602
+ var _hoisted_5 = ["onClick"];
3603
+ var _hoisted_6 = ["onMousedown"];
3604
+ var _hoisted_7 = { class: "table-header-title" };
3605
+ var _hoisted_8 = ["onMousedown"];
3606
+ var _hoisted_9 = ["colspan"];
3607
+ var _hoisted_10 = ["title"];
3608
+ var _hoisted_11 = { key: 0 };
3586
3609
  var _hoisted_12 = ["colspan"];
3587
- var _hoisted_13 = {
3610
+ var _hoisted_13 = ["colspan"];
3611
+ var _hoisted_14 = {
3588
3612
  class: "table-cell-wrapper",
3589
3613
  tabindex: "-1"
3590
3614
  };
3591
- var _hoisted_14 = {
3615
+ var _hoisted_15 = {
3592
3616
  key: 0,
3593
3617
  class: "vt-x-left"
3594
3618
  };
3595
- var _hoisted_15 = ["colspan"];
3596
- var _hoisted_16 = ["title"];
3597
- var _hoisted_17 = {
3619
+ var _hoisted_16 = ["colspan"];
3620
+ var _hoisted_17 = ["title"];
3621
+ var _hoisted_18 = {
3598
3622
  key: 2,
3599
3623
  class: "table-cell-wrapper",
3600
3624
  tabindex: "-1"
3601
3625
  };
3602
- var _hoisted_18 = ["title"];
3603
- var _hoisted_19 = { key: 2 };
3604
- var _hoisted_20 = {
3626
+ var _hoisted_19 = ["title"];
3627
+ var _hoisted_20 = { key: 2 };
3628
+ var _hoisted_21 = {
3605
3629
  key: 1,
3606
3630
  class: "vt-x-right"
3607
3631
  };
@@ -4075,6 +4099,15 @@ var StkTable_default = /* @__PURE__ */ defineComponent({
4075
4099
  [TagType.TF]: tfMap
4076
4100
  };
4077
4101
  });
4102
+ /**
4103
+ * fixed 模式下 colgroup 中单个 col 的样式。
4104
+ * 仅取叶子列的 width(与 cellStyleMap 中 --cw 保持一致);未设置 width 的列不声明宽度,
4105
+ * 由 table-layout:fixed 将剩余空间平分,符合“一列固定、其余列平分”的预期。
4106
+ */
4107
+ function getColGroupColStyle(col) {
4108
+ const width = transformWidthToStr(col.width);
4109
+ return width ? `width:${width}` : null;
4110
+ }
4078
4111
  function getAbsoluteRowIndex(rowIndex) {
4079
4112
  return rowIndex + virtualScroll.value.startIndex;
4080
4113
  }
@@ -4692,7 +4725,13 @@ var StkTable_default = /* @__PURE__ */ defineComponent({
4692
4725
  onContextmenu: onRowMenu,
4693
4726
  onMouseover: onTrMouseOver
4694
4727
  }, [
4695
- !__props.headless ? (openBlock(), createElementBlock("thead", _hoisted_3, [(openBlock(true), createElementBlock(Fragment, null, renderList(unref(virtualX_on) ? unref(virtualX_tableHeaders) : unref(tableHeaders), (row, rowIndex) => {
4728
+ props.fixedMode && !unref(virtualX_on) ? (openBlock(), createElementBlock("colgroup", _hoisted_3, [(openBlock(true), createElementBlock(Fragment, null, renderList(tableHeaderLast.value, (col) => {
4729
+ return openBlock(), createElementBlock("col", {
4730
+ key: colKeyGen.value(col),
4731
+ style: normalizeStyle(getColGroupColStyle(col))
4732
+ }, null, 4);
4733
+ }), 128))])) : createCommentVNode("", true),
4734
+ !__props.headless ? (openBlock(), createElementBlock("thead", _hoisted_4, [(openBlock(true), createElementBlock(Fragment, null, renderList(unref(virtualX_on) ? unref(virtualX_tableHeaders) : unref(tableHeaders), (row, rowIndex) => {
4696
4735
  return openBlock(), createElementBlock("tr", {
4697
4736
  key: rowIndex,
4698
4737
  onContextmenu: _cache[3] || (_cache[3] = ($event) => onHeaderMenu($event))
@@ -4713,7 +4752,7 @@ var StkTable_default = /* @__PURE__ */ defineComponent({
4713
4752
  key: 0,
4714
4753
  class: "table-header-resizer left",
4715
4754
  onMousedown: ($event) => unref(onThResizeMouseDown)($event, col, true)
4716
- }, null, 40, _hoisted_5)) : createCommentVNode("", true),
4755
+ }, null, 40, _hoisted_6)) : createCommentVNode("", true),
4717
4756
  createElementVNode("div", {
4718
4757
  class: "table-header-cell-wrapper",
4719
4758
  style: normalizeStyle(col.__R_SP__ ? `--row-span:${col.__R_SP__}` : null)
@@ -4729,7 +4768,7 @@ var StkTable_default = /* @__PURE__ */ defineComponent({
4729
4768
  ])) : renderSlot(_ctx.$slots, "tableHeader", {
4730
4769
  key: 1,
4731
4770
  col
4732
- }, () => [createElementVNode("span", _hoisted_6, toDisplayString(col.title), 1)]), col.sorter ? (openBlock(), createBlock(SortIcon_default, {
4771
+ }, () => [createElementVNode("span", _hoisted_7, toDisplayString(col.title), 1)]), col.sorter ? (openBlock(), createBlock(SortIcon_default, {
4733
4772
  key: 2,
4734
4773
  class: "table-header-sorter"
4735
4774
  })) : createCommentVNode("", true)], 4),
@@ -4737,8 +4776,8 @@ var StkTable_default = /* @__PURE__ */ defineComponent({
4737
4776
  key: 1,
4738
4777
  class: "table-header-resizer right",
4739
4778
  onMousedown: ($event) => unref(onThResizeMouseDown)($event, col)
4740
- }, null, 40, _hoisted_7)) : createCommentVNode("", true)
4741
- ], 16, _hoisted_4);
4779
+ }, null, 40, _hoisted_8)) : createCommentVNode("", true)
4780
+ ], 16, _hoisted_5);
4742
4781
  }), 128)),
4743
4782
  unref(virtualX_on) ? (openBlock(), createElementBlock("th", {
4744
4783
  key: 1,
@@ -4748,7 +4787,7 @@ var StkTable_default = /* @__PURE__ */ defineComponent({
4748
4787
  ], 32);
4749
4788
  }), 128))])) : createCommentVNode("", true),
4750
4789
  __props.footerData && __props.footerData.length > 0 ? (openBlock(), createBlock(resolveDynamicComponent(footerTagName.value), {
4751
- key: 1,
4790
+ key: 2,
4752
4791
  class: "stk-footer",
4753
4792
  style: normalizeStyle(isFooterTop.value ? `top:${unref(tableHeaderHeight)}px` : "")
4754
4793
  }, {
@@ -4764,7 +4803,7 @@ var StkTable_default = /* @__PURE__ */ defineComponent({
4764
4803
  key: 0,
4765
4804
  class: "vt-x-spacer",
4766
4805
  colspan: col.__VT_C_SP__
4767
- }, null, 8, _hoisted_8)) : (openBlock(), createElementBlock("td", mergeProps({
4806
+ }, null, 8, _hoisted_9)) : (openBlock(), createElementBlock("td", mergeProps({
4768
4807
  key: 1,
4769
4808
  ref_for: true
4770
4809
  }, getTFProps(col)), [col.customFooterCell ? (openBlock(), createBlock(resolveDynamicComponent(col.customFooterCell), {
@@ -4784,7 +4823,7 @@ var StkTable_default = /* @__PURE__ */ defineComponent({
4784
4823
  class: "table-cell-wrapper",
4785
4824
  tabindex: "-1",
4786
4825
  title: footRow[col.dataIndex] || ""
4787
- }, [footRow[col.dataIndex] != null ? (openBlock(), createElementBlock("span", _hoisted_10, toDisplayString(footRow[col.dataIndex]), 1)) : createCommentVNode("", true)], 8, _hoisted_9)], 16))], 64);
4826
+ }, [footRow[col.dataIndex] != null ? (openBlock(), createElementBlock("span", _hoisted_11, toDisplayString(footRow[col.dataIndex]), 1)) : createCommentVNode("", true)], 8, _hoisted_10)], 16))], 64);
4788
4827
  }), 128)),
4789
4828
  unref(virtualX_on) ? (openBlock(), createElementBlock("td", {
4790
4829
  key: 1,
@@ -4819,7 +4858,7 @@ var StkTable_default = /* @__PURE__ */ defineComponent({
4819
4858
  key: 0,
4820
4859
  class: "vt-x-spacer",
4821
4860
  colspan: col.__VT_C_SP__
4822
- }, null, 8, _hoisted_11)) : (openBlock(), createElementBlock("td", {
4861
+ }, null, 8, _hoisted_12)) : (openBlock(), createElementBlock("td", {
4823
4862
  key: 1,
4824
4863
  style: normalizeStyle(cellStyleMap.value[unref(TagType).TD].get(colKeyGen.value(col)))
4825
4864
  }, null, 4))], 64);
@@ -4839,17 +4878,17 @@ var StkTable_default = /* @__PURE__ */ defineComponent({
4839
4878
  }, { ref_for: true }, getTRProps(row, rowIndex)), [row && row.__EXP_R__ ? (openBlock(), createElementBlock("td", {
4840
4879
  key: 0,
4841
4880
  colspan: unref(expandRowColspan)
4842
- }, [createElementVNode("div", _hoisted_13, [renderSlot(_ctx.$slots, "expand", {
4881
+ }, [createElementVNode("div", _hoisted_14, [renderSlot(_ctx.$slots, "expand", {
4843
4882
  row: row.__EXP_R__,
4844
4883
  col: row.__EXP_C__
4845
- }, () => [createTextVNode(toDisplayString(row.__EXP_R__ && row.__EXP_C__ && row.__EXP_R__[row.__EXP_C__.dataIndex] || ""), 1)])])], 8, _hoisted_12)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
4846
- unref(virtualX_on) ? (openBlock(), createElementBlock("td", _hoisted_14)) : createCommentVNode("", true),
4884
+ }, () => [createTextVNode(toDisplayString(row.__EXP_R__ && row.__EXP_C__ && row.__EXP_R__[row.__EXP_C__.dataIndex] || ""), 1)])])], 8, _hoisted_13)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
4885
+ unref(virtualX_on) ? (openBlock(), createElementBlock("td", _hoisted_15)) : createCommentVNode("", true),
4847
4886
  (openBlock(true), createElementBlock(Fragment, null, renderList(unref(virtualX_columnPart), (col, _colIdx) => {
4848
4887
  return openBlock(), createElementBlock(Fragment, { key: col.__VT_C_SP__ ? `spacer-${_colIdx}` : colKeyGen.value(col) }, [col.__VT_C_SP__ ? (openBlock(), createElementBlock("td", {
4849
4888
  key: 0,
4850
4889
  class: "vt-x-spacer",
4851
4890
  colspan: col.__VT_C_SP__
4852
- }, null, 8, _hoisted_15)) : !shouldHideCell(row, col) ? (openBlock(), createElementBlock("td", mergeProps({
4891
+ }, null, 8, _hoisted_16)) : !shouldHideCell(row, col) ? (openBlock(), createElementBlock("td", mergeProps({
4853
4892
  key: 1,
4854
4893
  ref_for: true
4855
4894
  }, getTDProps(row, col, rowIndex, col.__LF_S__ ?? 0)), [col.customCell ? (openBlock(), createBlock(resolveDynamicComponent(col.customCell), {
@@ -4880,7 +4919,7 @@ var StkTable_default = /* @__PURE__ */ defineComponent({
4880
4919
  class: "table-cell-wrapper",
4881
4920
  tabindex: "-1",
4882
4921
  title: row[col.dataIndex] || ""
4883
- }, toDisplayString((row && row[col.dataIndex]) != null ? row && row[col.dataIndex] : getEmptyCellText.value(col, row)), 9, _hoisted_16)) : col.type === "seq" ? (openBlock(), createElementBlock("div", _hoisted_17, toDisplayString((props.seqConfig.startIndex || 0) + getAbsoluteRowIndex(rowIndex) + 1), 1)) : col.type === "tree-node" ? (openBlock(), createBlock(TreeNodeCell_default, {
4922
+ }, toDisplayString((row && row[col.dataIndex]) != null ? row && row[col.dataIndex] : getEmptyCellText.value(col, row)), 9, _hoisted_17)) : col.type === "seq" ? (openBlock(), createElementBlock("div", _hoisted_18, toDisplayString((props.seqConfig.startIndex || 0) + getAbsoluteRowIndex(rowIndex) + 1), 1)) : col.type === "tree-node" ? (openBlock(), createBlock(TreeNodeCell_default, {
4884
4923
  key: 3,
4885
4924
  class: "table-cell-wrapper",
4886
4925
  tabindex: "-1",
@@ -4894,9 +4933,9 @@ var StkTable_default = /* @__PURE__ */ defineComponent({
4894
4933
  }, [col.type === "dragRow" ? (openBlock(), createBlock(DragHandle_default, {
4895
4934
  key: 0,
4896
4935
  onDragstart: ($event) => unref(onTrDragStart)($event, getAbsoluteRowIndex(rowIndex))
4897
- }, null, 8, ["onDragstart"])) : col.type === "expand" ? (openBlock(), createBlock(TriangleIcon_default, { key: 1 })) : createCommentVNode("", true), row[col.dataIndex] != null ? (openBlock(), createElementBlock("span", _hoisted_19, toDisplayString(row[col.dataIndex]), 1)) : createCommentVNode("", true)], 8, _hoisted_18))], 16)) : createCommentVNode("", true)], 64);
4936
+ }, null, 8, ["onDragstart"])) : col.type === "expand" ? (openBlock(), createBlock(TriangleIcon_default, { key: 1 })) : createCommentVNode("", true), row[col.dataIndex] != null ? (openBlock(), createElementBlock("span", _hoisted_20, toDisplayString(row[col.dataIndex]), 1)) : createCommentVNode("", true)], 8, _hoisted_19))], 16)) : createCommentVNode("", true)], 64);
4898
4937
  }), 128)),
4899
- unref(virtualX_on) ? (openBlock(), createElementBlock("td", _hoisted_20)) : createCommentVNode("", true)
4938
+ unref(virtualX_on) ? (openBlock(), createElementBlock("td", _hoisted_21)) : createCommentVNode("", true)
4900
4939
  ], 64))], 16);
4901
4940
  }), 128)),
4902
4941
  !isExperimentalScrollY.value ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [unref(virtual_on) && !unref(isSRBRActive) ? (openBlock(), createElementBlock("tr", {
@@ -381,6 +381,8 @@ declare const _default: __VLS_WithTemplateSlots<import('vue').DefineComponent<im
381
381
  children?: (PrivateRowDT & /*elided*/ any)[];
382
382
  }))[], option?: {
383
383
  expand?: boolean;
384
+ all?: boolean;
385
+ level?: number;
384
386
  }) => void;
385
387
  /**
386
388
  * 获取拖选选中的单元格信息
@@ -4,7 +4,26 @@ import { PrivateRowDT, RowKeyGen, UniqKey } from './types';
4
4
  type DT = PrivateRowDT & {
5
5
  children?: DT[];
6
6
  };
7
- export declare function useTree(props: any, dataSourceCopy: ShallowRef<DT[]>, rowKeyGen: RowKeyGen, emits: any, onDataSourceChange: () => void): readonly [(row: DT, col: any) => void, (row: (UniqKey | DT) | (UniqKey | DT)[], option?: {
7
+ type SetTreeExpandOption = {
8
+ /**
9
+ * 是否展开
10
+ * en: Whether to expand
11
+ * @default false
12
+ */
8
13
  expand?: boolean;
9
- }) => void, (data: DT[]) => DT[]];
14
+ /**
15
+ * 是否展开所有子节点
16
+ * en: Whether to expand all child nodes
17
+ * @default false
18
+ * @version 1.0.4
19
+ */
20
+ all?: boolean;
21
+ /**
22
+ * 展开到第几层
23
+ * en: Expand to the nth level
24
+ * @version 1.0.4
25
+ */
26
+ level?: number;
27
+ };
28
+ export declare function useTree(props: any, dataSourceCopy: ShallowRef<DT[]>, rowKeyGen: RowKeyGen, emits: any, onDataSourceChange: () => void): readonly [(row: DT, col: any) => void, (row: (UniqKey | DT) | (UniqKey | DT)[], option?: SetTreeExpandOption) => void, (data: DT[]) => DT[]];
10
29
  export {};
@@ -1,12 +1,12 @@
1
1
  /**
2
2
  * name: stk-table-vue
3
- * version: v1.0.2
3
+ * version: v1.0.4
4
4
  * description: High performance realtime virtual table for vue3 and vue2.7
5
5
  * author: japlus
6
6
  * homepage: https://ja-plus.github.io/stk-table-vue/
7
7
  * license: MIT
8
8
  */
9
- import { a as insertToOrderedArray, i as binarySearch, n as registerFeature, o as strCompare, r as useAreaSelection, s as tableSort, t as StkTable_default } from "./StkTable-Deyo4iqb.js";
9
+ import { a as insertToOrderedArray, i as binarySearch, n as registerFeature, o as strCompare, r as useAreaSelection, s as tableSort, t as StkTable_default } from "./StkTable-DuT_ezDm.js";
10
10
  import { Fragment, computed, createApp, createBlock, createElementBlock, createElementVNode, createTextVNode, defineComponent, getCurrentInstance, h, markRaw, nextTick, normalizeClass, openBlock, ref, renderSlot, resolveDynamicComponent, toDisplayString, watch, withModifiers } from "vue";
11
11
  //#region src/StkTable/custom-cells/FilterCell/Dropdown/index.ts
12
12
  var DropdownIns = null;
@@ -15,7 +15,7 @@ async function getDropdownIns() {
15
15
  const div = document.createElement("div");
16
16
  div.classList.add("stk-filter-dropdown-wrapper");
17
17
  document.body.appendChild(div);
18
- DropdownIns = createApp(await import("./Dropdown-iW-rY3I6.js").then((module) => module.default)).mount(div);
18
+ DropdownIns = createApp(await import("./Dropdown-D7PIq_F7.js").then((module) => module.default)).mount(div);
19
19
  }
20
20
  return DropdownIns;
21
21
  }
package/lib/style.css CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * name: stk-table-vue
3
- * version: v1.0.2
3
+ * version: v1.0.4
4
4
  * description: High performance realtime virtual table for vue3 and vue2.7
5
5
  * author: japlus
6
6
  * homepage: https://ja-plus.github.io/stk-table-vue/
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stk-table-vue",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
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",
@@ -61,6 +61,11 @@
61
61
  @contextmenu="onRowMenu"
62
62
  @mouseover="onTrMouseOver"
63
63
  >
64
+ <!-- table-layout:fixed 下浏览器仅依据首行/colgroup 决定列宽,多级表头时子列宽度位于非首行会被忽略。
65
+ 故固定模式下通过 colgroup 显式声明每个叶子列宽度,保证子列 width 生效。 -->
66
+ <colgroup v-if="props.fixedMode && !virtualX_on">
67
+ <col v-for="col in tableHeaderLast" :key="colKeyGen(col)" :style="getColGroupColStyle(col)" />
68
+ </colgroup>
64
69
  <thead v-if="!headless">
65
70
  <tr
66
71
  v-for="(row, rowIndex) in virtualX_on ? virtualX_tableHeaders : tableHeaders"
@@ -1199,6 +1204,16 @@ const cellStyleMap = computed(() => {
1199
1204
  };
1200
1205
  });
1201
1206
 
1207
+ /**
1208
+ * fixed 模式下 colgroup 中单个 col 的样式。
1209
+ * 仅取叶子列的 width(与 cellStyleMap 中 --cw 保持一致);未设置 width 的列不声明宽度,
1210
+ * 由 table-layout:fixed 将剩余空间平分,符合“一列固定、其余列平分”的预期。
1211
+ */
1212
+ function getColGroupColStyle(col: PrivateStkTableColumn<DT>) {
1213
+ const width = transformWidthToStr(col.width);
1214
+ return width ? `width:${width}` : null;
1215
+ }
1216
+
1202
1217
  function getAbsoluteRowIndex(rowIndex: number) {
1203
1218
  return rowIndex + virtualScroll.value.startIndex;
1204
1219
  }
@@ -1,4 +1,4 @@
1
- import { ShallowRef, nextTick } from 'vue';
1
+ import { ShallowRef } from 'vue';
2
2
  import { EXPANDED_ROW_KEY_PREFIX } from './const';
3
3
  import { PrivateRowDT, RowKeyGen, StkTableColumn, UniqKey } from './types';
4
4
  type DT = PrivateRowDT;
@@ -24,7 +24,7 @@ export function useRowExpand(emits: any, dataSourceCopy: ShallowRef<DT[]>, rowKe
24
24
  */
25
25
  function setRowExpand(rowKeyOrRow: string | undefined | DT, expand?: boolean | null, data?: { col?: StkTableColumn<DT>; silent?: boolean }) {
26
26
  let rowKey: UniqKey;
27
- if (typeof rowKeyOrRow === 'string') {
27
+ if (typeof rowKeyOrRow === 'string' || typeof rowKeyOrRow === 'number') {
28
28
  rowKey = rowKeyOrRow;
29
29
  } else {
30
30
  rowKey = rowKeyGen(rowKeyOrRow);
@@ -1,8 +1,30 @@
1
- import { ShallowRef, nextTick } from 'vue';
1
+ import { ShallowRef } from 'vue';
2
2
  import { PrivateRowDT, RowKeyGen, TreeConfig, UniqKey } from './types';
3
3
 
4
4
  type DT = PrivateRowDT & { children?: DT[] };
5
5
 
6
+ type SetTreeExpandOption = {
7
+ /**
8
+ * 是否展开
9
+ * en: Whether to expand
10
+ * @default false
11
+ */
12
+ expand?: boolean;
13
+ /**
14
+ * 是否展开所有子节点
15
+ * en: Whether to expand all child nodes
16
+ * @default false
17
+ * @version 1.0.4
18
+ */
19
+ all?: boolean;
20
+ /**
21
+ * 展开到第几层
22
+ * en: Expand to the nth level
23
+ * @version 1.0.4
24
+ */
25
+ level?: number;
26
+ };
27
+
6
28
  export function useTree(props: any, dataSourceCopy: ShallowRef<DT[]>, rowKeyGen: RowKeyGen, emits: any, onDataSourceChange: () => void) {
7
29
  const { defaultExpandAll, defaultExpandKeys, defaultExpandLevel }: TreeConfig = props.treeConfig;
8
30
  /** It used to check if it is first load. To execute defaultExpandXXX */
@@ -18,16 +40,18 @@ export function useTree(props: any, dataSourceCopy: ShallowRef<DT[]>, rowKeyGen:
18
40
  * @param row rowKey or row
19
41
  * @param option
20
42
  * @param option.expand expand or collapse
43
+ * @param option.all expand all descendants
44
+ * @param option.level expand to the nth level
21
45
  * @param option.silent if set true, not emit `toggle-tree-expand`, default:false
22
46
  */
23
- function privateSetTreeExpand(row: (UniqKey | DT) | (UniqKey | DT)[], option: { expand?: boolean; col?: any; isClick: boolean }) {
47
+ function privateSetTreeExpand(row: (UniqKey | DT) | (UniqKey | DT)[], option: SetTreeExpandOption & { col?: any; isClick: boolean }) {
24
48
  const rowKeyOrRowArr: (UniqKey | DT)[] = Array.isArray(row) ? row : [row];
25
49
 
26
50
  const tempData = dataSourceCopy.value.slice();
27
51
  for (let i = 0; i < rowKeyOrRowArr.length; i++) {
28
52
  const rowKeyOrRow = rowKeyOrRowArr[i];
29
53
  let rowKey: UniqKey;
30
- if (typeof rowKeyOrRow === 'string') {
54
+ if (typeof rowKeyOrRow === 'string' || typeof rowKeyOrRow === 'number') {
31
55
  rowKey = rowKeyOrRow;
32
56
  } else {
33
57
  rowKey = rowKeyGen(rowKeyOrRow);
@@ -40,13 +64,26 @@ export function useTree(props: any, dataSourceCopy: ShallowRef<DT[]>, rowKeyGen:
40
64
 
41
65
  const row = tempData[index];
42
66
  const level = row.__T_LV__ || 0;
67
+ const wasExpanded = Boolean(row.__T_EXP__);
43
68
  let expanded = option?.expand;
44
69
  if (expanded === void 0) {
45
70
  expanded = !row.__T_EXP__;
46
71
  }
72
+ if (option.all || option.level !== void 0) {
73
+ const targetLevel = option.all ? Infinity : option.level || 0;
74
+ setDescendantsToLevel(row, level + 1, targetLevel, expanded);
75
+ }
47
76
  if (expanded) {
48
- const children = expandNode(row, level);
49
- tempData.splice(index + 1, 0, ...children);
77
+ if (wasExpanded) {
78
+ // already expanded, rebuild the flattened subtree so newly expanded
79
+ // descendants are inserted into the visible data source
80
+ const deleteCount = foldNode(index, tempData, level);
81
+ const children = expandNode(row, level);
82
+ tempData.splice(index + 1, deleteCount, ...children);
83
+ } else {
84
+ const children = expandNode(row, level);
85
+ tempData.splice(index + 1, 0, ...children);
86
+ }
50
87
  } else {
51
88
  // delete all child nodes from i
52
89
  const deleteCount = foldNode(index, tempData, level);
@@ -64,7 +101,7 @@ export function useTree(props: any, dataSourceCopy: ShallowRef<DT[]>, rowKeyGen:
64
101
  onDataSourceChange();
65
102
  }
66
103
 
67
- function setTreeExpand(row: (UniqKey | DT) | (UniqKey | DT)[], option?: { expand?: boolean }) {
104
+ function setTreeExpand(row: (UniqKey | DT) | (UniqKey | DT)[], option?: SetTreeExpandOption) {
68
105
  privateSetTreeExpand(row, { ...option, isClick: false });
69
106
  }
70
107
 
@@ -119,6 +156,18 @@ export function useTree(props: any, dataSourceCopy: ShallowRef<DT[]>, rowKeyGen:
119
156
  return result;
120
157
  }
121
158
 
159
+ /**
160
+ * 递归设置目标节点后代到指定层级的展开/折叠状态
161
+ * en: Recursively set expand/collapse state for descendants up to the target level
162
+ */
163
+ function setDescendantsToLevel(row: DT, currentLevel: number, targetLevel: number, expanded: boolean) {
164
+ if (!row.children || currentLevel > targetLevel) return;
165
+ for (const child of row.children) {
166
+ setNodeExpanded(child, expanded, currentLevel, row);
167
+ setDescendantsToLevel(child, currentLevel + 1, targetLevel, expanded);
168
+ }
169
+ }
170
+
122
171
  function expandNode(row: DT, level: number) {
123
172
  let result: DT[] = [];
124
173
  row.children &&