@deot/vc 1.0.70 → 1.0.71

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.
@@ -8089,16 +8089,6 @@
8089
8089
  };
8090
8090
  };
8091
8091
  curry$2.placeholder = curry$2;
8092
- var factory = (key) => (...funcs) => {
8093
- if (funcs.length === 0) return (arg) => arg;
8094
- if (funcs.length === 1) return funcs[0];
8095
- return funcs[key]((a, b) => {
8096
- return function(...args) {
8097
- return a.call(this, b.apply(this, args));
8098
- };
8099
- });
8100
- };
8101
- var compose = factory("reduce");
8102
8092
  var partial = (fn, ...partialArgs) => {
8103
8093
  return function(...nextArgs) {
8104
8094
  return fn.apply(this, mergeArgs(partialArgs, nextArgs, partial));
@@ -97189,7 +97179,7 @@ element.querySelector(thumbSelector);
97189
97179
  if (blot.parent == null || blot.parent.statics.blotName === "scroll" || blot.parent.statics.scope !== blot.statics.scope) return formats;
97190
97180
  return bubbleFormats(blot.parent, formats, filter);
97191
97181
  }
97192
- var import_Delta$11, NEWLINE_LENGTH, Block, BlockEmbed;
97182
+ var import_Delta$11, NEWLINE_LENGTH, Block$1, BlockEmbed;
97193
97183
  var init_block = __esmMin((() => {
97194
97184
  init_parchment();
97195
97185
  import_Delta$11 = /* @__PURE__ */ __toESM(require_Delta(), 1);
@@ -97197,7 +97187,7 @@ element.querySelector(thumbSelector);
97197
97187
  init_inline();
97198
97188
  init_text();
97199
97189
  NEWLINE_LENGTH = 1;
97200
- Block = class extends BlockBlot$1 {
97190
+ Block$1 = class extends BlockBlot$1 {
97201
97191
  cache = {};
97202
97192
  delta() {
97203
97193
  if (this.cache.delta == null) this.cache.delta = blockDelta(this);
@@ -97276,10 +97266,10 @@ element.querySelector(thumbSelector);
97276
97266
  return next;
97277
97267
  }
97278
97268
  };
97279
- Block.blotName = "block";
97280
- Block.tagName = "P";
97281
- Block.defaultChild = Break;
97282
- Block.allowedChildren = [
97269
+ Block$1.blotName = "block";
97270
+ Block$1.tagName = "P";
97271
+ Block$1.defaultChild = Break;
97272
+ Block$1.allowedChildren = [
97283
97273
  Break,
97284
97274
  Inline,
97285
97275
  EmbedBlot$1,
@@ -97311,7 +97301,7 @@ element.querySelector(thumbSelector);
97311
97301
  const lines = value.split("\n");
97312
97302
  const text = lines.pop();
97313
97303
  const blocks = lines.map((line) => {
97314
- const block = this.scroll.create(Block.blotName);
97304
+ const block = this.scroll.create(Block$1.blotName);
97315
97305
  block.insertAt(0, line);
97316
97306
  return block;
97317
97307
  });
@@ -97805,7 +97795,7 @@ element.querySelector(thumbSelector);
97805
97795
  }
97806
97796
  return parent.contains(descendant);
97807
97797
  }
97808
- var debug$4, Range, Selection;
97798
+ var debug$4, Range, Selection$1;
97809
97799
  var init_selection = __esmMin((() => {
97810
97800
  init_parchment();
97811
97801
  init_emitter();
@@ -97818,7 +97808,7 @@ element.querySelector(thumbSelector);
97818
97808
  this.length = length;
97819
97809
  }
97820
97810
  };
97821
- Selection = class {
97811
+ Selection$1 = class {
97822
97812
  constructor(scroll, emitter) {
97823
97813
  this.emitter = emitter;
97824
97814
  this.scroll = scroll;
@@ -98235,7 +98225,7 @@ element.querySelector(thumbSelector);
98235
98225
  this.scroll.insertAt(index, text);
98236
98226
  const [line, offset] = this.scroll.line(index);
98237
98227
  let formats = merge$1({}, bubbleFormats(line));
98238
- if (line instanceof Block) {
98228
+ if (line instanceof Block$1) {
98239
98229
  const [leaf] = line.descendant(LeafBlot$1, offset);
98240
98230
  if (leaf) formats = merge$1(formats, bubbleFormats(leaf));
98241
98231
  }
@@ -98329,7 +98319,7 @@ element.querySelector(thumbSelector);
98329
98319
  let leaves = [];
98330
98320
  if (length === 0) this.scroll.path(index).forEach((path) => {
98331
98321
  const [blot] = path;
98332
- if (blot instanceof Block) lines.push(blot);
98322
+ if (blot instanceof Block$1) lines.push(blot);
98333
98323
  else if (blot instanceof LeafBlot$1) leaves.push(blot);
98334
98324
  });
98335
98325
  else {
@@ -98387,7 +98377,7 @@ element.querySelector(thumbSelector);
98387
98377
  if (this.scroll.children.length === 0) return true;
98388
98378
  if (this.scroll.children.length > 1) return false;
98389
98379
  const blot = this.scroll.children.head;
98390
- if (blot?.statics.blotName !== Block.blotName) return false;
98380
+ if (blot?.statics.blotName !== Block$1.blotName) return false;
98391
98381
  const block = blot;
98392
98382
  if (block.children.length > 1) return false;
98393
98383
  return block.children.head instanceof Break;
@@ -98898,7 +98888,7 @@ element.querySelector(thumbSelector);
98898
98888
  if (!ScrollBlot || !("blotName" in ScrollBlot)) throw new Error(`Cannot initialize Quill without "${scrollBlotName}" blot`);
98899
98889
  this.scroll = new ScrollBlot(this.options.registry, this.root, { emitter: this.emitter });
98900
98890
  this.editor = new Editor$1(this.scroll);
98901
- this.selection = new Selection(this.scroll, this.emitter);
98891
+ this.selection = new Selection$1(this.scroll, this.emitter);
98902
98892
  this.composition = new Composition(this.scroll, this.emitter);
98903
98893
  this.theme = new this.options.theme(this, this.options);
98904
98894
  this.keyboard = this.theme.addModule("keyboard");
@@ -99181,7 +99171,7 @@ element.querySelector(thumbSelector);
99181
99171
  //#endregion
99182
99172
  //#region node_modules/.pnpm/quill@2.0.3/node_modules/quill/blots/scroll.js
99183
99173
  function isLine$1(blot) {
99184
- return blot instanceof Block || blot instanceof BlockEmbed;
99174
+ return blot instanceof Block$1 || blot instanceof BlockEmbed;
99185
99175
  }
99186
99176
  function isUpdatable(blot) {
99187
99177
  return typeof blot.updateContent === "function";
@@ -99226,9 +99216,9 @@ element.querySelector(thumbSelector);
99226
99216
  static blotName = "scroll";
99227
99217
  static className = "ql-editor";
99228
99218
  static tagName = "DIV";
99229
- static defaultChild = Block;
99219
+ static defaultChild = Block$1;
99230
99220
  static allowedChildren = [
99231
- Block,
99221
+ Block$1,
99232
99222
  BlockEmbed,
99233
99223
  Container$1
99234
99224
  ];
@@ -99540,7 +99530,7 @@ element.querySelector(thumbSelector);
99540
99530
  return `<pre>\n${escapeText(this.code(index, length))}\n</pre>`;
99541
99531
  }
99542
99532
  };
99543
- CodeBlock = class extends Block {
99533
+ CodeBlock = class extends Block$1 {
99544
99534
  static TAB = " ";
99545
99535
  static register() {
99546
99536
  Quill.register(CodeBlockContainer);
@@ -101047,7 +101037,7 @@ element.querySelector(thumbSelector);
101047
101037
  init_uiNode();
101048
101038
  init_module();
101049
101039
  Quill.register({
101050
- "blots/block": Block,
101040
+ "blots/block": Block$1,
101051
101041
  "blots/block/embed": BlockEmbed,
101052
101042
  "blots/break": Break,
101053
101043
  "blots/container": Container$1,
@@ -101109,7 +101099,7 @@ element.querySelector(thumbSelector);
101109
101099
  var Blockquote;
101110
101100
  var init_blockquote = __esmMin((() => {
101111
101101
  init_block();
101112
- Blockquote = class extends Block {
101102
+ Blockquote = class extends Block$1 {
101113
101103
  static blotName = "blockquote";
101114
101104
  static tagName = "blockquote";
101115
101105
  };
@@ -101119,7 +101109,7 @@ element.querySelector(thumbSelector);
101119
101109
  var Header;
101120
101110
  var init_header = __esmMin((() => {
101121
101111
  init_block();
101122
- Header = class extends Block {
101112
+ Header = class extends Block$1 {
101123
101113
  static blotName = "header";
101124
101114
  static tagName = [
101125
101115
  "H1",
@@ -101144,7 +101134,7 @@ element.querySelector(thumbSelector);
101144
101134
  ListContainer = class extends Container$1 {};
101145
101135
  ListContainer.blotName = "list-container";
101146
101136
  ListContainer.tagName = "OL";
101147
- ListItem = class extends Block {
101137
+ ListItem = class extends Block$1 {
101148
101138
  static create(value) {
101149
101139
  const node = super.create();
101150
101140
  node.setAttribute("data-list", value);
@@ -101698,7 +101688,7 @@ element.querySelector(thumbSelector);
101698
101688
  var init_table$1 = __esmMin((() => {
101699
101689
  init_block();
101700
101690
  init_container();
101701
- TableCell = class TableCell extends Block {
101691
+ TableCell = class TableCell extends Block$1 {
101702
101692
  static blotName = "table";
101703
101693
  static tagName = "TD";
101704
101694
  static create(value) {
@@ -108547,7 +108537,7 @@ ${p}
108547
108537
  }
108548
108538
  });
108549
108539
  /** @jsxImportSource vue */
108550
- var COMPONENT_NAME$136 = "vc-alert";
108540
+ var COMPONENT_NAME$137 = "vc-alert";
108551
108541
  var THEME_MAP = {
108552
108542
  info: [
108553
108543
  "#456CF6",
@@ -108571,7 +108561,7 @@ ${p}
108571
108561
  ]
108572
108562
  };
108573
108563
  var Alert = /* @__PURE__ */ (0, vue.defineComponent)({
108574
- name: COMPONENT_NAME$136,
108564
+ name: COMPONENT_NAME$137,
108575
108565
  props: props$93,
108576
108566
  setup(props, { slots, emit }) {
108577
108567
  const isActive = (0, vue.ref)(false);
@@ -110729,7 +110719,7 @@ ${p}
110729
110719
  return this.target.finally(callback);
110730
110720
  }
110731
110721
  };
110732
- var COMPONENT_NAME$120 = "vc-portal";
110722
+ var COMPONENT_NAME$121 = "vc-portal";
110733
110723
  var Portal = class Portal {
110734
110724
  /**
110735
110725
  * 清理Portals类型组件
@@ -110776,7 +110766,7 @@ ${p}
110776
110766
  this.wrapper = wrapper;
110777
110767
  this.globalOptions = {
110778
110768
  ...options,
110779
- name: options?.name || wrapper.name || getUid(COMPONENT_NAME$120)
110769
+ name: options?.name || wrapper.name || getUid(COMPONENT_NAME$121)
110780
110770
  };
110781
110771
  }
110782
110772
  popup(propsData, options) {
@@ -110835,7 +110825,7 @@ ${p}
110835
110825
  render(options, target, onFulfilled, onRejected) {
110836
110826
  const { el, tag, alive, aliveRegExp, aliveVisibleKey, aliveUpdateKey, name: name$, leaveDelay, autoDestroy, multiple, fragment, onDestroyed, onBeforeCreate, insertion, globalProperties, install, components, uses, slots, parent, propsData, ...rest } = options;
110837
110827
  let useAllNodes = fragment;
110838
- const name = multiple ? `${name$}__${getUid(COMPONENT_NAME$120)}` : name$;
110828
+ const name = multiple ? `${name$}__${getUid(COMPONENT_NAME$121)}` : name$;
110839
110829
  const container = document.createElement(tag);
110840
110830
  const root = typeof el === "object" ? el : document.querySelector(el || "body");
110841
110831
  !alive && Portal.leafs.get(name)?.destroy();
@@ -110867,7 +110857,7 @@ ${p}
110867
110857
  } else {
110868
110858
  const wrapper = this.wrapper;
110869
110859
  const app = (0, vue.createApp)({
110870
- name: COMPONENT_NAME$120,
110860
+ name: COMPONENT_NAME$121,
110871
110861
  parent,
110872
110862
  setup() {
110873
110863
  if (alive) {
@@ -114579,7 +114569,7 @@ ${p}
114579
114569
  }
114580
114570
  });
114581
114571
  /** @jsxImportSource vue */
114582
- var COMPONENT_NAME$95 = "vc-quarter-table";
114572
+ var COMPONENT_NAME$96 = "vc-quarter-table";
114583
114573
  /**
114584
114574
  * 获取季度对应的月份范围
114585
114575
  * @param panelDate ~
@@ -114606,7 +114596,7 @@ ${p}
114606
114596
  }
114607
114597
  };
114608
114598
  var QuarterTable = /* @__PURE__ */ (0, vue.defineComponent)({
114609
- name: COMPONENT_NAME$95,
114599
+ name: COMPONENT_NAME$96,
114610
114600
  props: {
114611
114601
  value: Array,
114612
114602
  panelDate: Date,
@@ -116061,14 +116051,14 @@ ${p}
116061
116051
  }
116062
116052
  });
116063
116053
  /** @jsxImportSource vue */
116064
- var COMPONENT_NAME$85 = "vc-date-picker";
116054
+ var COMPONENT_NAME$86 = "vc-date-picker";
116065
116055
  var getPanel$1 = (type) => {
116066
116056
  if (["daterange", "datetimerange"].includes(type)) return DateRangePanel;
116067
116057
  else if (type === "quarterrange") return QuarterRangePanel;
116068
116058
  else if (type === "monthrange") return MonthRangePanel;
116069
116059
  return DatePanel;
116070
116060
  };
116071
- var DatePicker = createPicker(COMPONENT_NAME$85, props$60, () => {
116061
+ var DatePicker = createPicker(COMPONENT_NAME$86, props$60, () => {
116072
116062
  const props = (0, vue.getCurrentInstance)().props;
116073
116063
  const icon = (0, vue.ref)("date");
116074
116064
  const panel = (0, vue.shallowRef)({});
@@ -116381,7 +116371,7 @@ ${p}
116381
116371
  ])
116382
116372
  };
116383
116373
  /** @jsxImportSource vue */
116384
- var COMPONENT_NAME$82 = "vc-scroller-track";
116374
+ var COMPONENT_NAME$83 = "vc-scroller-track";
116385
116375
  var BAR_MAP = {
116386
116376
  vertical: {
116387
116377
  scroll: "scrollTop",
@@ -116401,7 +116391,7 @@ ${p}
116401
116391
  }
116402
116392
  };
116403
116393
  var Track = /* @__PURE__ */ (0, vue.defineComponent)({
116404
- name: COMPONENT_NAME$82,
116394
+ name: COMPONENT_NAME$83,
116405
116395
  props: props$55,
116406
116396
  emits: ["change"],
116407
116397
  inheritAttrs: false,
@@ -118399,7 +118389,7 @@ ${p}
118399
118389
  }
118400
118390
  });
118401
118391
  /** @jsxImportSource vue */
118402
- var COMPONENT_NAME$70 = "vc-editor-view";
118392
+ var COMPONENT_NAME$71 = "vc-editor-view";
118403
118393
  var setImages = (v) => {
118404
118394
  if (!v) return;
118405
118395
  const IMG_REGX = /<img.*?(?:>|\/>)/gi;
@@ -118415,7 +118405,7 @@ ${p}
118415
118405
  }
118416
118406
  };
118417
118407
  var EditorView = /* @__PURE__ */ (0, vue.defineComponent)({
118418
- name: COMPONENT_NAME$70,
118408
+ name: COMPONENT_NAME$71,
118419
118409
  props: {
118420
118410
  value: {
118421
118411
  type: String,
@@ -119199,7 +119189,7 @@ ${p}
119199
119189
  };
119200
119190
  var store_default = new IMGStore();
119201
119191
  /** @jsxImportSource vue */
119202
- var COMPONENT_NAME$63 = "vc-image";
119192
+ var COMPONENT_NAME$64 = "vc-image";
119203
119193
  var isSupportObjectFit = false;
119204
119194
  window.addEventListener("DOMContentLoaded", () => {
119205
119195
  isSupportObjectFit = !IS_SERVER$3 && document.documentElement.style.objectFit !== void 0;
@@ -119212,7 +119202,7 @@ ${p}
119212
119202
  SCALE_DOWN: "scale-down"
119213
119203
  };
119214
119204
  var Image$1 = /* @__PURE__ */ (0, vue.defineComponent)({
119215
- name: COMPONENT_NAME$63,
119205
+ name: COMPONENT_NAME$64,
119216
119206
  inheritAttrs: false,
119217
119207
  props: props$42,
119218
119208
  setup(props, { slots, emit }) {
@@ -119632,10 +119622,10 @@ ${p}
119632
119622
  alone: Boolean
119633
119623
  };
119634
119624
  /** @jsxImportSource vue */
119635
- var COMPONENT_NAME$56 = "vcm-list-item";
119625
+ var COMPONENT_NAME$57 = "vcm-list-item";
119636
119626
  var HTTP_REGEX = /[a-zA-z]+:\/\/[^\s]*/;
119637
119627
  var MListItem = /* @__PURE__ */ (0, vue.defineComponent)({
119638
- name: COMPONENT_NAME$56,
119628
+ name: COMPONENT_NAME$57,
119639
119629
  props: props$38,
119640
119630
  emits: ["click"],
119641
119631
  setup(props, { slots, emit }) {
@@ -119705,11 +119695,11 @@ ${p}
119705
119695
  }
119706
119696
  };
119707
119697
  /** @jsxImportSource vue */
119708
- var COMPONENT_NAME$55 = "vc-marquee";
119698
+ var COMPONENT_NAME$56 = "vc-marquee";
119709
119699
  var ANIMATION = prefixStyle("animation").camel;
119710
119700
  var TRANSFORM_KEBAB = prefixStyle("transform").kebab;
119711
119701
  var Marquee = /* @__PURE__ */ (0, vue.defineComponent)({
119712
- name: COMPONENT_NAME$55,
119702
+ name: COMPONENT_NAME$56,
119713
119703
  props: props$37,
119714
119704
  setup(props, { slots }) {
119715
119705
  const instance = (0, vue.getCurrentInstance)();
@@ -119913,10 +119903,10 @@ ${p}
119913
119903
  onCancel: { type: Function }
119914
119904
  };
119915
119905
  /** @jsxImportSource vue */
119916
- var COMPONENT_NAME$53 = "vc-modal";
119906
+ var COMPONENT_NAME$54 = "vc-modal";
119917
119907
  var zIndexNumber = 1002;
119918
119908
  var ModalView = /* @__PURE__ */ (0, vue.defineComponent)({
119919
- name: COMPONENT_NAME$53,
119909
+ name: COMPONENT_NAME$54,
119920
119910
  emits: [
119921
119911
  "update:modelValue",
119922
119912
  "close",
@@ -122399,10 +122389,10 @@ ${p}
122399
122389
  return keys;
122400
122390
  };
122401
122391
  /** @jsxImportSource vue */
122402
- var COMPONENT_NAME$29 = "vc-recycle-list-container";
122392
+ var COMPONENT_NAME$30 = "vc-recycle-list-container";
122403
122393
  var transformKey = prefixStyle("transform").camel;
122404
122394
  var Container = /* @__PURE__ */ (0, vue.defineComponent)({
122405
- name: COMPONENT_NAME$29,
122395
+ name: COMPONENT_NAME$30,
122406
122396
  props: props$18,
122407
122397
  emits: ["refresh"],
122408
122398
  setup(props, { slots }) {
@@ -123330,15 +123320,28 @@ ${p}
123330
123320
  let v1;
123331
123321
  if (typeof v !== "undefined") {
123332
123322
  v1 = parseWidth(v);
123333
- if (isNaN(v1)) v = 80;
123323
+ if (isNaN(v1)) v1 = 80;
123334
123324
  }
123335
123325
  return v1;
123336
123326
  };
123337
123327
  /**
123328
+ * 由叶子列生成 CSS Grid 的 grid-template-columns 值。
123329
+ * 最后一列 minmax 兜底,容器更宽时由其撑满。
123330
+ * @param columns 叶子列
123331
+ * @returns 模板值
123332
+ */
123333
+ var computeGridTemplateColumns = (columns = []) => {
123334
+ return columns.map((column, index) => {
123335
+ const { states } = column;
123336
+ const width = states.realWidth || states.width || 80;
123337
+ return index === columns.length - 1 ? `minmax(${width}px, 1fr)` : `${width}px`;
123338
+ }).join(" ");
123339
+ };
123340
+ /**
123338
123341
  * 行 -> 唯一key
123339
- * @param row ~
123340
- * @param primaryKey ~
123341
- * @returns ~
123342
+ * @param row 表格行数据
123343
+ * @param primaryKey 行主键字段名或取值函数
123344
+ * @returns 行的唯一标识值
123342
123345
  */
123343
123346
  var getRowValue = (row, primaryKey) => {
123344
123347
  if (row.__KEY__) return row.__KEY__;
@@ -123368,81 +123371,18 @@ ${p}
123368
123371
  return arrayMap;
123369
123372
  };
123370
123373
  /**
123371
- * ~
123372
- * @param columns ~
123373
- * @param columnId ~
123374
- * @returns ~
123375
- */
123376
- var getColumnById = (columns, columnId) => {
123377
- let column = null;
123378
- columns.forEach((item) => {
123379
- if (item.id === columnId) column = item;
123380
- });
123381
- return column;
123382
- };
123383
- /**
123384
- * ~
123385
- * @param columns ~
123386
- * @param cell ~
123387
- * @returns ~
123374
+ * 展开列树为叶子列节点数组
123375
+ * @param nodes 列树
123376
+ * @returns 叶子列节点
123388
123377
  */
123389
- var getColumnByCell = (columns, cell) => {
123390
- const matches = (cell.className || "").match(/vc-table_[^\s]+/gm);
123391
- if (matches) return getColumnById(columns, matches[0]);
123392
- return null;
123393
- };
123394
- /**
123395
- * ~
123396
- * @param e ~
123397
- * @returns ~
123398
- */
123399
- var getCell = (e) => {
123400
- let cell = e.target;
123401
- while (cell && cell.tagName.toUpperCase() !== "HTML") {
123402
- if (cell.classList.contains("vc-table__td")) return cell;
123403
- cell = cell.parentNode;
123404
- }
123405
- return null;
123406
- };
123407
- var getAllColumns = (columns) => {
123378
+ var flattenColumnNodes = (nodes) => {
123408
123379
  const result = [];
123409
- columns.forEach((column) => {
123410
- if (column.children) {
123411
- result.push(column);
123412
- result.push(...getAllColumns(column.children));
123413
- } else result.push(column);
123380
+ nodes.forEach((node) => {
123381
+ if (node.childNodes.length) result.push(...flattenColumnNodes(node.childNodes));
123382
+ else result.push(node);
123414
123383
  });
123415
123384
  return result;
123416
123385
  };
123417
- var columnsToRowsEffect = (v) => {
123418
- let maxLevel = 1;
123419
- const traverse = (column, parent) => {
123420
- if (parent) {
123421
- column.level = parent.level + 1;
123422
- if (maxLevel < column.level) maxLevel = column.level;
123423
- }
123424
- if (column.children) {
123425
- let colspan = 0;
123426
- column.children.forEach((subColumn) => {
123427
- traverse(subColumn, column);
123428
- colspan += subColumn.colspan;
123429
- });
123430
- column.colspan = colspan;
123431
- } else column.colspan = 1;
123432
- };
123433
- v.forEach((column) => {
123434
- column.level = 1;
123435
- traverse(column);
123436
- });
123437
- const rows = [];
123438
- for (let i = 0; i < maxLevel; i++) rows.push([]);
123439
- getAllColumns(v).forEach((column) => {
123440
- if (!column.children) column.rowspan = maxLevel - column.level + 1;
123441
- else column.rowspan = 1;
123442
- rows[column.level - 1].push(column);
123443
- });
123444
- return rows;
123445
- };
123446
123386
  var flattenData = (data, opts = {}) => {
123447
123387
  const result = [];
123448
123388
  data.forEach((item) => {
@@ -123488,6 +123428,34 @@ ${p}
123488
123428
  if (!isNil(children)) _walker(item, children, baseLevel);
123489
123429
  });
123490
123430
  };
123431
+ /**
123432
+ * 存在副作用
123433
+ * 对 statusArr 做添加和删除的操作
123434
+ * @param statusArr 状态数组(如 selection / expandRows)
123435
+ * @param row 目标行数据
123436
+ * @param newVal 指定展开/选中与否;省略时切换
123437
+ * @param batch 为 true 时,使用 delete(批处理使用 splice 性能差,使用 delete 后统一再处理)
123438
+ * @returns 是否发生变更
123439
+ */
123440
+ var toggleRowStatus = (statusArr, row, newVal, batch = false) => {
123441
+ let changed = false;
123442
+ const index = statusArr.indexOf(row);
123443
+ const included = index !== -1;
123444
+ const addRow = () => {
123445
+ statusArr.push(row);
123446
+ changed = true;
123447
+ };
123448
+ const removeRow = () => {
123449
+ if (!batch) statusArr.splice(index, 1);
123450
+ else delete statusArr[index];
123451
+ changed = true;
123452
+ };
123453
+ if (typeof newVal === "boolean") {
123454
+ if (newVal && !included) addRow();
123455
+ else if (!newVal && included) removeRow();
123456
+ } else included ? removeRow() : addRow();
123457
+ return changed;
123458
+ };
123491
123459
  var BaseWatcher = class {
123492
123460
  states = (0, vue.reactive)({
123493
123461
  _data: [],
@@ -123516,16 +123484,400 @@ ${p}
123516
123484
  treeLazyColumnIdentifier: "hasChildren",
123517
123485
  treeChildrenColumnName: "children",
123518
123486
  isComplex: (0, vue.computed)(() => this.states.leftFixedColumns.length > 0 || this.states.rightFixedColumns.length > 0),
123487
+ hasMergeCells: (0, vue.computed)(() => this.states.list.some((item) => !!item.cells)),
123519
123488
  isGroup: (0, vue.computed)(() => this.states.columns.length > this.states.originColumns.length),
123520
- columns: (0, vue.computed)(() => concat(this.states.leftFixedLeafColumns, this.states.leafColumns, this.states.rightFixedLeafColumns)),
123521
- leafColumns: (0, vue.computed)(() => flattenData(this.states.notFixedColumns)),
123522
- leftFixedLeafColumns: (0, vue.computed)(() => flattenData(this.states.leftFixedColumns)),
123523
- rightFixedLeafColumns: (0, vue.computed)(() => flattenData(this.states.rightFixedColumns)),
123489
+ columns: (0, vue.computed)(() => {
123490
+ return concat(this.states.leftFixedLeafColumns, this.states.leafColumns, this.states.rightFixedLeafColumns);
123491
+ }),
123492
+ leafColumns: (0, vue.computed)(() => flattenColumnNodes(this.states.notFixedColumns)),
123493
+ leftFixedLeafColumns: (0, vue.computed)(() => flattenColumnNodes(this.states.leftFixedColumns)),
123494
+ rightFixedLeafColumns: (0, vue.computed)(() => flattenColumnNodes(this.states.rightFixedColumns)),
123524
123495
  leafColumnsLength: (0, vue.computed)(() => this.states.leafColumns.length),
123525
123496
  leftFixedLeafColumnsLength: (0, vue.computed)(() => this.states.leftFixedLeafColumns.length),
123526
123497
  rightFixedLeafColumnsLength: (0, vue.computed)(() => this.states.rightFixedLeafColumns.length)
123527
123498
  });
123528
123499
  };
123500
+ /**
123501
+ * 归一化 getSpan 的返回值:[rowspan, colspan] | { rowspan, colspan } -> { rowspan, colspan }
123502
+ * @param v getSpan 返回值
123503
+ * @returns 归一化后的 rowspan / colspan
123504
+ */
123505
+ var normalizeSpan = (v) => {
123506
+ if (Array.isArray(v)) return {
123507
+ rowspan: v[0] ?? 1,
123508
+ colspan: v[1] ?? 1
123509
+ };
123510
+ if (v && typeof v === "object") return {
123511
+ rowspan: v.rowspan ?? 1,
123512
+ colspan: v.colspan ?? 1
123513
+ };
123514
+ return {
123515
+ rowspan: 1,
123516
+ colspan: 1
123517
+ };
123518
+ };
123519
+ /**
123520
+ * 基于 getSpan 预求值合并信息,产出"合并计划":
123521
+ * - 以"行方向连续合并块"为最小单位切块(与虚拟化语义保持一致,块即 RecycleList 的最小渲染单位);
123522
+ * - 含合并的块附带 cells[](坐标 + span 的一维数组,被覆盖的格子已剔除),交给 TableGrid 渲染;
123523
+ * - 不含合并的块 cells 为空,渲染层按行合成 1×1 cells;
123524
+ * - covers: rowIndex -> 覆盖该行的合并 anchor 坐标(rowspan > 1,不含 anchor 本行),供 hover 关联高亮。
123525
+ * @param data 当前数据(外部已完成排序/过滤)
123526
+ * @param columns 叶子列
123527
+ * @param getSpan ({ row, column, rowIndex, columnIndex }) => [rowspan, colspan] | { rowspan, colspan }
123528
+ * @returns 合并计划,形如 { blocks: [{ start, end, cells? }], covers }
123529
+ */
123530
+ var computeMergePlan = (data, columns, getSpan) => {
123531
+ const rowCount = data.length;
123532
+ const columnCount = columns.length;
123533
+ let spans = null;
123534
+ let skip = null;
123535
+ let reach = null;
123536
+ for (let r = 0; r < rowCount; r++) for (let c = 0; c < columnCount; c++) {
123537
+ const key = r * columnCount + c;
123538
+ if (skip && skip.has(key)) continue;
123539
+ const v = normalizeSpan(getSpan({
123540
+ row: data[r],
123541
+ column: columns[c].states,
123542
+ rowIndex: r,
123543
+ columnIndex: c
123544
+ }));
123545
+ if (v.rowspan === 1 && v.colspan === 1) continue;
123546
+ if (!spans) {
123547
+ spans = /* @__PURE__ */ new Map();
123548
+ skip = /* @__PURE__ */ new Set();
123549
+ reach = Array.from({ length: rowCount }, (_, i) => i);
123550
+ }
123551
+ if (v.rowspan < 1 || v.colspan < 1) {
123552
+ skip.add(key);
123553
+ continue;
123554
+ }
123555
+ const rowspan = Math.min(v.rowspan, rowCount - r);
123556
+ const colspan = Math.min(v.colspan, columnCount - c);
123557
+ if (rowspan === 1 && colspan === 1) continue;
123558
+ spans.set(key, {
123559
+ rowspan,
123560
+ colspan
123561
+ });
123562
+ for (let i = r; i < r + rowspan; i++) for (let j = c; j < c + colspan; j++) {
123563
+ if (i === r && j === c) continue;
123564
+ skip.add(i * columnCount + j);
123565
+ }
123566
+ reach[r] = Math.max(reach[r], r + rowspan - 1);
123567
+ }
123568
+ if (!spans) {
123569
+ const blocks = new Array(rowCount);
123570
+ for (let r = 0; r < rowCount; r++) blocks[r] = {
123571
+ start: r,
123572
+ end: r
123573
+ };
123574
+ return {
123575
+ blocks,
123576
+ covers: null
123577
+ };
123578
+ }
123579
+ const blocks = [];
123580
+ let start = 0;
123581
+ let end = 0;
123582
+ for (let r = 0; r < rowCount; r++) {
123583
+ end = Math.max(end, reach[r]);
123584
+ if (r === end) {
123585
+ blocks.push({
123586
+ start,
123587
+ end
123588
+ });
123589
+ start = r + 1;
123590
+ end = r + 1;
123591
+ }
123592
+ }
123593
+ blocks.forEach((block) => {
123594
+ let hasMerge = block.end > block.start;
123595
+ const cells = [];
123596
+ for (let r = block.start; r <= block.end; r++) for (let c = 0; c < columnCount; c++) {
123597
+ const key = r * columnCount + c;
123598
+ if (skip.has(key)) {
123599
+ hasMerge = true;
123600
+ continue;
123601
+ }
123602
+ const span = spans.get(key);
123603
+ if (span) hasMerge = true;
123604
+ cells.push({
123605
+ rowIndex: r,
123606
+ columnIndex: c,
123607
+ rowspan: span?.rowspan || 1,
123608
+ colspan: span?.colspan || 1
123609
+ });
123610
+ }
123611
+ if (hasMerge) block.cells = cells;
123612
+ });
123613
+ const covers = /* @__PURE__ */ new Map();
123614
+ spans.forEach((span, key) => {
123615
+ if (span.rowspan <= 1) return;
123616
+ const r = Math.floor(key / columnCount);
123617
+ const c = key % columnCount;
123618
+ for (let i = r + 1; i < r + span.rowspan; i++) {
123619
+ let anchors = covers.get(i);
123620
+ if (!anchors) covers.set(i, anchors = []);
123621
+ anchors.push({
123622
+ rowIndex: r,
123623
+ columnIndex: c
123624
+ });
123625
+ }
123626
+ });
123627
+ return {
123628
+ blocks,
123629
+ covers: covers.size ? covers : null
123630
+ };
123631
+ };
123632
+ /**
123633
+ * 虚拟化块编排:list 构建、getSpan 合并计划缓存与 list 重组。
123634
+ */
123635
+ var Block = class {
123636
+ store;
123637
+ _cache = {
123638
+ data: null,
123639
+ length: 0,
123640
+ columnsKey: "",
123641
+ getSpan: null,
123642
+ plan: null
123643
+ };
123644
+ constructor(store) {
123645
+ this.store = store;
123646
+ }
123647
+ buildInitialList(data) {
123648
+ const { primaryKey } = this.store.table.props;
123649
+ return data.map((row, index) => {
123650
+ const id = primaryKey ? getRowValue(row, primaryKey) : index;
123651
+ return {
123652
+ id: typeof id === "undefined" ? index : id,
123653
+ rows: [{
123654
+ index,
123655
+ data: row
123656
+ }],
123657
+ rowStart: index,
123658
+ expand: false
123659
+ };
123660
+ });
123661
+ }
123662
+ /**
123663
+ * 按 getSpan 合并计划重组 states.list:为合并块生成 cells,并写入 rowStart。
123664
+ * 只有存在合并时,才全量构建cells, 主要目的是一个block内含多少个row数据;(性能后续再优化)
123665
+ */
123666
+ rebuildMergeList() {
123667
+ const { getSpan, primaryKey } = this.store.table.props;
123668
+ const { data, columns, list } = this.store.states;
123669
+ if (typeof getSpan !== "function" || !data.length || !columns.length) return;
123670
+ const columnsKey = columns.map((column) => column.states.id).join(",");
123671
+ const cache = this._cache;
123672
+ let plan = cache.plan;
123673
+ if (!plan || cache.data !== data || cache.length !== data.length || cache.columnsKey !== columnsKey || cache.getSpan !== getSpan) {
123674
+ plan = computeMergePlan(data, columns, getSpan);
123675
+ this._cache = {
123676
+ data,
123677
+ length: data.length,
123678
+ columnsKey,
123679
+ getSpan,
123680
+ plan
123681
+ };
123682
+ }
123683
+ const flatRows = list.reduce((pre, block) => (pre.push(...block.rows), pre), []);
123684
+ if (flatRows.length !== data.length) return;
123685
+ this.store.states.list = plan.blocks.map((block) => {
123686
+ const rows = flatRows.slice(block.start, block.end + 1);
123687
+ const id = primaryKey ? rows.map((row) => getRowValue(row.data, primaryKey)).join(",") : block.start;
123688
+ return {
123689
+ id: typeof id === "undefined" ? block.start : id,
123690
+ rows,
123691
+ expand: false,
123692
+ cells: block.cells,
123693
+ rowStart: block.start
123694
+ };
123695
+ });
123696
+ }
123697
+ getCoverAnchors(rowIndex) {
123698
+ return this._cache.plan?.covers?.get(rowIndex) || [];
123699
+ }
123700
+ };
123701
+ var getAllColumns = (columns) => {
123702
+ const result = [];
123703
+ columns.forEach((column) => {
123704
+ if (column.childNodes.length) {
123705
+ result.push(column);
123706
+ result.push(...getAllColumns(column.childNodes));
123707
+ } else result.push(column);
123708
+ });
123709
+ return result;
123710
+ };
123711
+ var columnsToRowsEffect = (v) => {
123712
+ let maxLevel = 1;
123713
+ const traverse = (column, parent) => {
123714
+ if (parent) {
123715
+ column.states.level = parent.states.level + 1;
123716
+ if (maxLevel < column.states.level) maxLevel = column.states.level;
123717
+ }
123718
+ if (column.childNodes.length) {
123719
+ let colspan = 0;
123720
+ column.childNodes.forEach((subColumn) => {
123721
+ traverse(subColumn, column);
123722
+ colspan += subColumn.states.colspan;
123723
+ });
123724
+ column.states.colspan = colspan;
123725
+ } else column.states.colspan = 1;
123726
+ };
123727
+ v.forEach((column) => {
123728
+ column.states.level = 1;
123729
+ traverse(column);
123730
+ });
123731
+ const rows = [];
123732
+ for (let i = 0; i < maxLevel; i++) rows.push([]);
123733
+ getAllColumns(v).forEach((column) => {
123734
+ if (!column.childNodes.length) column.states.rowspan = maxLevel - column.states.level + 1;
123735
+ else column.states.rowspan = 1;
123736
+ rows[column.states.level - 1].push(column);
123737
+ });
123738
+ return rows;
123739
+ };
123740
+ var COLUMN_SYNC_KEYS = [
123741
+ "id",
123742
+ "hidden",
123743
+ "label",
123744
+ "prop",
123745
+ "type"
123746
+ ];
123747
+ var Column = class {
123748
+ store;
123749
+ _sync = {
123750
+ snapshot: [],
123751
+ suppressWatch: false
123752
+ };
123753
+ constructor(store) {
123754
+ this.store = store;
123755
+ }
123756
+ insert(column, index, parent) {
123757
+ const array = parent ? parent.childNodes : this.store.states._columns;
123758
+ if (typeof index !== "undefined") array.splice(index, 0, column);
123759
+ else array.push(column);
123760
+ if (column.states.type === "selection") {
123761
+ this.store.states.selectable = column.states.selectable;
123762
+ this.store.states.reserveSelection = !!column.states.reserveSelection;
123763
+ }
123764
+ if (this.store.table.exposed.isReady.value) {
123765
+ this.store.updateColumns();
123766
+ this.store.scheduleLayout();
123767
+ }
123768
+ }
123769
+ remove(column, parent) {
123770
+ const array = parent ? parent.childNodes : this.store.states._columns;
123771
+ const index = array.indexOf(column);
123772
+ if (index > -1) array.splice(index, 1);
123773
+ if (this.store.table.exposed.isReady.value) {
123774
+ this.store.updateColumns();
123775
+ this.store.scheduleLayout();
123776
+ }
123777
+ }
123778
+ /**
123779
+ * 更新列派生状态(leftFixed/rightFixed/originColumns/headerRows)。
123780
+ * 不调用 Block、不 emit。
123781
+ */
123782
+ update() {
123783
+ const { states } = this.store;
123784
+ const _columns = states._columns || [];
123785
+ if (_columns[0] && _columns[0].states.type === "selection" && !_columns[0].states.fixed) {
123786
+ if (_columns.some((column) => column.states.fixed === true || column.states.fixed === "left")) _columns[0].states.fixed = true;
123787
+ }
123788
+ const visibleColumns = this.cloneVisibleTree(_columns);
123789
+ const leftFixedColumns = visibleColumns.filter((column) => column.states.fixed === true || column.states.fixed === "left");
123790
+ const rightFixedColumns = visibleColumns.filter((column) => column.states.fixed === "right");
123791
+ const notFixedColumns = visibleColumns.filter((column) => !column.states.fixed);
123792
+ const originColumns = concat(leftFixedColumns, notFixedColumns, rightFixedColumns);
123793
+ const headerRows = columnsToRowsEffect(originColumns);
123794
+ states.leftFixedColumns = leftFixedColumns;
123795
+ states.notFixedColumns = notFixedColumns;
123796
+ states.rightFixedColumns = rightFixedColumns;
123797
+ states.originColumns = originColumns;
123798
+ states.headerRows = headerRows;
123799
+ }
123800
+ /**
123801
+ * 基于 _columns 生成"可见树":剔除 hidden 列。
123802
+ * 仅克隆含子列的分组节点(避免 columnsToRowsEffect 把 colspan/level/rowspan
123803
+ * 写回原列节点造成残留);leaf 列保持原引用,以便 Layout 写回 realWidth/stickyStyle/stickyClass。
123804
+ * @param arr 列节点集合
123805
+ * @returns 可见列节点集合
123806
+ */
123807
+ cloneVisibleTree(arr) {
123808
+ const walk = (list) => {
123809
+ const out = [];
123810
+ for (const column of list) {
123811
+ if (column.states.hidden) continue;
123812
+ if (column.childNodes.length) {
123813
+ const children = walk(column.childNodes);
123814
+ if (children.length === 0) continue;
123815
+ out.push(column.cloneNode(children));
123816
+ } else out.push(column);
123817
+ }
123818
+ return out;
123819
+ };
123820
+ return walk(arr);
123821
+ }
123822
+ /**
123823
+ * 向外部 emit update:columns。
123824
+ * 暴露全部收集到的 leaf 列(含被隐藏的,带 hidden 标记),不做可见性过滤。
123825
+ */
123826
+ syncToParent() {
123827
+ const columns = flattenColumnNodes(this.store.states._columns).map((column) => pick(column.states, COLUMN_SYNC_KEYS));
123828
+ if (isEqualWith(columns.map((i) => pick(i, COLUMN_SYNC_KEYS)), this._sync.snapshot.map((i) => pick(i, COLUMN_SYNC_KEYS)))) return;
123829
+ this._sync.snapshot = columns;
123830
+ this._sync.suppressWatch = true;
123831
+ this.store.table.emit("update:columns", columns);
123832
+ }
123833
+ /**
123834
+ * 处理外部对 v-model:columns 的写回:
123835
+ * 1) 按 id 把 hidden 回写到内部列节点(递归含 childNodes,覆盖多级表头);
123836
+ * 2) 按 id 对齐顺序重排顶层 _columns(缺失项按原相对顺序补在末尾,避免误丢列)。
123837
+ * @param v 外部写回的列数组
123838
+ */
123839
+ applyExternal(v) {
123840
+ if (this._sync.suppressWatch) {
123841
+ this._sync.suppressWatch = false;
123842
+ return;
123843
+ }
123844
+ const _columns = this.store.states._columns;
123845
+ if (!Array.isArray(v) || !v.length) return;
123846
+ const hiddenById = v.reduce((pre, e) => (e && e.id != null && pre.set(e.id, !!e.hidden), pre), /* @__PURE__ */ new Map());
123847
+ let hiddenChanged = false;
123848
+ const applyHidden = (list) => {
123849
+ for (const column of list) {
123850
+ if (hiddenById.has(column.states.id)) {
123851
+ const v1 = hiddenById.get(column.states.id);
123852
+ if (!!column.states.hidden !== v1) {
123853
+ column.states.hidden = v1;
123854
+ hiddenChanged = true;
123855
+ }
123856
+ }
123857
+ if (column.childNodes.length) applyHidden(column.childNodes);
123858
+ }
123859
+ };
123860
+ applyHidden(_columns);
123861
+ const order = v.map((e) => e?.id).filter(Boolean);
123862
+ const idToCol = _columns.reduce((pre, column) => (pre.set(column.states.id, column), pre), /* @__PURE__ */ new Map());
123863
+ const used = /* @__PURE__ */ new Set();
123864
+ const reordered = [];
123865
+ for (const id of order) {
123866
+ const column = idToCol.get(id);
123867
+ if (column && !used.has(column)) {
123868
+ reordered.push(column);
123869
+ used.add(column);
123870
+ }
123871
+ }
123872
+ for (const column of _columns) if (!used.has(column)) reordered.push(column);
123873
+ const orderChanged = !(reordered.length === _columns.length && reordered.every((column, i) => column === _columns[i]));
123874
+ orderChanged && (this.store.states._columns = reordered);
123875
+ if (orderChanged || hiddenChanged) {
123876
+ this.store.updateColumns();
123877
+ this.store.scheduleLayout();
123878
+ }
123879
+ }
123880
+ };
123529
123881
  var Expand$1 = class {
123530
123882
  store;
123531
123883
  constructor(store) {
@@ -123547,7 +123899,7 @@ ${p}
123547
123899
  toggle(row, expanded) {
123548
123900
  const store = this.store;
123549
123901
  const { expandRows } = store.states;
123550
- if (store.toggleRowStatus(expandRows, row, expanded)) {
123902
+ if (toggleRowStatus(expandRows, row, expanded)) {
123551
123903
  store.table.emit("expand-change", row, expandRows.slice());
123552
123904
  store.scheduleLayout();
123553
123905
  }
@@ -123571,12 +123923,165 @@ ${p}
123571
123923
  return expandRows.indexOf(row) !== -1;
123572
123924
  }
123573
123925
  };
123574
- var Current = class {
123926
+ var Layout = class {
123927
+ table;
123928
+ store;
123929
+ states = (0, vue.reactive)({
123930
+ height: null,
123931
+ scrollX: false,
123932
+ scrollY: false,
123933
+ bodyWidth: null,
123934
+ tableHeight: null,
123935
+ headerHeight: 44,
123936
+ appendHeight: 0,
123937
+ footerHeight: 44,
123938
+ bodyHeight: null
123939
+ });
123940
+ /**
123941
+ * grid-template-columns 唯一真源:经表根 `--vc-table-columns` CSS 变量下发,
123942
+ * header / body 的所有 TableGrid 消费 var(),列宽变化只写表根一个节点。
123943
+ */
123944
+ templateColumns = (0, vue.computed)(() => computeGridTemplateColumns(this.store.states.columns));
123945
+ constructor(store) {
123946
+ this.store = store;
123947
+ this.table = store.table;
123948
+ if (!this.table) throw new VcError("table", "Table Layout 必须包含table实例");
123949
+ if (!this.store) throw new VcError("table", "Table Layout 必须包含store实例");
123950
+ }
123951
+ updateScrollY() {
123952
+ const { height, bodyHeight } = this.states;
123953
+ if (height === null || bodyHeight === null) return;
123954
+ const bodyYWrapper = this.table.exposed.bodyYWrapper.value;
123955
+ if (this.table.vnode.el && bodyYWrapper) this.states.scrollY = bodyYWrapper.offsetHeight > bodyHeight;
123956
+ }
123957
+ setHeight(value, prop = "height") {
123958
+ if (IS_SERVER$3) return;
123959
+ const el = this.table.vnode.el;
123960
+ value = parseHeight(value);
123961
+ this.states.height = value;
123962
+ if (!el && (value || value === 0)) return (0, vue.nextTick)(() => this.setHeight(value, prop));
123963
+ if (value) {
123964
+ el.style[prop] = `${value}px`;
123965
+ this.updateElsHeight();
123966
+ }
123967
+ }
123968
+ setMaxHeight(value) {
123969
+ this.setHeight(value, "max-height");
123970
+ }
123971
+ updateElsHeight() {
123972
+ if (!this.table.exposed.isReady.value) return (0, vue.nextTick)(() => this.updateElsHeight());
123973
+ const table = this.table.exposed;
123974
+ const headerWrapper = table.headerWrapper.value;
123975
+ const appendWrapper = table.appendWrapper.value;
123976
+ const footerWrapper = table.footerWrapper.value;
123977
+ const { showHeader } = this.table.props;
123978
+ this.states.appendHeight = appendWrapper ? appendWrapper.offsetHeight : 0;
123979
+ if (showHeader && !headerWrapper) return;
123980
+ const headerHeight = !showHeader ? 0 : headerWrapper.offsetHeight;
123981
+ this.states.headerHeight = headerHeight;
123982
+ if (showHeader && headerWrapper.offsetWidth > 0 && (this.store.states.columns || []).length > 0 && headerHeight < 2) return (0, vue.nextTick)(() => this.updateElsHeight());
123983
+ const tableHeight = this.table.vnode.el.clientHeight;
123984
+ this.states.tableHeight = tableHeight;
123985
+ const footerHeight = footerWrapper ? footerWrapper.offsetHeight : 0;
123986
+ this.states.footerHeight = footerHeight;
123987
+ if (this.states.height !== null) this.states.bodyHeight = tableHeight - headerHeight - footerHeight + (footerWrapper ? 1 : 0);
123988
+ this.updateScrollY();
123989
+ }
123990
+ updateColumnsWidth() {
123991
+ if (IS_SERVER$3) return;
123992
+ const bodyWidth = this.table.vnode.el.clientWidth;
123993
+ let bodyMinWidth = 0;
123994
+ const flattenColumns = this.store.states.columns;
123995
+ const flexColumns = flattenColumns.filter((column) => typeof column.states.width !== "number");
123996
+ const { fit } = this.table.props;
123997
+ if (flexColumns.length > 0 && fit) {
123998
+ flattenColumns.forEach((column) => {
123999
+ bodyMinWidth += column.states.width || column.states.minWidth || 80;
124000
+ });
124001
+ if (bodyMinWidth <= bodyWidth) {
124002
+ this.states.scrollX = false;
124003
+ const totalFlexWidth = bodyWidth - bodyMinWidth;
124004
+ if (flexColumns.length === 1) flexColumns[0].states.realWidth = (flexColumns[0].states.minWidth || 80) + totalFlexWidth;
124005
+ else {
124006
+ const flexWidthPerPixel = totalFlexWidth / flexColumns.reduce((prev, column) => prev + (column.states.minWidth || 80), 0);
124007
+ let noneFirstWidth = 0;
124008
+ flexColumns.forEach((column, index) => {
124009
+ if (index === 0) return;
124010
+ const flexWidth = Math.floor((column.states.minWidth || 80) * flexWidthPerPixel);
124011
+ noneFirstWidth += flexWidth;
124012
+ column.states.realWidth = (column.states.minWidth || 80) + flexWidth;
124013
+ });
124014
+ flexColumns[0].states.realWidth = (flexColumns[0].states.minWidth || 80) + totalFlexWidth - noneFirstWidth;
124015
+ }
124016
+ } else {
124017
+ this.states.scrollX = true;
124018
+ flexColumns.forEach((column) => {
124019
+ column.states.realWidth = column.states.width || column.states.minWidth;
124020
+ });
124021
+ }
124022
+ this.states.bodyWidth = Math.max(bodyMinWidth, bodyWidth);
124023
+ this.table.exposed.resizeState.value.width = this.states.bodyWidth;
124024
+ } else {
124025
+ flattenColumns.forEach((column) => {
124026
+ if (!column.states.width && !column.states.minWidth) column.states.realWidth = 80;
124027
+ else column.states.realWidth = column.states.width || column.states.minWidth;
124028
+ bodyMinWidth += column.states.realWidth;
124029
+ });
124030
+ this.states.scrollX = bodyMinWidth > bodyWidth;
124031
+ this.states.bodyWidth = bodyMinWidth;
124032
+ }
124033
+ this.syncStickyOffsets();
124034
+ }
124035
+ /**
124036
+ * 提前计算固定列的 sticky 偏移并写到列节点 states 上(包含分组列),渲染层(header /
124037
+ * body-row / footer)从 column.stickyStyle / column.stickyClass 直接消费即可。
124038
+ * 非固定列上的 sticky 信息一并清除,避免列从 fixed 切换为非 fixed 时残留。
124039
+ */
124040
+ syncStickyOffsets() {
124041
+ const { leftFixedColumns = [], rightFixedColumns = [], notFixedColumns = [] } = this.store.states;
124042
+ leftFixedColumns.reduce((offset, column, index) => {
124043
+ column.states.stickyOffset = offset;
124044
+ column.states.stickyStyle = {
124045
+ position: "sticky",
124046
+ left: `${offset}px`
124047
+ };
124048
+ column.states.stickyClass = "is-fixed-left";
124049
+ if (index === leftFixedColumns.length - 1) column.states.stickyClass += " is-fixed-left-tail";
124050
+ offset += column.states.realWidth || column.states.width || 0;
124051
+ return offset;
124052
+ }, 0);
124053
+ rightFixedColumns.reduceRight((offset, column, index) => {
124054
+ column.states.stickyOffset = offset;
124055
+ column.states.stickyStyle = {
124056
+ position: "sticky",
124057
+ right: `${offset}px`
124058
+ };
124059
+ column.states.stickyClass = "is-fixed-right";
124060
+ if (index === rightFixedColumns.length - 1) column.states.stickyClass += " is-fixed-right-head";
124061
+ offset += column.states.realWidth || column.states.width || 0;
124062
+ return offset;
124063
+ }, 0);
124064
+ notFixedColumns.forEach((column) => {
124065
+ column.states.stickyOffset = void 0;
124066
+ column.states.stickyStyle = void 0;
124067
+ column.states.stickyClass = void 0;
124068
+ });
124069
+ }
124070
+ };
124071
+ var Row = class {
123575
124072
  store;
123576
124073
  constructor(store) {
123577
124074
  this.store = store;
123578
124075
  }
123579
- reset(id) {
124076
+ setHoverIndex(index) {
124077
+ this.store.states.hoverRowIndex = index;
124078
+ }
124079
+ set(row) {
124080
+ const old = this.store.states.currentRow;
124081
+ this.store.states.currentRow = row;
124082
+ if (old !== row) this.store.table.emit("current-change", row, old);
124083
+ }
124084
+ setById(id) {
123580
124085
  const store = this.store;
123581
124086
  const { primaryKey } = store.table.props;
123582
124087
  store.checkPrimaryKey();
@@ -123599,6 +124104,102 @@ ${p}
123599
124104
  }
123600
124105
  }
123601
124106
  };
124107
+ var Selection = class {
124108
+ store;
124109
+ constructor(store) {
124110
+ this.store = store;
124111
+ }
124112
+ isSelected(row) {
124113
+ const { selection = [] } = this.store.states;
124114
+ return selection.includes(row);
124115
+ }
124116
+ clear() {
124117
+ this.store.states.isAllSelected = false;
124118
+ const oldSelection = this.store.states.selection;
124119
+ if (this.store.states.selection.length) this.store.states.selection = [];
124120
+ if (oldSelection.length > 0) this.store.table.emit("selection-change", []);
124121
+ }
124122
+ clean() {
124123
+ const { primaryKey } = this.store.table.props;
124124
+ const { selection = [], data } = this.store.states;
124125
+ let deleted;
124126
+ if (primaryKey) {
124127
+ deleted = [];
124128
+ const selectedMap = getValuesMap(selection, primaryKey);
124129
+ const dataMap = getValuesMap(data, primaryKey);
124130
+ for (const key in selectedMap) if (hasOwn$1(selectedMap, key) && !dataMap[key]) deleted.push(selectedMap[key].row);
124131
+ } else deleted = selection.filter((item) => {
124132
+ return !this.store.flatData.value.includes(item);
124133
+ });
124134
+ deleted.forEach((deletedItem) => {
124135
+ selection.splice(selection.indexOf(deletedItem), 1);
124136
+ });
124137
+ if (deleted.length) {
124138
+ const newSelection = selection.filter((item) => !deleted.includes(item));
124139
+ this.store.states.selection = newSelection;
124140
+ this.store.table.emit("selection-change", newSelection.slice());
124141
+ }
124142
+ }
124143
+ toggle(row, selected, emitChange = true) {
124144
+ const { selection } = this.store.states;
124145
+ if (toggleRowStatus(selection, row, selected)) {
124146
+ const newSelection = (this.store.states.selection || []).slice();
124147
+ if (emitChange) this.store.table.emit("select", newSelection, row);
124148
+ this.store.table.emit("selection-change", newSelection);
124149
+ }
124150
+ }
124151
+ toggleAll = debounce(() => {
124152
+ const { indeterminate } = this.store.table.props;
124153
+ const { selection, isAllSelected, selectable } = this.store.states;
124154
+ const value = indeterminate ? !isAllSelected : !(isAllSelected || selection.length);
124155
+ this.store.states.isAllSelected = value;
124156
+ let selectionChanged = false;
124157
+ this.store.flatData.value.forEach((row, index) => {
124158
+ if (selectable) {
124159
+ if (selectable.call(null, row, index) && toggleRowStatus(selection, row, value, true)) selectionChanged = true;
124160
+ } else if (toggleRowStatus(selection, row, value, true)) selectionChanged = true;
124161
+ });
124162
+ this.store.states.selection = [...selection].filter((i) => typeof i !== "undefined");
124163
+ const selection$ = this.store.states.selection.slice();
124164
+ if (selectionChanged) this.store.table.emit("selection-change", selection$);
124165
+ this.store.table.emit("select-all", selection$);
124166
+ }, 10);
124167
+ updateByRowKey() {
124168
+ const { primaryKey } = this.store.table.props;
124169
+ const { selection } = this.store.states;
124170
+ const selectedMap = getValuesMap(selection, primaryKey);
124171
+ this.store.states.selection = this.store.flatData.value.reduce((prev, row) => {
124172
+ if (selectedMap[getRowValue(row, primaryKey)]) prev.push(row);
124173
+ return prev;
124174
+ }, []);
124175
+ }
124176
+ updateAllSelected() {
124177
+ const { selectable, data = [] } = this.store.states;
124178
+ if (data.length === 0) {
124179
+ this.store.states.isAllSelected = false;
124180
+ return;
124181
+ }
124182
+ let isAllSelected = true;
124183
+ let selectedCount = 0;
124184
+ const temp = this.store.flatData.value;
124185
+ for (let i = 0, j = temp.length; i < j; i++) {
124186
+ const row = temp[i];
124187
+ const isRowSelectable = selectable && selectable.call(null, row, i);
124188
+ if (!this.isSelected(row)) {
124189
+ if (!selectable || isRowSelectable) {
124190
+ isAllSelected = false;
124191
+ break;
124192
+ }
124193
+ } else selectedCount++;
124194
+ }
124195
+ if (selectedCount === 0) isAllSelected = false;
124196
+ this.store.states.isAllSelected = isAllSelected;
124197
+ }
124198
+ rowChanged(row) {
124199
+ this.toggle(row);
124200
+ this.updateAllSelected();
124201
+ }
124202
+ };
123602
124203
  var Tree$1 = class {
123603
124204
  store;
123604
124205
  /**
@@ -123665,7 +124266,7 @@ ${p}
123665
124266
  return max$2(data.map((item) => {
123666
124267
  const traverse = (source) => {
123667
124268
  if (!source) return 0;
123668
- if (source.expanded && source.children.length > 0) return max$2([source.level, ...source.children.map((key) => traverse(treeData[key]))]);
124269
+ if (source.expand && source.children.length > 0) return max$2([source.level, ...source.children.map((key) => traverse(treeData[key]))]);
123669
124270
  else return source.level;
123670
124271
  };
123671
124272
  return traverse(treeData[getRowValue(item, primaryKey)]);
@@ -123680,14 +124281,14 @@ ${p}
123680
124281
  const { defaultExpandAll } = this.store.table.props;
123681
124282
  const { treeData: oldTreeData, treeExpandRowValue, treeLazy } = this.store.states;
123682
124283
  const rootLazyRowValue = [];
123683
- const getExpanded = (oldValue, key) => {
124284
+ const getExpand = (oldValue, key) => {
123684
124285
  const included = defaultExpandAll || treeExpandRowValue && treeExpandRowValue.indexOf(key) !== -1;
123685
- return !!(oldValue && oldValue.expanded || included);
124286
+ return !!(oldValue && oldValue.expand || included);
123686
124287
  };
123687
124288
  keys.forEach((key) => {
123688
124289
  const oldValue = oldTreeData[key];
123689
124290
  const newValue = { ...nested[key] };
123690
- newValue.expanded = getExpanded(oldValue, key);
124291
+ newValue.expand = getExpand(oldValue, key);
123691
124292
  if (newValue.lazy) {
123692
124293
  const { loaded = false, loading = false } = oldValue || {};
123693
124294
  newValue.loaded = !!loaded;
@@ -123709,7 +124310,7 @@ ${p}
123709
124310
  lazy: true,
123710
124311
  loaded: !!loaded,
123711
124312
  loading: !!loading,
123712
- expanded: getExpanded(oldValue, key),
124313
+ expand: getExpand(oldValue, key),
123713
124314
  children: lazyNodeChildren,
123714
124315
  level: ""
123715
124316
  });
@@ -123729,11 +124330,11 @@ ${p}
123729
124330
  const { treeData } = this.store.states;
123730
124331
  const id = getRowValue(row, primaryKey);
123731
124332
  const data = id && treeData[id];
123732
- if (id && data && "expanded" in data) {
123733
- const oldExpanded = data.expanded;
123734
- expanded = typeof expanded === "undefined" ? !data.expanded : expanded;
123735
- this.store.states.treeData[id].expanded = expanded;
123736
- if (oldExpanded !== expanded) this.store.table.emit("expand-change", row, expanded, this.getMaxLevel());
124333
+ if (id && data && "expand" in data) {
124334
+ const oldExpand = data.expand;
124335
+ expanded = typeof expanded === "undefined" ? !data.expand : expanded;
124336
+ this.store.states.treeData[id].expand = expanded;
124337
+ if (oldExpand !== expanded) this.store.table.emit("expand-change", row, expanded, this.getMaxLevel());
123737
124338
  this.store.updateTableScrollY();
123738
124339
  }
123739
124340
  }
@@ -123758,7 +124359,7 @@ ${p}
123758
124359
  if (!Array.isArray(data)) throw new VcError("table", "data必须是数组");
123759
124360
  this.store.states.treeData[key].loading = false;
123760
124361
  this.store.states.treeData[key].loaded = true;
123761
- this.store.states.treeData[key].expanded = true;
124362
+ this.store.states.treeData[key].expand = true;
123762
124363
  /**
123763
124364
  * 处理tree中和返回的数据与首次相同的情况,
123764
124365
  */
@@ -123779,10 +124380,10 @@ ${p}
123779
124380
  return pre.concat(treelazyNodeMap[cur]);
123780
124381
  }, []);
123781
124382
  }
123782
- if (this.store.isSelected(row)) data.forEach((i) => {
123783
- this.store.toggleRowSelection(i);
124383
+ if (this.store.selection.isSelected(row)) data.forEach((i) => {
124384
+ this.store.selection.toggle(i);
123784
124385
  });
123785
- this.store.updateAllSelected();
124386
+ this.store.selection.updateAllSelected();
123786
124387
  /**
123787
124388
  * 计算最大的level, 有必要添加$nextTick
123788
124389
  * TODO: 去除$nextTick, 期间会触发一次update
@@ -123798,156 +124399,15 @@ ${p}
123798
124399
  }
123799
124400
  }
123800
124401
  };
123801
- var Layout = class {
123802
- table;
123803
- store;
123804
- states = (0, vue.reactive)({
123805
- height: null,
123806
- scrollX: false,
123807
- scrollY: false,
123808
- bodyWidth: null,
123809
- tableHeight: null,
123810
- headerHeight: 44,
123811
- appendHeight: 0,
123812
- footerHeight: 44,
123813
- bodyHeight: null
123814
- });
123815
- constructor(store) {
123816
- this.store = store;
123817
- this.table = store.table;
123818
- if (!this.table) throw new VcError("table", "Table Layout 必须包含table实例");
123819
- if (!this.store) throw new VcError("table", "Table Layout 必须包含store实例");
123820
- }
123821
- updateScrollY() {
123822
- const { height, bodyHeight } = this.states;
123823
- if (height === null || bodyHeight === null) return;
123824
- const bodyYWrapper = this.table.exposed.bodyYWrapper.value;
123825
- if (this.table.vnode.el && bodyYWrapper) this.states.scrollY = bodyYWrapper.offsetHeight > bodyHeight;
123826
- }
123827
- setHeight(value, prop = "height") {
123828
- if (IS_SERVER$3) return;
123829
- const el = this.table.vnode.el;
123830
- value = parseHeight(value);
123831
- this.states.height = value;
123832
- if (!el && (value || value === 0)) return (0, vue.nextTick)(() => this.setHeight(value, prop));
123833
- if (value) {
123834
- el.style[prop] = `${value}px`;
123835
- this.updateElsHeight();
123836
- }
123837
- }
123838
- setMaxHeight(value) {
123839
- this.setHeight(value, "max-height");
123840
- }
123841
- updateElsHeight() {
123842
- if (!this.table.exposed.isReady.value) return (0, vue.nextTick)(() => this.updateElsHeight());
123843
- const table = this.table.exposed;
123844
- const headerWrapper = table.headerWrapper.value;
123845
- const appendWrapper = table.appendWrapper.value;
123846
- const footerWrapper = table.footerWrapper.value;
123847
- const { showHeader } = this.table.props;
123848
- this.states.appendHeight = appendWrapper ? appendWrapper.offsetHeight : 0;
123849
- if (showHeader && !headerWrapper) return;
123850
- const headerHeight = !showHeader ? 0 : headerWrapper.offsetHeight;
123851
- this.states.headerHeight = headerHeight;
123852
- if (showHeader && headerWrapper.offsetWidth > 0 && (this.store.states.columns || []).length > 0 && headerHeight < 2) return (0, vue.nextTick)(() => this.updateElsHeight());
123853
- const tableHeight = this.table.vnode.el.clientHeight;
123854
- this.states.tableHeight = tableHeight;
123855
- const footerHeight = footerWrapper ? footerWrapper.offsetHeight : 0;
123856
- this.states.footerHeight = footerHeight;
123857
- if (this.states.height !== null) this.states.bodyHeight = tableHeight - headerHeight - footerHeight + (footerWrapper ? 1 : 0);
123858
- this.updateScrollY();
123859
- }
123860
- updateColumnsWidth() {
123861
- if (IS_SERVER$3) return;
123862
- const bodyWidth = this.table.vnode.el.clientWidth;
123863
- let bodyMinWidth = 0;
123864
- const flattenColumns = this.store.states.columns;
123865
- const flexColumns = flattenColumns.filter((column) => typeof column.width !== "number");
123866
- const { fit } = this.table.props;
123867
- if (flexColumns.length > 0 && fit) {
123868
- flattenColumns.forEach((column) => {
123869
- bodyMinWidth += column.width || column.minWidth || 80;
123870
- });
123871
- if (bodyMinWidth <= bodyWidth) {
123872
- this.states.scrollX = false;
123873
- const totalFlexWidth = bodyWidth - bodyMinWidth;
123874
- if (flexColumns.length === 1) flexColumns[0].realWidth = (flexColumns[0].minWidth || 80) + totalFlexWidth;
123875
- else {
123876
- const flexWidthPerPixel = totalFlexWidth / flexColumns.reduce((prev, column) => prev + (column.minWidth || 80), 0);
123877
- let noneFirstWidth = 0;
123878
- flexColumns.forEach((column, index) => {
123879
- if (index === 0) return;
123880
- const flexWidth = Math.floor((column.minWidth || 80) * flexWidthPerPixel);
123881
- noneFirstWidth += flexWidth;
123882
- column.realWidth = (column.minWidth || 80) + flexWidth;
123883
- });
123884
- flexColumns[0].realWidth = (flexColumns[0].minWidth || 80) + totalFlexWidth - noneFirstWidth;
123885
- }
123886
- } else {
123887
- this.states.scrollX = true;
123888
- flexColumns.forEach((column) => {
123889
- column.realWidth = column.width || column.minWidth;
123890
- });
123891
- }
123892
- this.states.bodyWidth = Math.max(bodyMinWidth, bodyWidth);
123893
- this.table.exposed.resizeState.value.width = this.states.bodyWidth;
123894
- } else {
123895
- flattenColumns.forEach((column) => {
123896
- if (!column.width && !column.minWidth) column.realWidth = 80;
123897
- else column.realWidth = column.width || column.minWidth;
123898
- bodyMinWidth += column.realWidth;
123899
- });
123900
- this.states.scrollX = bodyMinWidth > bodyWidth;
123901
- this.states.bodyWidth = bodyMinWidth;
123902
- }
123903
- this.syncStickyOffsets();
123904
- }
123905
- /**
123906
- * 提前计算固定列的 sticky 偏移并写到列对象上(包含分组列),渲染层(header /
123907
- * body-row / footer)从 column.stickyLeft / column.stickyRight 直接消费即可。
123908
- * 非固定列上的 sticky 信息一并清除,避免列从 fixed 切换为非 fixed 时残留。
123909
- */
123910
- syncStickyOffsets() {
123911
- const { leftFixedColumns = [], rightFixedColumns = [], notFixedColumns = [] } = this.store.states;
123912
- leftFixedColumns.reduce((offset, column, index) => {
123913
- column.stickyOffset = offset;
123914
- column.stickyStyle = {
123915
- position: "sticky",
123916
- left: `${offset}px`
123917
- };
123918
- column.stickyClass = "is-fixed-left";
123919
- if (index === leftFixedColumns.length - 1) column.stickyClass += " is-fixed-left-tail";
123920
- offset += column.realWidth || column.width || 0;
123921
- return offset;
123922
- }, 0);
123923
- rightFixedColumns.reduceRight((offset, column, index) => {
123924
- column.stickyOffset = offset;
123925
- column.stickyStyle = {
123926
- position: "sticky",
123927
- right: `${offset}px`
123928
- };
123929
- column.stickyClass = "is-fixed-right";
123930
- if (index === rightFixedColumns.length - 1) column.stickyClass += " is-fixed-right-head";
123931
- offset += column.realWidth || column.width || 0;
123932
- return offset;
123933
- }, 0);
123934
- notFixedColumns.forEach((column) => {
123935
- delete column.stickyOffset;
123936
- delete column.stickyStyle;
123937
- delete column.stickyClass;
123938
- });
123939
- }
123940
- };
123941
124402
  var Store$1 = class extends BaseWatcher {
123942
124403
  table;
123943
- current;
124404
+ row;
123944
124405
  expand;
123945
124406
  tree;
124407
+ block;
124408
+ column;
123946
124409
  layout;
123947
- _columnsSync = {
123948
- snapshot: [],
123949
- suppressWatch: false
123950
- };
124410
+ selection;
123951
124411
  flatData = (0, vue.computed)(() => {
123952
124412
  if (this.table.props.expandSelectable) return concat(flattenData(this.states.data, {
123953
124413
  parent: true,
@@ -123959,10 +124419,13 @@ ${p}
123959
124419
  super();
123960
124420
  if (!options.table) throw new VcError("table", "table必传");
123961
124421
  this.table = options.table;
123962
- this.current = new Current(this);
124422
+ this.row = new Row(this);
123963
124423
  this.expand = new Expand$1(this);
123964
124424
  this.tree = new Tree$1(this);
124425
+ this.block = new Block(this);
124426
+ this.column = new Column(this);
123965
124427
  this.layout = new Layout(this);
124428
+ this.selection = new Selection(this);
123966
124429
  const { props } = options.table;
123967
124430
  merge$1(this.states, {
123968
124431
  expandSelectable: props.expandSelectable,
@@ -123972,58 +124435,36 @@ ${p}
123972
124435
  });
123973
124436
  }
123974
124437
  setData(data) {
123975
- const { primaryKey } = this.table.props;
123976
124438
  const dataInstanceChanged = this.states._data !== data;
123977
124439
  this.states._data = data;
123978
124440
  this.states.data = data;
123979
- const caches = /* @__PURE__ */ new Map();
123980
- this.states.list.forEach((item) => {
123981
- item.rows.forEach((row) => {
123982
- caches.set(row.data, row);
123983
- });
123984
- });
123985
- this.states.list = data.reduce((pre, row, index) => {
123986
- const rows = [{
123987
- index,
123988
- data: row,
123989
- height: (caches.get(row) || {}).height || ""
123990
- }];
123991
- const id = primaryKey ? rows.map((rowData) => getRowValue(rowData.data, primaryKey)).join(",") : index;
123992
- pre.push({
123993
- id: typeof id === "undefined" ? index : id,
123994
- rows,
123995
- expand: false
123996
- });
123997
- return pre;
123998
- }, []);
123999
- caches.clear();
124441
+ this.states.list = this.block.buildInitialList(data);
124442
+ this.block.rebuildMergeList();
124000
124443
  /**
124001
124444
  * 数据变化,更新部分数据。
124002
124445
  * 没有使用 computed,而是手动更新部分数据
124003
124446
  * https://github.com/vuejs/vue/issues/6660#issuecomment-331417140
124004
124447
  */
124005
- this.current.update();
124448
+ this.row.update();
124006
124449
  this.expand.update();
124007
- if (!this.states.reserveSelection) if (dataInstanceChanged) this.clearSelection();
124008
- else this.cleanSelection();
124450
+ if (!this.states.reserveSelection) if (dataInstanceChanged) this.selection.clear();
124451
+ else this.selection.clean();
124009
124452
  else {
124010
124453
  this.checkPrimaryKey();
124011
- this.updateSelectionByRowKey();
124454
+ this.selection.updateByRowKey();
124012
124455
  }
124013
- this.updateAllSelected();
124456
+ this.selection.updateAllSelected();
124014
124457
  this.updateTableScrollY();
124015
124458
  }
124016
- rowSelectedChanged(row) {
124017
- this.toggleRowSelection(row);
124018
- this.updateAllSelected();
124019
- }
124020
- setHoverRow(index) {
124021
- this.states.hoverRowIndex = index;
124459
+ updateColumns() {
124460
+ this.column.update();
124461
+ this.block.rebuildMergeList();
124462
+ this.column.syncToParent();
124022
124463
  }
124023
- setCurrentRow(row) {
124024
- const oldCurrentRow = this.states.currentRow;
124025
- this.states.currentRow = row;
124026
- if (oldCurrentRow !== row) this.table.emit("current-change", row, oldCurrentRow);
124464
+ toggleRowExpansionAdapter(row, expanded) {
124465
+ const { columns } = this.states;
124466
+ if (columns.some((node) => node.states.type === "expand")) this.expand.toggle(row, expanded);
124467
+ else this.tree.toggle(row, expanded);
124027
124468
  }
124028
124469
  /**
124029
124470
  * 检查 primaryKey 是否存在
@@ -124032,297 +124473,10 @@ ${p}
124032
124473
  const { primaryKey } = this.table.props;
124033
124474
  if (!primaryKey) {}
124034
124475
  }
124035
- /**
124036
- * states
124037
- * -> _columns
124038
- * -> selectable
124039
- * -> reserveSelection
124040
- * @param column ~
124041
- * @param index ~
124042
- * @param parent ~
124043
- */
124044
- insertColumn(column, index, parent) {
124045
- let array = this.states._columns;
124046
- if (parent) {
124047
- array = parent.children;
124048
- if (!array) {
124049
- array = [];
124050
- parent.children = array;
124051
- }
124052
- }
124053
- if (typeof index !== "undefined") array.splice(index, 0, column);
124054
- else array.push(column);
124055
- if (column.type === "selection") {
124056
- this.states.selectable = column.selectable;
124057
- this.states.reserveSelection = column.reserveSelection;
124058
- }
124059
- if (this.table.exposed.isReady.value) {
124060
- this.updateColumns();
124061
- this.scheduleLayout();
124062
- }
124063
- }
124064
- removeColumn(column, parent) {
124065
- let array = this.states._columns;
124066
- if (parent) array = parent.children || [];
124067
- if (array) array.splice(array.indexOf(column), 1);
124068
- if (this.table.exposed.isReady.value) {
124069
- this.updateColumns();
124070
- this.scheduleLayout();
124071
- }
124072
- }
124073
- /**
124074
- * 更新列
124075
- * leftFixedColumns: 左fixed
124076
- * rightFixedColumns: 右fixed
124077
- * originColumns: 中(包括左右)
124078
- * columns: 展开以上
124079
- * leafColumnsLength
124080
- * leftFixedLeafColumnsLength
124081
- * rightFixedLeafColumnsLength
124082
- * isComplex: 是否包含固定列
124083
- */
124084
- updateColumns() {
124085
- const { states } = this;
124086
- const _columns = states._columns || [];
124087
- if (_columns[0] && _columns[0].type === "selection" && !_columns[0].fixed) {
124088
- if (_columns.some((column) => column.fixed === true || column.fixed === "left")) _columns[0].fixed = true;
124089
- }
124090
- const visibleColumns = this.cloneVisibleTree(_columns);
124091
- const leftFixedColumns = visibleColumns.filter((column) => column.fixed === true || column.fixed === "left");
124092
- const rightFixedColumns = visibleColumns.filter((column) => column.fixed === "right");
124093
- const notFixedColumns = visibleColumns.filter((column) => !column.fixed);
124094
- const originColumns = concat(leftFixedColumns, notFixedColumns, rightFixedColumns);
124095
- const headerRows = columnsToRowsEffect(originColumns);
124096
- states.leftFixedColumns = leftFixedColumns;
124097
- states.notFixedColumns = notFixedColumns;
124098
- states.rightFixedColumns = rightFixedColumns;
124099
- states.originColumns = originColumns;
124100
- states.headerRows = headerRows;
124101
- this.syncColumnsToParent();
124102
- }
124103
- /**
124104
- * 基于 _columns 生成"可见树":剔除 hidden 列。
124105
- * 仅克隆含 children 的父节点(避免 columnsToRowsEffect 把 colspan/level/rowspan
124106
- * 写回原列对象造成残留);leaf 列保持原引用,以便 Layout 写回 realWidth/stickyStyle/stickyClass。
124107
- * @param arr 列集合
124108
- * @returns 可见列集合
124109
- */
124110
- cloneVisibleTree(arr) {
124111
- const walk = (list) => {
124112
- const out = [];
124113
- for (const column of list) {
124114
- if (column.hidden) continue;
124115
- if (column.children && column.children.length) {
124116
- const children = walk(column.children);
124117
- if (children.length === 0) continue;
124118
- out.push({
124119
- ...column,
124120
- children
124121
- });
124122
- } else out.push(column);
124123
- }
124124
- return out;
124125
- };
124126
- return walk(arr);
124127
- }
124128
- /**
124129
- * 向外部 emit update:columns。
124130
- * 暴露全部收集到的 leaf 列(含被隐藏的,带 hidden 标记),不做可见性过滤。
124131
- * 指纹同时纳入 id 顺序与各列 hidden 状态:
124132
- * - 外部写回(顺序/hidden)后内部应用,指纹不变 -> 不重复 emit,避免回环;
124133
- * - 内部列增删导致变化 -> 指纹变化 -> emit 通知外部。
124134
- */
124135
- syncColumnsToParent() {
124136
- const keys = [
124137
- "id",
124138
- "hidden",
124139
- "label",
124140
- "prop",
124141
- "type"
124142
- ];
124143
- const columns = flattenData(this.states._columns).map((column) => pick(column, keys));
124144
- if (isEqualWith(columns.map((i) => pick(i, keys)), this._columnsSync.snapshot.map((i) => pick(i, keys)))) return;
124145
- this._columnsSync.snapshot = columns;
124146
- this._columnsSync.suppressWatch = true;
124147
- this.table.emit("update:columns", columns);
124148
- }
124149
- /**
124150
- * 处理外部对 v-model:columns 的写回:
124151
- * 1) 按 id 把 hidden 回写到内部列对象(递归含 children,覆盖多级表头);
124152
- * 2) 按 id 对齐顺序重排顶层 _columns(缺失项按原相对顺序补在末尾,避免误丢列)。
124153
- * @param v 外部写回的列数组
124154
- */
124155
- applyExternalColumns(v) {
124156
- if (this._columnsSync.suppressWatch) {
124157
- this._columnsSync.suppressWatch = false;
124158
- return;
124159
- }
124160
- const _columns = this.states._columns;
124161
- if (!Array.isArray(v) || !v.length) return;
124162
- const hiddenById = v.reduce((pre, e) => (e && e.id != null && pre.set(e.id, !!e.hidden), pre), /* @__PURE__ */ new Map());
124163
- let hiddenChanged = false;
124164
- const applyHidden = (list) => {
124165
- for (const column of list) {
124166
- if (hiddenById.has(column.id)) {
124167
- const v1 = hiddenById.get(column.id);
124168
- if (!!column.hidden !== v1) {
124169
- column.hidden = v1;
124170
- hiddenChanged = true;
124171
- }
124172
- }
124173
- if (column.children && column.children.length) applyHidden(column.children);
124174
- }
124175
- };
124176
- applyHidden(_columns);
124177
- const order = v.map((e) => e?.id).filter(Boolean);
124178
- const idToCol = _columns.reduce((pre, column) => (pre.set(column.id, column), pre), /* @__PURE__ */ new Map());
124179
- const used = /* @__PURE__ */ new Set();
124180
- const reordered = [];
124181
- for (const id of order) {
124182
- const column = idToCol.get(id);
124183
- if (column && !used.has(column)) {
124184
- reordered.push(column);
124185
- used.add(column);
124186
- }
124187
- }
124188
- for (const column of _columns) if (!used.has(column)) reordered.push(column);
124189
- const orderChanged = !(reordered.length === _columns.length && reordered.every((column, i) => column === _columns[i]));
124190
- orderChanged && (this.states._columns = reordered);
124191
- if (orderChanged || hiddenChanged) {
124192
- this.updateColumns();
124193
- this.scheduleLayout();
124194
- }
124195
- }
124196
- isSelected(row) {
124197
- const { selection = [] } = this.states;
124198
- return selection.includes(row);
124199
- }
124200
- /**
124201
- * 清除选择
124202
- */
124203
- clearSelection() {
124204
- this.states.isAllSelected = false;
124205
- const oldSelection = this.states.selection;
124206
- if (this.states.selection.length) this.states.selection = [];
124207
- if (oldSelection.length > 0) this.table.emit("selection-change", []);
124208
- }
124209
- /**
124210
- * 清理选择
124211
- */
124212
- cleanSelection() {
124213
- const { primaryKey } = this.table.props;
124214
- const { selection = [], data } = this.states;
124215
- let deleted;
124216
- if (primaryKey) {
124217
- deleted = [];
124218
- const selectedMap = getValuesMap(selection, primaryKey);
124219
- const dataMap = getValuesMap(data, primaryKey);
124220
- for (const key in selectedMap) if (hasOwn$1(selectedMap, key) && !dataMap[key]) deleted.push(selectedMap[key].row);
124221
- } else deleted = selection.filter((item) => {
124222
- return !this.flatData.value.includes(item);
124223
- });
124224
- deleted.forEach((deletedItem) => {
124225
- selection.splice(selection.indexOf(deletedItem), 1);
124226
- });
124227
- if (deleted.length) {
124228
- const newSelection = selection.filter((item) => !deleted.includes(item));
124229
- this.states.selection = newSelection;
124230
- this.table.emit("selection-change", newSelection.slice());
124231
- }
124232
- }
124233
- /**
124234
- * 存在副作用
124235
- * 对statusArr做添加和删除的操作
124236
- * 如 this.states.selection
124237
- * @param statusArr ~
124238
- * @param row ~
124239
- * @param newVal ~
124240
- * @param batch 为true时,使用delete (批处理使用splice性能差,使用delete后统一再处理)
124241
- * @returns ~
124242
- */
124243
- toggleRowStatus(statusArr, row, newVal, batch = false) {
124244
- let changed = false;
124245
- const index = statusArr.indexOf(row);
124246
- const included = index !== -1;
124247
- const addRow = () => {
124248
- statusArr.push(row);
124249
- changed = true;
124250
- };
124251
- const removeRow = () => {
124252
- if (!batch) statusArr.splice(index, 1);
124253
- else delete statusArr[index];
124254
- changed = true;
124255
- };
124256
- if (typeof newVal === "boolean") {
124257
- if (newVal && !included) addRow();
124258
- else if (!newVal && included) removeRow();
124259
- } else included ? removeRow() : addRow();
124260
- return changed;
124261
- }
124262
- toggleRowSelection(row, selected, emitChange = true) {
124263
- const { selection } = this.states;
124264
- if (this.toggleRowStatus(selection, row, selected)) {
124265
- const newSelection = (this.states.selection || []).slice();
124266
- if (emitChange) this.table.emit("select", newSelection, row);
124267
- this.table.emit("selection-change", newSelection);
124268
- }
124269
- }
124270
- toggleAllSelection = debounce(() => {
124271
- const { indeterminate } = this.table.props;
124272
- const { selection, isAllSelected, selectable } = this.states;
124273
- const value = indeterminate ? !isAllSelected : !(isAllSelected || selection.length);
124274
- this.states.isAllSelected = value;
124275
- let selectionChanged = false;
124276
- this.flatData.value.forEach((row, index) => {
124277
- if (selectable) {
124278
- if (selectable.call(null, row, index) && this.toggleRowStatus(selection, row, value, true)) selectionChanged = true;
124279
- } else if (this.toggleRowStatus(selection, row, value, true)) selectionChanged = true;
124280
- });
124281
- this.states.selection = [...selection].filter((i) => typeof i !== "undefined");
124282
- const selection$ = this.states.selection.slice();
124283
- if (selectionChanged) this.table.emit("selection-change", selection$);
124284
- this.table.emit("select-all", selection$);
124285
- }, 10);
124286
- toggleRowExpansionAdapter(row, expanded) {
124287
- const { columns } = this.states;
124288
- if (columns.some(({ type }) => type === "expand")) this.expand.toggle(row, expanded);
124289
- else this.tree.toggle(row, expanded);
124290
- }
124291
124476
  setExpandRowValueAdapter(val) {
124292
124477
  this.expand.reset(val);
124293
124478
  this.tree.expand(val);
124294
124479
  }
124295
- updateSelectionByRowKey() {
124296
- const { primaryKey } = this.table.props;
124297
- const { selection } = this.states;
124298
- const selectedMap = getValuesMap(selection, primaryKey);
124299
- this.states.selection = this.flatData.value.reduce((prev, row) => {
124300
- if (selectedMap[getRowValue(row, primaryKey)]) prev.push(row);
124301
- return prev;
124302
- }, []);
124303
- }
124304
- updateAllSelected() {
124305
- const { selectable, data = [] } = this.states;
124306
- if (data.length === 0) {
124307
- this.states.isAllSelected = false;
124308
- return;
124309
- }
124310
- let isAllSelected = true;
124311
- let selectedCount = 0;
124312
- const temp = this.flatData.value;
124313
- for (let i = 0, j = temp.length; i < j; i++) {
124314
- const row = temp[i];
124315
- const isRowSelectable = selectable && selectable.call(null, row, i);
124316
- if (!this.isSelected(row)) {
124317
- if (!selectable || isRowSelectable) {
124318
- isAllSelected = false;
124319
- break;
124320
- }
124321
- } else selectedCount++;
124322
- }
124323
- if (selectedCount === 0) isAllSelected = false;
124324
- this.states.isAllSelected = isAllSelected;
124325
- }
124326
124480
  updateTableScrollY() {
124327
124481
  (0, vue.nextTick)(() => this.table.exposed.updateScrollY());
124328
124482
  }
@@ -124332,8 +124486,8 @@ ${p}
124332
124486
  }
124333
124487
  };
124334
124488
  var useStates = (mapper, $store) => {
124335
- const store = $store || (0, vue.inject)("vc-table")?.store;
124336
- const states = (0, vue.reactive)({});
124489
+ const store = $store || (0, vue.inject)("vc-table").store;
124490
+ const states = {};
124337
124491
  Object.keys(mapper).forEach((key) => {
124338
124492
  const value = mapper[key];
124339
124493
  if (typeof value === "string") states[key] = (0, vue.computed)(() => {
@@ -124344,44 +124498,126 @@ ${p}
124344
124498
  });
124345
124499
  else console.error("invalid value type");
124346
124500
  });
124347
- return states;
124501
+ return (0, vue.reactive)(states);
124348
124502
  };
124503
+ /**
124504
+ * 非虚拟化路径:直接渲染块内容。
124505
+ * grid 下行高由内容撑开、同一 grid 行内 cell 高度天然同步,无需测高回写。
124506
+ */
124349
124507
  var NormalList = /* @__PURE__ */ (0, vue.defineComponent)({
124350
124508
  name: "vc-table-normal-list",
124351
124509
  props: { data: {
124352
124510
  type: Array,
124353
124511
  default: () => []
124354
124512
  } },
124355
- emits: ["row-resize"],
124356
- setup(props, { emit, slots }) {
124357
- let resizeChanges = [];
124358
- const emitChanges = () => {
124359
- if (resizeChanges.length > 0) {
124360
- emit("row-resize", resizeChanges);
124361
- resizeChanges = [];
124362
- }
124363
- };
124364
- const handleResize = (e, index) => {
124365
- resizeChanges.push({
124366
- index,
124367
- size: e.height
124368
- });
124369
- (0, vue.nextTick)(emitChanges);
124370
- };
124513
+ setup(props, { slots }) {
124371
124514
  return () => {
124372
- return props.data.map((mergeData, index) => {
124373
- return (0, vue.createVNode)(Resizer, {
124374
- "key": mergeData.id,
124375
- "fill": false,
124376
- "onResize": (e) => handleResize(e, index)
124377
- }, { default: () => [slots.default?.({
124378
- row: mergeData,
124515
+ return props.data.map((block, index) => {
124516
+ return (0, vue.createVNode)(vue.Fragment, { "key": block.id }, [slots.default?.({
124517
+ row: block,
124379
124518
  index
124380
- })] });
124519
+ })]);
124381
124520
  });
124382
124521
  };
124383
124522
  }
124384
124523
  });
124524
+ /**
124525
+ * 基于 CSS Grid 的公共布局层,header(多级表头)与 body(getSpan 合并块)共用。
124526
+ * - 列宽模板单源:表格内消费表根的 `--vc-table-columns` CSS 变量(layout 统一产出,
124527
+ * 列宽变化只写表根一个节点);独立使用时回退为按 columns 本地计算;
124528
+ * - cell 定位使用 grid-row/column-start + span,anchor cell 上输出 aria-rowspan/aria-colspan;
124529
+ * - rowStart 为虚拟化扩展点:cells 的 rowIndex 为绝对行号,按 rowStart 平移映射 grid 行号,
124530
+ * 未来若 RecycleList 支持跨窗口 anchor,可直接以窗口起始行号作为 rowStart 渲染窗口内 cells。
124531
+ */
124532
+ var TableGrid = /* @__PURE__ */ (0, vue.defineComponent)({
124533
+ name: "vc-table-grid",
124534
+ props: {
124535
+ columns: {
124536
+ type: Array,
124537
+ default: () => []
124538
+ },
124539
+ cells: {
124540
+ type: Array,
124541
+ default: () => []
124542
+ },
124543
+ rowStart: {
124544
+ type: Number,
124545
+ default: 0
124546
+ },
124547
+ rowHeight: [Number, String],
124548
+ role: {
124549
+ type: String,
124550
+ default: "rowgroup"
124551
+ },
124552
+ cellRole: {
124553
+ type: String,
124554
+ default: "cell"
124555
+ }
124556
+ },
124557
+ setup(props) {
124558
+ const table = (0, vue.inject)("vc-table", null);
124559
+ const localTemplateColumns = (0, vue.computed)(() => computeGridTemplateColumns(props.columns));
124560
+ const gridTemplateColumns = (0, vue.computed)(() => table ? "var(--vc-table-columns)" : localTemplateColumns.value);
124561
+ const rowHeight = (0, vue.computed)(() => parseHeight(props.rowHeight));
124562
+ return () => {
124563
+ const columnCount = props.columns.length;
124564
+ return (0, vue.createVNode)("div", {
124565
+ "class": "vc-table__grid",
124566
+ "role": props.role,
124567
+ "style": {
124568
+ gridTemplateColumns: gridTemplateColumns.value,
124569
+ gridAutoRows: rowHeight.value ? `${rowHeight.value}px` : void 0
124570
+ }
124571
+ }, [props.cells.map((cell) => {
124572
+ const rowspan = cell.rowspan || 1;
124573
+ const colspan = cell.colspan || 1;
124574
+ return (0, vue.createVNode)("div", (0, vue.mergeProps)(cell.attrs || {}, {
124575
+ "key": cell.key ?? `${cell.rowIndex}:${cell.columnIndex}`,
124576
+ "role": props.cellRole,
124577
+ "aria-rowspan": rowspan > 1 ? rowspan : void 0,
124578
+ "aria-colspan": colspan > 1 ? colspan : void 0,
124579
+ "class": [cell.class, {
124580
+ "is-grid-first": cell.columnIndex === 0,
124581
+ "is-grid-last": cell.columnIndex + colspan >= columnCount
124582
+ }],
124583
+ "style": [cell.style, {
124584
+ gridRow: `${cell.rowIndex - props.rowStart + 1} / span ${rowspan}`,
124585
+ gridColumn: `${cell.columnIndex + 1} / span ${colspan}`
124586
+ }]
124587
+ }), [cell.render?.(cell)]);
124588
+ })]);
124589
+ };
124590
+ }
124591
+ });
124592
+ /** @jsxImportSource vue */
124593
+ /**
124594
+ * 展开行内容:作为块内 `<TableGrid />` 的兄弟节点渲染,
124595
+ * 每个展开行输出一条全宽内容行(`vc-table__tr is-expanded` + 全宽 cell)。
124596
+ * 高度变化由块级 Resize 观察自然回馈到虚拟化布局。
124597
+ */
124598
+ var TableExpand = /* @__PURE__ */ (0, vue.defineComponent)({
124599
+ name: "vc-table-expand",
124600
+ props: { rows: {
124601
+ type: Array,
124602
+ default: () => []
124603
+ } },
124604
+ setup(props) {
124605
+ const table = (0, vue.inject)("vc-table");
124606
+ return () => {
124607
+ const renderExpand = table.renderExpand.value;
124608
+ if (!renderExpand) return null;
124609
+ return props.rows.map((row) => (0, vue.createVNode)("div", {
124610
+ "key": `expand-${row.index}`,
124611
+ "class": "vc-table__tr is-expanded",
124612
+ "data-row": row.index
124613
+ }, [(0, vue.createVNode)("div", { "class": "vc-table__td vc-table__expanded-cell" }, [renderExpand({
124614
+ row: row.data,
124615
+ rowIndex: row.index,
124616
+ store: table.store
124617
+ })])]));
124618
+ };
124619
+ }
124620
+ });
124385
124621
  var HIDDEN_TEXT_STYLE = `
124386
124622
  position: absolute!important;
124387
124623
  word-break: break-all!important;
@@ -124454,19 +124690,21 @@ ${p}
124454
124690
  }
124455
124691
  return endIndex;
124456
124692
  };
124457
- var TableBodyRow = /* @__PURE__ */ (0, vue.defineComponent)({
124458
- name: "vc-table-body-row",
124459
- props: {
124460
- data: {
124461
- type: Object,
124462
- required: true
124463
- },
124464
- index: {
124465
- type: Number,
124466
- required: true
124467
- },
124468
- height: { type: [Number, String] }
124469
- },
124693
+ /** @jsxImportSource vue */
124694
+ /**
124695
+ * 块渲染(虚拟化最小单位):
124696
+ * - 单行块(无合并,绝大多数场景):容器即 `vc-table__tr`(行语义 + grid 容器 + cells 直接父级);
124697
+ * - 多行合并块:容器为 `vc-table__tr-group`;用户 row-class/row-style 无效;
124698
+ * - stripe / highlight / expand 等内部行态统一挂 cell;用户 row-class/row-style 仍仅挂单行块 `vc-table__tr`;
124699
+ * - cell 事件走容器级委托(cells 只带 data-row / data-column,无 per-cell 闭包);
124700
+ * - 展开行以 `<TableGrid /> + <TableExpand />` 兄弟结构渲染在块内。
124701
+ */
124702
+ var TableBodyBlock = /* @__PURE__ */ (0, vue.defineComponent)({
124703
+ name: "vc-table-body-block",
124704
+ props: { store: {
124705
+ type: Object,
124706
+ required: true
124707
+ } },
124470
124708
  setup(props) {
124471
124709
  const table = (0, vue.inject)("vc-table");
124472
124710
  const states = useStates({
@@ -124474,20 +124712,10 @@ ${p}
124474
124712
  currentRow: "currentRow",
124475
124713
  expandRows: "expandRows"
124476
124714
  });
124477
- const selected = (0, vue.computed)(() => table.store.isSelected(props.data));
124478
- const maxColumnIndex = (0, vue.computed)(() => states.columns.length - 1);
124479
- const getRowClass = (row, rowIndex) => {
124480
- const classes = ["vc-table__row"];
124481
- if (table.props.highlight && row === states.currentRow) classes.push("current-row");
124482
- if (table.props.stripe && rowIndex % 2 === 1) classes.push("vc-table__row--striped");
124483
- const rowClass = table.props.rowClass;
124484
- if (typeof rowClass === "string") classes.push(rowClass);
124485
- else if (typeof rowClass === "function") classes.push(rowClass.call(null, {
124486
- row,
124487
- rowIndex
124488
- }));
124489
- if (states.expandRows.indexOf(row) > -1) classes.push("expanded");
124490
- return classes;
124715
+ const getValueOfRow = (row, index) => {
124716
+ const { primaryKey } = table.props;
124717
+ if (primaryKey) return getRowValue(row, primaryKey);
124718
+ return index;
124491
124719
  };
124492
124720
  const getCellStyle = (rowIndex, columnIndex, row, column) => {
124493
124721
  const { cellStyle } = table.props;
@@ -124518,7 +124746,23 @@ ${p}
124518
124746
  }));
124519
124747
  return classes.join(" ");
124520
124748
  };
124521
- const getRowStyle = (row, rowIndex) => {
124749
+ const getInternalCellClass = (row, rowIndex) => {
124750
+ const classes = [];
124751
+ if (table.props.highlight && row === states.currentRow) classes.push("current-row");
124752
+ if (table.props.stripe && rowIndex % 2 === 1) classes.push("vc-table__row--striped", "is-striped");
124753
+ if (states.expandRows.indexOf(row) > -1) classes.push("expanded");
124754
+ return classes;
124755
+ };
124756
+ const getUserRowClass = (row, rowIndex) => {
124757
+ const { rowClass } = table.props;
124758
+ if (typeof rowClass === "string") return rowClass;
124759
+ if (typeof rowClass === "function") return rowClass.call(null, {
124760
+ row,
124761
+ rowIndex
124762
+ });
124763
+ return "";
124764
+ };
124765
+ const getUserRowStyle = (row, rowIndex) => {
124522
124766
  const { rowStyle } = table.props;
124523
124767
  if (typeof rowStyle === "function") return rowStyle.call(null, {
124524
124768
  row,
@@ -124526,19 +124770,35 @@ ${p}
124526
124770
  });
124527
124771
  return rowStyle || null;
124528
124772
  };
124529
- let poper;
124530
- const handleCellMouseEnter = (e, row, column) => {
124531
- const cell = getCell(e);
124532
- const hoverState = {
124533
- cell,
124534
- column,
124535
- row
124536
- };
124537
- if (cell) {
124538
- table.hoverState.value = hoverState;
124539
- table.emit("cell-mouse-enter", hoverState.row, hoverState.column, hoverState.cell, e);
124773
+ const resolveCellEl = (e) => {
124774
+ const root = e.currentTarget;
124775
+ let node = e.target;
124776
+ while (node && node !== root) {
124777
+ if (node.parentElement === root) return node.classList?.contains?.("vc-table__td") ? node : null;
124778
+ node = node.parentElement;
124540
124779
  }
124541
- const el = e.target.querySelector(".vc-table__text-line");
124780
+ return null;
124781
+ };
124782
+ const resolveCell = (e) => {
124783
+ const cellEl = resolveCellEl(e);
124784
+ if (!cellEl) return null;
124785
+ const rowIndex = Number(cellEl.dataset.row);
124786
+ const columnIndex = Number(cellEl.dataset.column);
124787
+ const rowStart = props.store.rowStart ?? (props.store.rows[0]?.index || 0);
124788
+ const row = props.store.rows[rowIndex - rowStart];
124789
+ const columnNode = states.columns[columnIndex];
124790
+ if (!row || !columnNode) return null;
124791
+ return {
124792
+ cellEl,
124793
+ row: row.data,
124794
+ rowIndex,
124795
+ column: columnNode.states,
124796
+ columnIndex
124797
+ };
124798
+ };
124799
+ let poper;
124800
+ const showTextLineTooltip = (cellEl, row, column) => {
124801
+ const el = cellEl.querySelector(".vc-table__text-line");
124542
124802
  const line = typeof column.line !== "undefined" ? column.line : VcInstance.options.TableColumn?.line;
124543
124803
  if (!el || !line) return;
124544
124804
  const value = `${row[column.prop]}`;
@@ -124561,101 +124821,132 @@ ${p}
124561
124821
  });
124562
124822
  }
124563
124823
  };
124564
- const handleCellMouseLeave = (e, row, column) => {
124565
- const cell = getCell(e);
124566
- if (!cell) return;
124567
- table.emit("cell-mouse-leave", row, column, cell, e);
124568
- };
124569
- const handleMouseEnter = debounce((index) => {
124570
- table.store.setHoverRow(index);
124824
+ const handleHoverEnter = debounce((index) => {
124825
+ table.store.row.setHoverIndex(index);
124571
124826
  }, 30);
124572
- const handleMouseLeave = debounce(() => {
124573
- table.store.setHoverRow(null);
124827
+ const handleHoverLeave = debounce(() => {
124828
+ table.store.row.setHoverIndex(null);
124574
124829
  }, 30);
124575
- const handleEvent = (e, row, name) => {
124576
- const cell = getCell(e);
124577
- let column;
124578
- if (cell) {
124579
- column = getColumnByCell(states.columns, cell);
124580
- if (column) table.emit(`cell-${name}`, row, column, cell, e);
124581
- }
124582
- table.emit(`row-${name}`, row, column, e);
124830
+ const enterCell = (e, cell) => {
124831
+ handleHoverEnter(cell.rowIndex);
124832
+ table.hoverState.value = {
124833
+ cell: cell.cellEl,
124834
+ column: cell.column,
124835
+ row: cell.row
124836
+ };
124837
+ table.emit("cell-mouse-enter", cell.row, cell.column, cell.cellEl, e);
124838
+ showTextLineTooltip(cell.cellEl, cell.row, cell.column);
124583
124839
  };
124584
- const handleContextMenu = (e, row) => {
124585
- handleEvent(e, row, "contextmenu");
124840
+ const leaveCell = (e, cell) => {
124841
+ table.emit("cell-mouse-leave", cell.row, cell.column, cell.cellEl, e);
124586
124842
  };
124587
- const handleDoubleClick = (e, row) => {
124588
- handleEvent(e, row, "dblclick");
124843
+ let activeCell = null;
124844
+ const handleMouseOver = (e) => {
124845
+ const cell = resolveCell(e);
124846
+ if (activeCell && cell && activeCell.cellEl === cell.cellEl) return;
124847
+ if (activeCell) leaveCell(e, activeCell);
124848
+ activeCell = cell;
124849
+ if (cell) enterCell(e, cell);
124589
124850
  };
124590
- const handleClick = (e, row) => {
124591
- table.store.setCurrentRow(row);
124592
- handleEvent(e, row, "click");
124851
+ const handleMouseLeave = (e) => {
124852
+ if (activeCell) {
124853
+ leaveCell(e, activeCell);
124854
+ activeCell = null;
124855
+ }
124856
+ handleHoverLeave();
124857
+ };
124858
+ const handleEvent = (e, name) => {
124859
+ const cell = resolveCell(e);
124860
+ if (!cell) return;
124861
+ table.emit(`cell-${name}`, cell.row, cell.column, cell.cellEl, e);
124862
+ table.emit(`row-${name}`, cell.row, cell.column, e);
124863
+ return cell;
124864
+ };
124865
+ const handleClick = (e) => {
124866
+ const cell = resolveCell(e);
124867
+ if (!cell) return;
124868
+ table.store.row.set(cell.row);
124869
+ table.emit("cell-click", cell.row, cell.column, cell.cellEl, e);
124870
+ table.emit("row-click", cell.row, cell.column, e);
124593
124871
  };
124594
124872
  (0, vue.onBeforeUnmount)(() => {
124595
124873
  poper && poper.destroy();
124874
+ handleHoverEnter.cancel();
124875
+ handleHoverLeave.cancel();
124596
124876
  });
124597
124877
  return () => {
124598
- return (0, vue.createVNode)("div", {
124599
- "class": [getRowClass(props.data, props.index), "vc-table__tr"],
124600
- "style": getRowStyle(props.data, props.index),
124601
- "data-row": props.index,
124602
- "onDblclick": (e) => handleDoubleClick(e, props.data),
124603
- "onClick": (e) => handleClick(e, props.data),
124604
- "onContextmenu": (e) => handleContextMenu(e, props.data),
124605
- "onMouseenter": () => handleMouseEnter(props.index),
124606
- "onMouseleave": () => handleMouseLeave()
124607
- }, [states.columns.map((column, columnIndex) => {
124608
- const { realWidth, renderCell } = column;
124609
- const sizeStyle = {
124610
- width: `${realWidth}px`,
124611
- height: `${props.height ? `${props.height}px` : "auto"}`
124612
- };
124613
- return (0, vue.createVNode)("div", {
124614
- "key": column.id,
124615
- "style": [
124616
- getCellStyle(props.index, columnIndex, props.data, column),
124617
- sizeStyle,
124618
- column.stickyStyle
124878
+ const block = props.store;
124879
+ const columns = states.columns;
124880
+ const rows = block.rows;
124881
+ const isSingleRow = rows.length === 1;
124882
+ const maxColumnIndex = columns.length - 1;
124883
+ const rowStart = block.rowStart ?? (rows[0]?.index || 0);
124884
+ let layoutCells = block.cells;
124885
+ if (!layoutCells) {
124886
+ layoutCells = [];
124887
+ for (let i = 0; i < rows.length; i++) for (let c = 0; c < columns.length; c++) layoutCells.push({
124888
+ rowIndex: rows[i].index,
124889
+ columnIndex: c,
124890
+ rowspan: 1,
124891
+ colspan: 1
124892
+ });
124893
+ }
124894
+ const rowSelected = rows.map((row) => table.store.selection.isSelected(row.data));
124895
+ const singleRow = isSingleRow ? rows[0] : null;
124896
+ const cells = layoutCells.reduce((pre, cell) => {
124897
+ const rowOffset = cell.rowIndex - rowStart;
124898
+ const row = rows[rowOffset];
124899
+ const columnNode = columns[cell.columnIndex];
124900
+ if (!row || !columnNode) return pre;
124901
+ const column = columnNode.states;
124902
+ pre.push({
124903
+ key: `${getValueOfRow(row.data, row.index)}-${column.id}`,
124904
+ rowIndex: cell.rowIndex,
124905
+ columnIndex: cell.columnIndex,
124906
+ rowspan: cell.rowspan,
124907
+ colspan: cell.colspan,
124908
+ class: [
124909
+ getInternalCellClass(row.data, cell.rowIndex),
124910
+ getCellClass(cell.rowIndex, cell.columnIndex, row.data, column),
124911
+ "vc-table__td"
124619
124912
  ],
124620
- "class": [getCellClass(props.index, columnIndex, props.data, column), "vc-table__td"],
124621
- "onMouseenter": (e) => handleCellMouseEnter(e, props.data, column),
124622
- "onMouseleave": (e) => handleCellMouseLeave(e, props.data, column)
124623
- }, [renderCell({
124624
- row: props.data,
124625
- rowIndex: props.index,
124626
- column,
124627
- columnIndex,
124628
- selected: selected.value,
124629
- store: table.store,
124630
- isHead: columnIndex === 0,
124631
- isTail: columnIndex === maxColumnIndex.value
124632
- })]);
124633
- })]);
124634
- };
124635
- }
124636
- });
124637
- var TableBodyMergeRow = /* @__PURE__ */ (0, vue.defineComponent)({
124638
- name: "vc-table-body-merge-row",
124639
- props: { store: {
124640
- type: Object,
124641
- required: true
124642
- } },
124643
- setup(props) {
124644
- const table = (0, vue.inject)("vc-table");
124645
- const getValueOfRow = (row, index) => {
124646
- const { primaryKey } = table.props;
124647
- if (primaryKey) return getRowValue(row, primaryKey);
124648
- return index;
124649
- };
124650
- return () => {
124651
- return (0, vue.createVNode)("div", { "class": "vc-table__merge-row" }, [props.store.rows.map((row) => {
124652
- return (0, vue.createVNode)(TableBodyRow, {
124653
- "key": getValueOfRow(row, row.index),
124654
- "data": row.data,
124655
- "index": row.index,
124656
- "height": table.props.rowHeight || row.height
124657
- }, null);
124658
- })]);
124913
+ style: [getCellStyle(cell.rowIndex, cell.columnIndex, row.data, column), column.stickyStyle],
124914
+ attrs: {
124915
+ "data-row": cell.rowIndex,
124916
+ "data-column": cell.columnIndex
124917
+ },
124918
+ render: () => column.renderCell({
124919
+ row: row.data,
124920
+ rowIndex: cell.rowIndex,
124921
+ column,
124922
+ columnIndex: cell.columnIndex,
124923
+ selected: rowSelected[rowOffset],
124924
+ store: table.store,
124925
+ isHead: cell.columnIndex === 0,
124926
+ isTail: cell.columnIndex + (cell.colspan || 1) - 1 === maxColumnIndex
124927
+ })
124928
+ });
124929
+ return pre;
124930
+ }, []);
124931
+ const grid = (0, vue.createVNode)(TableGrid, (0, vue.mergeProps)({
124932
+ "class": [isSingleRow ? "vc-table__tr" : "vc-table__tr-group", isSingleRow && getUserRowClass(singleRow.data, singleRow.index)],
124933
+ "style": isSingleRow ? getUserRowStyle(singleRow.data, singleRow.index) : null,
124934
+ "data-row": isSingleRow ? rowStart : void 0,
124935
+ "role": isSingleRow ? "row" : "rowgroup",
124936
+ "columns": columns,
124937
+ "rowStart": rowStart,
124938
+ "rowHeight": table.props.rowHeight,
124939
+ "cells": cells
124940
+ }, {
124941
+ onClick: handleClick,
124942
+ onDblclick: (e) => handleEvent(e, "dblclick"),
124943
+ onContextmenu: (e) => handleEvent(e, "contextmenu"),
124944
+ onMouseover: handleMouseOver,
124945
+ onMouseleave: handleMouseLeave
124946
+ }), null);
124947
+ const expandedRows = isSingleRow && table.renderExpand.value ? rows.filter((row) => states.expandRows.indexOf(row.data) > -1) : [];
124948
+ if (!expandedRows.length) return grid;
124949
+ return (0, vue.createVNode)(vue.Fragment, null, [grid, (0, vue.createVNode)(TableExpand, { "rows": expandedRows }, null)]);
124659
124950
  };
124660
124951
  }
124661
124952
  });
@@ -124681,23 +124972,25 @@ ${p}
124681
124972
  });
124682
124973
  const target = (0, vue.ref)();
124683
124974
  (0, vue.watch)(() => table.store.states.hoverRowIndex, (v, oldV) => {
124684
- if (!table.store.states.isComplex || IS_SERVER$3) return;
124975
+ if (IS_SERVER$3) return;
124685
124976
  raf(() => {
124686
- const oldRow = instance.vnode.el.querySelector(`.vc-table__row[data-row="${oldV}"]`);
124687
- const newRow = instance.vnode.el.querySelector(`.vc-table__row[data-row="${v}"]`);
124688
- oldRow && removeClass(oldRow, "hover-row");
124689
- newRow && addClass(newRow, "hover-row");
124690
- });
124691
- });
124692
- const handleMergeRowResize = (changes) => {
124693
- if (table.props.rowHeight) return;
124694
- changes.forEach((v) => {
124695
- states.list[v.index].rows.forEach((row) => {
124696
- if (row.height === v.size) return;
124697
- row.height = v.size || "";
124698
- });
124977
+ const el = instance.vnode.el;
124978
+ if (!el) return;
124979
+ const selectRow = (index) => el.querySelectorAll(`.vc-table__td[data-row="${index}"]`);
124980
+ const selectAnchors = (index) => {
124981
+ if (index == null) return [];
124982
+ return table.store.block.getCoverAnchors(index).reduce((pre, anchor) => {
124983
+ const dom = el.querySelector(`.vc-table__td[data-row="${anchor.rowIndex}"][data-column="${anchor.columnIndex}"]`);
124984
+ dom && pre.push(dom);
124985
+ return pre;
124986
+ }, []);
124987
+ };
124988
+ selectRow(oldV).forEach((dom) => removeClass(dom, "hover-row"));
124989
+ selectAnchors(oldV).forEach((dom) => removeClass(dom, "hover-related"));
124990
+ selectRow(v).forEach((dom) => addClass(dom, "hover-row"));
124991
+ selectAnchors(v).forEach((dom) => addClass(dom, "hover-related"));
124699
124992
  });
124700
- };
124993
+ });
124701
124994
  expose({ target });
124702
124995
  const layout = table.layout;
124703
124996
  const scrollerOptions = (0, vue.computed)(() => ({
@@ -124715,7 +125008,7 @@ ${p}
124715
125008
  0
124716
125009
  ]
124717
125010
  }));
124718
- const renderers = { default: ({ row }) => (0, vue.createVNode)(TableBodyMergeRow, { "store": row }, null) };
125011
+ const renderers = { default: ({ row }) => (0, vue.createVNode)(TableBodyBlock, { "store": row }, null) };
124719
125012
  let timer;
124720
125013
  (0, vue.onBeforeMount)(() => {
124721
125014
  if (table.props.delay) timer = setTimeout(() => allowRender.value = true, table.props.delay);
@@ -124734,7 +125027,6 @@ ${p}
124734
125027
  "scrollerOptions": scrollerOptions.value,
124735
125028
  "pageSize": table.props.rows,
124736
125029
  "onScroll": (e) => emit("scroll", e),
124737
- "onRowResize": handleMergeRowResize,
124738
125030
  "style": props.heightStyle
124739
125031
  }, _isSlot(renderers) ? renderers : { default: () => [renderers] }), slots.default?.()]);
124740
125032
  return (0, vue.createVNode)(ScrollerWheel, (0, vue.mergeProps)({
@@ -124743,10 +125035,7 @@ ${p}
124743
125035
  }, scrollerOptions.value, {
124744
125036
  "style": props.heightStyle,
124745
125037
  "onScroll": (e) => emit("scroll", e)
124746
- }), { default: () => [(0, vue.createVNode)(NormalList, {
124747
- "data": states.list,
124748
- "onRowResize": handleMergeRowResize
124749
- }, _isSlot(renderers) ? renderers : { default: () => [renderers] }), slots.default?.()] });
125038
+ }), { default: () => [(0, vue.createVNode)(NormalList, { "data": states.list }, _isSlot(renderers) ? renderers : { default: () => [renderers] }), slots.default?.()] });
124750
125039
  };
124751
125040
  }
124752
125041
  });
@@ -124802,17 +125091,16 @@ ${p}
124802
125091
  isGroup: "isGroup",
124803
125092
  headerRows: "headerRows"
124804
125093
  });
124805
- const getHeaderRowStyle = (rowIndex) => {
125094
+ const getHeaderRowStyle = () => {
124806
125095
  const { headerRowStyle } = table.props;
124807
- if (typeof headerRowStyle === "function") return headerRowStyle.call(null, { rowIndex });
125096
+ if (typeof headerRowStyle === "function") return headerRowStyle.call(null);
124808
125097
  return headerRowStyle;
124809
125098
  };
124810
- const getHeaderRowClass = (rowIndex) => {
124811
- const classes = [];
125099
+ const getHeaderRowClass = () => {
124812
125100
  const { headerRowClass } = table.props;
124813
- if (typeof headerRowClass === "string") classes.push(headerRowClass);
124814
- else if (typeof headerRowClass === "function") classes.push(headerRowClass.call(null, { rowIndex }));
124815
- return classes.join(" ");
125101
+ if (typeof headerRowClass === "string") return headerRowClass;
125102
+ if (typeof headerRowClass === "function") return headerRowClass.call(null);
125103
+ return "";
124816
125104
  };
124817
125105
  const getHeaderCellStyle = (rowIndex, columnIndex, row, column) => {
124818
125106
  const { headerCellStyle } = table.props;
@@ -124820,47 +125108,48 @@ ${p}
124820
125108
  rowIndex,
124821
125109
  columnIndex,
124822
125110
  row,
124823
- column
125111
+ column: column.states
124824
125112
  });
124825
125113
  return {
124826
125114
  ...headerCellStyle,
124827
- ...column.style
125115
+ ...column.states.style
124828
125116
  };
124829
125117
  };
124830
125118
  const getHeaderCellClass = (rowIndex, columnIndex, row, column) => {
125119
+ const { states: columnStates } = column;
124831
125120
  const classes = [
124832
- column.id,
124833
- column.order,
124834
- column.realHeaderAlign,
124835
- column.class,
124836
- column.labelClass
125121
+ columnStates.id,
125122
+ columnStates.order,
125123
+ columnStates.realHeaderAlign,
125124
+ columnStates.class,
125125
+ columnStates.labelClass
124837
125126
  ];
124838
- if (!column.children) classes.push("is-leaf");
125127
+ if (!column.childNodes.length) classes.push("is-leaf");
124839
125128
  const { headerCellClass } = table.props;
124840
125129
  if (typeof headerCellClass === "string") classes.push(headerCellClass);
124841
125130
  else if (typeof headerCellClass === "function") classes.push(headerCellClass.call(null, {
124842
125131
  rowIndex,
124843
125132
  columnIndex,
124844
125133
  row,
124845
- column
125134
+ column: columnStates
124846
125135
  }));
124847
125136
  return classes.join(" ");
124848
125137
  };
124849
125138
  const handleHeaderClick = (e, column) => {
124850
- table.emit("header-click", column, e);
125139
+ table.emit("header-click", column.states, e);
124851
125140
  };
124852
125141
  const handleHeaderContextMenu = (e, column) => {
124853
- table.emit("header-contextmenu", column, e);
125142
+ table.emit("header-contextmenu", column.states, e);
124854
125143
  };
124855
125144
  const handleMouseDown = (e, column) => {
124856
125145
  if (IS_SERVER$3) return;
124857
- if (column.children && column.children.length > 0) return;
125146
+ if (column.childNodes.length > 0) return;
124858
125147
  /* istanbul ignore if */
124859
125148
  if (draggingColumn.value && allowDrag.value) {
124860
125149
  dragging.value = true;
124861
125150
  table.resizeProxyVisible.value = true;
124862
125151
  const tableLeft = table.tableWrapper.value.getBoundingClientRect().left;
124863
- const columnEl = instance.vnode.el.querySelector(`.vc-table__th.${column.id}`);
125152
+ const columnEl = instance.vnode.el.querySelector(`.vc-table__th.${column.states.id}`);
124864
125153
  const columnRect = columnEl.getBoundingClientRect();
124865
125154
  const minLeft = columnRect.left - tableLeft + 30;
124866
125155
  addClass(columnEl, "noclick");
@@ -124874,16 +125163,17 @@ ${p}
124874
125163
  resizeProxy.style.left = dragState.value.startLeft + "px";
124875
125164
  document.onselectstart = () => false;
124876
125165
  document.ondragstart = () => false;
124877
- const handleMouseMove = ($e) => {
125166
+ const handleDocumentMouseMove = ($e) => {
124878
125167
  const deltaLeft = $e.clientX - dragState.value.startMouseLeft;
124879
125168
  const proxyLeft = dragState.value.startLeft + deltaLeft;
124880
125169
  resizeProxy.style.left = Math.max(minLeft, proxyLeft) + "px";
124881
125170
  };
124882
- const handleMouseUp = () => {
125171
+ const handleDocumentMouseUp = () => {
124883
125172
  if (dragging.value) {
124884
125173
  const { startColumnLeft, startLeft } = dragState.value;
124885
- column.width = column.minWidth = column.realWidth = parseInt(resizeProxy.style.left, 10) - startColumnLeft;
124886
- table.emit("header-dragend", column.width, startLeft - startColumnLeft, column);
125174
+ const columnWidth = parseInt(resizeProxy.style.left, 10) - startColumnLeft;
125175
+ column.states.width = column.states.minWidth = column.states.realWidth = columnWidth;
125176
+ table.emit("header-dragend", column.states.width, startLeft - startColumnLeft, column.states);
124887
125177
  table.store.scheduleLayout();
124888
125178
  document.body.style.cursor = "";
124889
125179
  dragging.value = false;
@@ -124891,23 +125181,23 @@ ${p}
124891
125181
  dragState.value = {};
124892
125182
  table.resizeProxyVisible.value = false;
124893
125183
  }
124894
- document.removeEventListener("mousemove", handleMouseMove);
124895
- document.removeEventListener("mouseup", handleMouseUp);
125184
+ document.removeEventListener("mousemove", handleDocumentMouseMove);
125185
+ document.removeEventListener("mouseup", handleDocumentMouseUp);
124896
125186
  document.onselectstart = null;
124897
125187
  document.ondragstart = null;
124898
125188
  setTimeout(function() {
124899
125189
  removeClass(columnEl, "noclick");
124900
125190
  }, 0);
124901
125191
  };
124902
- document.addEventListener("mousemove", handleMouseMove);
124903
- document.addEventListener("mouseup", handleMouseUp);
125192
+ document.addEventListener("mousemove", handleDocumentMouseMove);
125193
+ document.addEventListener("mouseup", handleDocumentMouseUp);
124904
125194
  }
124905
125195
  };
124906
125196
  const handleMouseMove = (event, column) => {
124907
- if (column.children && column.children.length > 0) return;
125197
+ if (column.childNodes.length > 0) return;
124908
125198
  let target = event.target;
124909
125199
  while (target && !target.classList?.contains?.("vc-table__th")) target = target.parentNode;
124910
- if (!column || !column.resizable) return;
125200
+ if (!column || !column.states.resizable || !target) return;
124911
125201
  if (!dragging.value && allowDrag.value) {
124912
125202
  const rect = target.getBoundingClientRect();
124913
125203
  const bodyStyle = document.body.style;
@@ -124950,54 +125240,87 @@ ${p}
124950
125240
  alone: true
124951
125241
  });
124952
125242
  };
125243
+ const renderCellContent = (column, columnIndex) => {
125244
+ const { states: columnStates } = column;
125245
+ return (0, vue.createVNode)("div", { "class": ["vc-table__cell", columnStates.labelClass] }, [
125246
+ columnStates.renderHeader ? columnStates.renderHeader({
125247
+ column: columnStates,
125248
+ columnIndex,
125249
+ store: table.store
125250
+ }) : columnStates.label,
125251
+ columnStates.tooltip ? (0, vue.createVNode)(Icon, {
125252
+ "type": "o-info",
125253
+ "class": "vc-table__tooltip",
125254
+ "onMouseenter": (e) => handleCellMouseEnter(e, columnStates)
125255
+ }, null) : null,
125256
+ columnStates.sortable ? (0, vue.createVNode)(TableSort, {
125257
+ "order": columnStates.prop === props.sort.prop ? props.sort.order : "",
125258
+ "onClick": (order) => handleSort(columnStates.prop, order)
125259
+ }, null) : null,
125260
+ columnStates.filters ? (0, vue.createVNode)(TableFilter, {
125261
+ "data": columnStates.filters,
125262
+ "value": columnStates.filteredValue,
125263
+ "icon": columnStates.filterIcon,
125264
+ "portalClass": columnStates.filterPopupClass,
125265
+ "multiple": columnStates.filterMultiple,
125266
+ "onChange": (v) => handleFilter(columnStates, v)
125267
+ }, null) : null
125268
+ ]);
125269
+ };
125270
+ /**
125271
+ * 把 states.headerRows(二维,多级表头)推导为 TableGrid 的 cells[]:
125272
+ * 多级表头本质就是 rowspan/colspan(columnsToRowsEffect 已写在 column.states 上),
125273
+ * 这里只需按占位推导每个 cell 的起始叶子列号(grid 列坐标)。
125274
+ * 注意:headerRowStyle/Class 挂在 thead 内唯一 vc-table__tr 上,不再合并到 th。
125275
+ * @returns 表头 cells
125276
+ */
125277
+ const buildHeaderCells = () => {
125278
+ const rows = states.headerRows;
125279
+ const cells = [];
125280
+ const taken = rows.map(() => []);
125281
+ rows.forEach((columns, rowIndex) => {
125282
+ let gridColumnIndex = 0;
125283
+ columns.forEach((column, columnIndex) => {
125284
+ while (taken[rowIndex][gridColumnIndex]) gridColumnIndex++;
125285
+ const rowspan = column.states.rowspan || 1;
125286
+ const colspan = column.states.colspan || 1;
125287
+ for (let i = rowIndex; i < rowIndex + rowspan && i < rows.length; i++) for (let j = gridColumnIndex; j < gridColumnIndex + colspan; j++) taken[i][j] = true;
125288
+ cells.push({
125289
+ key: column.states.id,
125290
+ rowIndex,
125291
+ columnIndex: gridColumnIndex,
125292
+ rowspan,
125293
+ colspan,
125294
+ class: [
125295
+ getHeaderCellClass(rowIndex, columnIndex, columns, column),
125296
+ column.states.resizable && dragLineClass.value,
125297
+ column.states.stickyClass,
125298
+ "vc-table__th"
125299
+ ],
125300
+ style: [getHeaderCellStyle(rowIndex, columnIndex, columns, column), column.states.stickyStyle],
125301
+ attrs: {
125302
+ onMousemove: (e) => handleMouseMove(e, column),
125303
+ onMouseout: handleMouseOut,
125304
+ onMousedown: (e) => handleMouseDown(e, column),
125305
+ onClick: (e) => handleHeaderClick(e, column),
125306
+ onContextmenu: (e) => handleHeaderContextMenu(e, column)
125307
+ },
125308
+ render: () => renderCellContent(column, columnIndex)
125309
+ });
125310
+ gridColumnIndex += colspan;
125311
+ });
125312
+ });
125313
+ return cells;
125314
+ };
124953
125315
  return () => {
124954
- return (0, vue.createVNode)("div", { "class": "vc-table__header" }, [(0, vue.createVNode)("div", { "class": [{ "is-group": states.isGroup }, "vc-table__thead"] }, [states.headerRows.map((columns, rowIndex) => (0, vue.createVNode)("div", {
124955
- "style": getHeaderRowStyle(rowIndex),
124956
- "class": [getHeaderRowClass(rowIndex), "vc-table__tr"]
124957
- }, [columns.map((column, columnIndex) => {
124958
- return (0, vue.createVNode)("div", {
124959
- "onMousemove": (e) => handleMouseMove(e, column),
124960
- "onMouseout": handleMouseOut,
124961
- "onMousedown": (e) => handleMouseDown(e, column),
124962
- "onClick": (e) => handleHeaderClick(e, column),
124963
- "onContextmenu": (e) => handleHeaderContextMenu(e, column),
124964
- "style": [
124965
- getHeaderCellStyle(rowIndex, columnIndex, columns, column),
124966
- { width: `${column.realWidth}px` },
124967
- column.stickyStyle
124968
- ],
124969
- "class": [
124970
- getHeaderCellClass(rowIndex, columnIndex, columns, column),
124971
- column.resizable && dragLineClass.value,
124972
- column.stickyClass,
124973
- "vc-table__th"
124974
- ],
124975
- "key": column.id
124976
- }, [(0, vue.createVNode)("div", { "class": ["vc-table__cell", column.labelClass] }, [
124977
- column.renderHeader ? column.renderHeader({
124978
- column,
124979
- columnIndex,
124980
- store: table.store
124981
- }) : column.label,
124982
- column.tooltip ? (0, vue.createVNode)(Icon, {
124983
- "type": "o-info",
124984
- "class": "vc-table__tooltip",
124985
- "onMouseenter": (e) => handleCellMouseEnter(e, column)
124986
- }, null) : null,
124987
- column.sortable ? (0, vue.createVNode)(TableSort, {
124988
- "order": column.prop === props.sort.prop ? props.sort.order : "",
124989
- "onClick": (order) => handleSort(column.prop, order)
124990
- }, null) : null,
124991
- column.filters ? (0, vue.createVNode)(TableFilter, {
124992
- "data": column.filters,
124993
- "value": column.filteredValue,
124994
- "icon": column.filterIcon,
124995
- "portalClass": column.filterPopupClass,
124996
- "multiple": column.filterMultiple,
124997
- "onChange": (v) => handleFilter(column, v)
124998
- }, null) : null
124999
- ])]);
125000
- })]))])]);
125316
+ return (0, vue.createVNode)("div", { "class": [{ "is-group": states.isGroup }, "vc-table__thead"] }, [(0, vue.createVNode)(TableGrid, {
125317
+ "class": [getHeaderRowClass(), "vc-table__tr"],
125318
+ "style": getHeaderRowStyle(),
125319
+ "role": "row",
125320
+ "columns": states.columns,
125321
+ "cells": buildHeaderCells(),
125322
+ "cellRole": "columnheader"
125323
+ }, null)]);
125001
125324
  };
125002
125325
  }
125003
125326
  });
@@ -125016,19 +125339,19 @@ ${p}
125016
125339
  });
125017
125340
  const getRowClasses = (column) => {
125018
125341
  const classes = [column.realAlign, column.labelClass];
125019
- if (column.className) classes.push(column.className);
125020
125342
  if (column.fixed === true || column.fixed === "left") classes.push("is-fixed-left");
125021
125343
  else if (column.fixed === "right") classes.push("is-fixed-right");
125022
- if (!column.children) classes.push("is-leaf");
125344
+ classes.push("is-leaf");
125023
125345
  return classes;
125024
125346
  };
125025
125347
  const sums = (0, vue.computed)(() => {
125026
125348
  let v = [];
125349
+ const columnStates = states.columns.map((node) => node.states);
125027
125350
  if (props.getSummary) v = props.getSummary({
125028
- columns: states.columns,
125351
+ columns: columnStates,
125029
125352
  data: states.data
125030
125353
  });
125031
- else states.columns.forEach((column, index) => {
125354
+ else columnStates.forEach((column, index) => {
125032
125355
  if (index === 0) {
125033
125356
  v[index] = props.sumText;
125034
125357
  return;
@@ -125059,7 +125382,8 @@ ${p}
125059
125382
  "cellspacing": "0",
125060
125383
  "cellpadding": "0",
125061
125384
  "border": "0"
125062
- }, [(0, vue.createVNode)("div", { "class": "vc-table__tbody" }, [(0, vue.createVNode)("div", { "class": "vc-table__tr" }, [states.columns.map((column, columnIndex) => {
125385
+ }, [(0, vue.createVNode)("div", { "class": "vc-table__tbody" }, [(0, vue.createVNode)("div", { "class": "vc-table__tr" }, [states.columns.map((node, columnIndex) => {
125386
+ const column = node.states;
125063
125387
  return (0, vue.createVNode)("div", {
125064
125388
  "key": columnIndex,
125065
125389
  "class": [getRowClasses(column), "vc-table__td"],
@@ -125192,6 +125516,7 @@ ${p}
125192
125516
  "cell-mouse-leave",
125193
125517
  "cell-click",
125194
125518
  "cell-dblclick",
125519
+ "cell-contextmenu",
125195
125520
  "row-click",
125196
125521
  "row-contextmenu",
125197
125522
  "row-dblclick",
@@ -125208,7 +125533,7 @@ ${p}
125208
125533
  const instance = (0, vue.getCurrentInstance)();
125209
125534
  const store = new Store$1({ table: instance });
125210
125535
  const { layout } = store;
125211
- const renderExpanded = (0, vue.ref)(null);
125536
+ const renderExpand = (0, vue.ref)(null);
125212
125537
  const resizeProxyVisible = (0, vue.ref)(false);
125213
125538
  const resizeState = (0, vue.ref)({
125214
125539
  width: null,
@@ -125309,20 +125634,20 @@ ${p}
125309
125634
  refreshAffix();
125310
125635
  };
125311
125636
  const toggleAllSelection = () => {
125312
- store.toggleAllSelection();
125637
+ store.selection.toggleAll();
125313
125638
  };
125314
125639
  const setCurrentRow = (row) => {
125315
- store.setCurrentRow(row);
125640
+ store.row.set(row);
125316
125641
  };
125317
125642
  const toggleRowSelection = (row, selected, emitChange) => {
125318
- store.toggleRowSelection(row, selected, emitChange);
125319
- store.updateAllSelected();
125643
+ store.selection.toggle(row, selected, emitChange);
125644
+ store.selection.updateAllSelected();
125320
125645
  };
125321
125646
  const toggleRowExpansion = (row, expanded) => {
125322
125647
  store.toggleRowExpansionAdapter(row, expanded);
125323
125648
  };
125324
125649
  const clearSelection = () => {
125325
- store.clearSelection();
125650
+ store.selection.clear();
125326
125651
  };
125327
125652
  const handleScrollX = () => {
125328
125653
  if (!bodyXWrapper.value) return;
@@ -125351,7 +125676,7 @@ ${p}
125351
125676
  }
125352
125677
  };
125353
125678
  const handleMouseLeave = () => {
125354
- store.setHoverRow(null);
125679
+ store.row.setHoverIndex(null);
125355
125680
  if (hoverState.value) hoverState.value = null;
125356
125681
  };
125357
125682
  const handleMousewheel = (deltaX, deltaY) => {
@@ -125401,7 +125726,7 @@ ${p}
125401
125726
  }, { immediate: true });
125402
125727
  (0, vue.watch)(() => props.currentRowValue, (v) => {
125403
125728
  if (!props.primaryKey) return;
125404
- store.current.reset(v);
125729
+ store.row.setById(v);
125405
125730
  }, { immediate: true });
125406
125731
  (0, vue.watch)(() => [props.data, props.data.length], () => {
125407
125732
  store.setData(props.data);
@@ -125412,7 +125737,7 @@ ${p}
125412
125737
  }, { immediate: true });
125413
125738
  (0, vue.watch)(() => props.columns, (v) => {
125414
125739
  if (!Array.isArray(v) || v.length === 0) return;
125415
- store.applyExternalColumns(v);
125740
+ store.column.applyExternal(v);
125416
125741
  }, {
125417
125742
  deep: true,
125418
125743
  flush: "post"
@@ -125470,7 +125795,7 @@ ${p}
125470
125795
  debouncedUpdateLayout,
125471
125796
  isReady,
125472
125797
  hoverState,
125473
- renderExpanded,
125798
+ renderExpand,
125474
125799
  hiddenColumns,
125475
125800
  props,
125476
125801
  emit,
@@ -125487,6 +125812,8 @@ ${p}
125487
125812
  tableId,
125488
125813
  "vc-table"
125489
125814
  ],
125815
+ "style": { "--vc-table-columns": layout.templateColumns.value },
125816
+ "role": "table",
125490
125817
  "onMouseleave": handleMouseLeave
125491
125818
  }, [
125492
125819
  (0, vue.createVNode)("div", {
@@ -125531,6 +125858,41 @@ ${p}
125531
125858
  };
125532
125859
  }
125533
125860
  });
125861
+ var tableColumnProps = {
125862
+ type: {
125863
+ type: String,
125864
+ default: "default"
125865
+ },
125866
+ line: Number,
125867
+ label: String,
125868
+ labelClass: String,
125869
+ prop: String,
125870
+ width: Number,
125871
+ minWidth: Number,
125872
+ renderHeader: Function,
125873
+ resizable: {
125874
+ type: Boolean,
125875
+ default: true
125876
+ },
125877
+ align: String,
125878
+ headerAlign: String,
125879
+ fixed: [Boolean, String],
125880
+ formatter: Function,
125881
+ selectable: Function,
125882
+ reserveSelection: Boolean,
125883
+ index: [Number, Function],
125884
+ sortable: Boolean,
125885
+ filters: Array,
125886
+ filterMultiple: {
125887
+ type: Boolean,
125888
+ default: true
125889
+ },
125890
+ filterIcon: String,
125891
+ filteredValue: Array,
125892
+ filterPopupClass: String,
125893
+ filter: Function,
125894
+ tooltip: [String, Function]
125895
+ };
125534
125896
  /** @jsxImportSource vue */
125535
125897
  var cellStarts = {
125536
125898
  default: { order: "" },
@@ -125559,7 +125921,7 @@ ${p}
125559
125921
  "indeterminate": store.states.selection.length > 0 && !store.states.isAllSelected,
125560
125922
  "onClick": (e) => {
125561
125923
  e.stopPropagation();
125562
- store.toggleAllSelection();
125924
+ store.selection.toggleAll();
125563
125925
  }
125564
125926
  }, null);
125565
125927
  },
@@ -125567,7 +125929,7 @@ ${p}
125567
125929
  return (0, vue.withDirectives)((0, vue.createVNode)(Checkbox, {
125568
125930
  "modelValue": selected,
125569
125931
  "disabled": column.selectable ? !column.selectable.call(null, row, rowIndex) : false,
125570
- "onChange": () => store.rowSelectedChanged(row),
125932
+ "onChange": () => store.selection.rowChanged(row),
125571
125933
  "onClick": (e) => e.stopPropagation()
125572
125934
  }, null), [[vue.vShow, store.states.expandSelectable || level === 0]]);
125573
125935
  },
@@ -125609,12 +125971,12 @@ ${p}
125609
125971
  class: "vc-table__expand-column"
125610
125972
  }
125611
125973
  };
125612
- var defaultRenderCell = (rowData = {}) => {
125974
+ var defaultRenderCell = (rowData) => {
125613
125975
  const column = rowData.column;
125614
125976
  const { prop, formatter } = column;
125615
125977
  let value;
125616
125978
  if (prop) value = getPropByPath(rowData.row, prop).v;
125617
- if (formatter) return column.formatter(rowData);
125979
+ if (formatter) return formatter(rowData);
125618
125980
  const line = typeof column.line !== "undefined" ? column.line : VcInstance.options.TableColumn?.line;
125619
125981
  if (line && value) return (0, vue.createVNode)("div", {
125620
125982
  "class": "vc-table__text-line",
@@ -125633,10 +125995,10 @@ ${p}
125633
125995
  "class": "vc-table__indent",
125634
125996
  "style": { "padding-left": treeNode.indent + "px" }
125635
125997
  }, null));
125636
- if (typeof treeNode.expanded === "boolean" && !treeNode.noLazyChildren) {
125998
+ if (typeof treeNode.expand === "boolean" && !treeNode.noLazyChildren) {
125637
125999
  const expandClasses = {
125638
126000
  "vc-table__expand-icon": true,
125639
- "is-expand": treeNode.expanded
126001
+ "is-expand": treeNode.expand
125640
126002
  };
125641
126003
  ele.push((0, vue.createVNode)("span", {
125642
126004
  "class": expandClasses,
@@ -125645,191 +126007,229 @@ ${p}
125645
126007
  } else ele.push((0, vue.createVNode)("span", { "class": "vc-table__placeholder" }, null));
125646
126008
  return ele;
125647
126009
  };
126010
+ /** @jsxImportSource vue */
126011
+ /**
126012
+ * 列 states 完整形状:构造期仅初始化核心字段,props 镜像与 render 函数由 `init()` 写入。
126013
+ */
126014
+ /**
126015
+ * renderCell / renderHeader / formatter 等渲染回调的入参。
126016
+ */
126017
+ var DERIVED_KEYS = ["realAlign", "realHeaderAlign"];
126018
+ var assignStates = (target, source) => {
126019
+ for (const key in source) {
126020
+ if (!hasOwn$1(source, key) || DERIVED_KEYS.includes(key)) continue;
126021
+ target[key] = source[key];
126022
+ }
126023
+ };
126024
+ var TableColumnNode = class TableColumnNode {
126025
+ /**
126026
+ * 列的全部响应式数据(唯一列对象):
126027
+ * - 内部(store / layout / header / body)读写 `node.states.*`;
126028
+ * - 对外(slot / emit / renderCell / 用户回调)直接传该对象。
126029
+ */
126030
+ states = (() => {
126031
+ const v = (0, vue.reactive)({
126032
+ id: "",
126033
+ type: "default",
126034
+ colspan: 1,
126035
+ rowspan: 1,
126036
+ align: "",
126037
+ headerAlign: "",
126038
+ minWidth: 80,
126039
+ resizable: true,
126040
+ filterMultiple: true,
126041
+ hidden: false,
126042
+ fixed: false,
126043
+ realAlign: (0, vue.computed)(() => {
126044
+ return v.align ? "is-" + v.align : null;
126045
+ }),
126046
+ realHeaderAlign: (0, vue.computed)(() => {
126047
+ return v.headerAlign ? "is-" + v.headerAlign : v.realAlign;
126048
+ })
126049
+ });
126050
+ return v;
126051
+ })();
126052
+ childNodes = (0, vue.reactive)([]);
126053
+ parentNode = null;
126054
+ constructor(options) {
126055
+ (0, vue.markRaw)(this);
126056
+ this.table = options.table;
126057
+ this.parentNode = options.parentNode ?? null;
126058
+ options.instance && (this.instance = options.instance);
126059
+ options.states && assignStates(this.states, options.states);
126060
+ }
126061
+ /**
126062
+ * 兼容按 children 遍历列树的场景(如 flattenData)。
126063
+ * leaf 返回 undefined,保持与原扁平对象一致的 truthy 判断。
126064
+ * @returns 子节点集合(leaf 为 undefined)
126065
+ */
126066
+ get children() {
126067
+ return this.childNodes.length ? this.childNodes : void 0;
126068
+ }
126069
+ /**
126070
+ * 由组件 props 初始化 states,并绑定 props 监听
126071
+ * 1) defaults + cellStarts + props 合并(merge 跳过 undefined,保留 cellStarts 的宽度等预设)
126072
+ * 2) 特定类型的强制属性(cellForced)
126073
+ * 3) 宽度归一化(width/minWidth/realWidth)
126074
+ * 4) renderHeader / renderCell 包装
126075
+ * @param props ~
126076
+ * @param slots ~
126077
+ * @param attrs ~
126078
+ */
126079
+ init(props, slots, attrs) {
126080
+ let column = merge$1({
126081
+ colspan: 1,
126082
+ rowspan: 1,
126083
+ class: attrs.class,
126084
+ style: attrs.style,
126085
+ ...cellStarts[props.type],
126086
+ id: this.states.id
126087
+ }, Object.keys(props).reduce((pre, key) => {
126088
+ pre[key] = props[key];
126089
+ return pre;
126090
+ }, {}));
126091
+ column = this.applyForcedProps(column);
126092
+ column = this.applyWidth(column, props);
126093
+ column = this.applyRenders(column, props, slots);
126094
+ assignStates(this.states, column);
126095
+ this.registerWatchers(props);
126096
+ }
126097
+ /**
126098
+ * 监听 props 同步 states,并在布局相关字段变化时重排。
126099
+ * @param props ~
126100
+ */
126101
+ registerWatchers(props) {
126102
+ Object.keys(props).forEach((key) => {
126103
+ (0, vue.watch)(() => props[key], (v) => {
126104
+ this.states[key] = v;
126105
+ });
126106
+ });
126107
+ (0, vue.watch)(() => props.fixed, () => {
126108
+ this.table.store.scheduleLayout(true);
126109
+ });
126110
+ (0, vue.watch)(() => parseWidth(props.width), (v) => {
126111
+ this.states.width = v ?? void 0;
126112
+ this.states.realWidth = v ?? void 0;
126113
+ this.table.store.scheduleLayout(false);
126114
+ });
126115
+ (0, vue.watch)(() => parseMinWidth(props.minWidth), () => {
126116
+ this.table.store.scheduleLayout(false);
126117
+ });
126118
+ }
126119
+ /**
126120
+ * 对于特定类型的 column,某些属性不允许被覆盖
126121
+ * 如 type: selection | index | expand
126122
+ * @param column ~
126123
+ * @returns ~
126124
+ */
126125
+ applyForcedProps(column) {
126126
+ const source = cellForced[column.type] || {};
126127
+ Object.keys(source).forEach((prop) => {
126128
+ const value = source[prop];
126129
+ if (value !== void 0) column[prop] = prop === "class" ? `${column.class ? `${column.class} ` : ""}${value}` : value;
126130
+ });
126131
+ return column;
126132
+ }
126133
+ /**
126134
+ * width / minWidth / realWidth 归一化
126135
+ * @param column ~
126136
+ * @param props ~
126137
+ * @returns ~
126138
+ */
126139
+ applyWidth(column, props) {
126140
+ column.width = parseWidth(props.width) || column.width;
126141
+ column.minWidth = parseMinWidth(props.minWidth) || column.minWidth || 80;
126142
+ column.realWidth = typeof column.width === "undefined" ? column.minWidth : column.width;
126143
+ return column;
126144
+ }
126145
+ /**
126146
+ * column
126147
+ * -> renderHeader: 渲染头部
126148
+ * -> renderCell: 渲染单元格
126149
+ * owner
126150
+ * -> renderExpand: 展开
126151
+ * @param column ~
126152
+ * @param props ~
126153
+ * @param slots ~
126154
+ * @returns ~
126155
+ */
126156
+ applyRenders(column, props, slots) {
126157
+ const specialTypes = Object.keys(cellForced);
126158
+ if (props.renderHeader) column.renderHeader = props.renderHeader;
126159
+ else if (specialTypes.indexOf(column.type) === -1) column.renderHeader = (data) => {
126160
+ const renderHeader = slots.header;
126161
+ return renderHeader ? renderHeader(data) : data?.column?.label;
126162
+ };
126163
+ let originRenderCell = column.renderCell;
126164
+ if (column.type === "expand") {
126165
+ column.renderCell = (data) => (0, vue.createVNode)("div", { "class": "vc-table__cell" }, [originRenderCell(data)]);
126166
+ this.table.renderExpand.value = (data) => {
126167
+ return slots.default ? slots.default(data) : slots.default;
126168
+ };
126169
+ } else {
126170
+ originRenderCell = originRenderCell || defaultRenderCell;
126171
+ column.renderCell = (data) => {
126172
+ const children = slots.default ? slots?.default?.(data) : originRenderCell(data);
126173
+ let prefix = treeCellPrefix(data);
126174
+ if (!isEmpty(this.table.store.states.treeData) && !prefix && data.isExpandColumn) prefix = (0, vue.createVNode)("span", { "class": "vc-table__unexpand__indent" }, null);
126175
+ const { placeholder } = this.table.props;
126176
+ const contentPlaceholder = typeof placeholder === "function" ? placeholder() : placeholder;
126177
+ return (0, vue.createVNode)("div", { "class": "vc-table__cell" }, [prefix, children === void 0 || children === "" || children === null ? contentPlaceholder : children]);
126178
+ };
126179
+ }
126180
+ return column;
126181
+ }
126182
+ /**
126183
+ * 浅克隆当前节点(类似 Element.prototype.cloneNode):
126184
+ * states 复制为独立 reactive 副本,避免 columnsToRowsEffect 写入 level/colspan/rowspan 污染原节点;
126185
+ * 子节点默认空,由调用方传入(如 cloneVisibleTree 过滤后的可见子树)。
126186
+ * leaf 列通常不调用,在调用方保持原引用。
126187
+ * @param childNodes 挂载到克隆节点上的子节点
126188
+ * @returns 克隆节点
126189
+ */
126190
+ cloneNode(childNodes = []) {
126191
+ const source = { ...this.states };
126192
+ for (const key of DERIVED_KEYS) delete source[key];
126193
+ const cloned = new TableColumnNode({
126194
+ table: this.table,
126195
+ parentNode: this.parentNode,
126196
+ instance: this.instance,
126197
+ states: source
126198
+ });
126199
+ cloned.childNodes.push(...childNodes);
126200
+ return cloned;
126201
+ }
126202
+ };
125648
126203
  var TableColumn = /* @__PURE__ */ (0, vue.defineComponent)({
125649
126204
  name: "vc-table-column",
125650
126205
  inheritAttrs: false,
125651
- props: {
125652
- type: {
125653
- type: String,
125654
- default: "default"
125655
- },
125656
- line: Number,
125657
- label: String,
125658
- labelClass: String,
125659
- prop: String,
125660
- width: Number,
125661
- minWidth: Number,
125662
- renderHeader: Function,
125663
- resizable: {
125664
- type: Boolean,
125665
- default: true
125666
- },
125667
- columnKey: String,
125668
- align: String,
125669
- headerAlign: String,
125670
- fixed: [Boolean, String],
125671
- formatter: Function,
125672
- selectable: Function,
125673
- reserveSelection: Boolean,
125674
- index: [Number, Function],
125675
- sortable: Boolean,
125676
- filters: Array,
125677
- filterMultiple: {
125678
- type: Boolean,
125679
- default: true
125680
- },
125681
- filterIcon: String,
125682
- filteredValue: Array,
125683
- filterPopupClass: String,
125684
- filter: Function,
125685
- tooltip: [String, Function]
125686
- },
126206
+ props: tableColumnProps,
125687
126207
  setup(props, { slots, attrs }) {
125688
126208
  const instance = (0, vue.getCurrentInstance)();
125689
126209
  const table = (0, vue.inject)("vc-table");
125690
126210
  const parent = (0, vue.inject)("vc-table-column", table);
125691
126211
  const isSubColumn = table !== parent;
125692
- const columnId = (0, vue.ref)((parent.tableId || parent.columnId) + getUid("column"));
125693
- const realWidth = (0, vue.computed)(() => {
125694
- return parseWidth(props.width);
125695
- });
125696
- const realMinWidth = (0, vue.computed)(() => {
125697
- return parseMinWidth(props.minWidth);
125698
- });
125699
- const realAlign = (0, vue.computed)(() => {
125700
- return props.align ? "is-" + props.align : null;
125701
- });
125702
- const realHeaderAlign = (0, vue.computed)(() => {
125703
- return props.headerAlign ? "is-" + props.headerAlign : realAlign.value;
126212
+ const parentNode = "columnNode" in parent ? parent.columnNode : void 0;
126213
+ const columnNode = new TableColumnNode({
126214
+ table,
126215
+ parentNode,
126216
+ instance,
126217
+ states: { id: ("columnId" in parent ? parent.columnId.value : parent.tableId) + getUid("column") }
125704
126218
  });
125705
- const columnConfig = (0, vue.reactive)({});
125706
- /**
125707
- * 获取当前值情况,this[key]
125708
- * @param args ~
125709
- * @returns ~
125710
- */
125711
- const getPropsData = (...args) => {
125712
- return args.reduce((prev, cur) => {
125713
- if (Array.isArray(cur)) cur.forEach((key) => {
125714
- prev[key] = props[key];
125715
- });
125716
- return prev;
125717
- }, {});
125718
- };
125719
- /**
125720
- * compose 1
125721
- * 对于特定类型的 column,某些属性不允许设置
125722
- * 如 type: selection | index | expand
125723
- * @param column ~
125724
- * @returns ~
125725
- */
125726
- const setColumnForcedProps = (column) => {
125727
- const source = cellForced[column.type] || {};
125728
- Object.keys(source).forEach((prop) => {
125729
- const value = source[prop];
125730
- if (value !== void 0) column[prop] = prop === "class" ? `${column[prop] ? `${column[prop]} ` : ""}${value}` : value;
125731
- });
125732
- return column;
125733
- };
125734
- /**
125735
- * compose 2
125736
- * column
125737
- * -> width
125738
- * -> minWidth
125739
- * @param column ~
125740
- * @returns ~
125741
- */
125742
- const setColumnWidth = (column) => {
125743
- column.width = realWidth.value || column.width;
125744
- column.minWidth = realMinWidth.value || column.minWidth || 80;
125745
- column.realWidth = typeof column.width === "undefined" ? column.minWidth : column.width;
125746
- return column;
125747
- };
125748
- /**
125749
- * compose 3
125750
- * column
125751
- * -> renderHeader: 渲染头部
125752
- * -> renderCell: 渲染单元格
125753
- * owner
125754
- * -> renderExpanded: 展开
125755
- * @param column ~
125756
- * @returns ~
125757
- */
125758
- const setColumnRenders = (column) => {
125759
- const specialTypes = Object.keys(cellForced);
125760
- if (props.renderHeader) column.renderHeader = props.renderHeader;
125761
- else if (specialTypes.indexOf(column.type) === -1) column.renderHeader = (data) => {
125762
- const renderHeader = slots.header;
125763
- return renderHeader ? renderHeader(data) : data?.column?.label;
125764
- };
125765
- let originRenderCell = column.renderCell;
125766
- if (column.type === "expand") {
125767
- column.renderCell = (data) => (0, vue.createVNode)("div", { "class": "vc-table__cell" }, [originRenderCell(data)]);
125768
- table.renderExpanded.value = (data) => {
125769
- return slots.default ? slots.default(data) : slots.default;
125770
- };
125771
- } else {
125772
- originRenderCell = originRenderCell || defaultRenderCell;
125773
- column.renderCell = (data) => {
125774
- let children = null;
125775
- if (slots.default) children = slots?.default?.(data);
125776
- else children = originRenderCell(data);
125777
- let prefix = treeCellPrefix(data);
125778
- const $props = {
125779
- class: "vc-table__cell",
125780
- style: {}
125781
- };
125782
- if (!isEmpty(table.store.states.treeData) && !prefix && data.isExpandColumn) prefix = (0, vue.createVNode)("span", { "class": "vc-table__unexpand__indent" }, null);
125783
- const { placeholder } = table.props;
125784
- const contentPlaceholder = typeof placeholder === "function" ? placeholder() : placeholder;
125785
- return (0, vue.createVNode)("div", $props, [prefix, children === void 0 || children === "" || children === null ? contentPlaceholder : children]);
125786
- };
125787
- }
125788
- return column;
125789
- };
125790
- const registerColumn = () => {
125791
- let column = merge$1({
125792
- colspan: 1,
125793
- rowspan: 1,
125794
- class: attrs.class,
125795
- style: attrs.style,
125796
- ...cellStarts[props.type],
125797
- id: columnId.value,
125798
- realAlign,
125799
- realHeaderAlign
125800
- }, getPropsData(Object.keys(props)));
125801
- column = compose(setColumnRenders, setColumnWidth, setColumnForcedProps)(column);
125802
- for (const key in column) if (hasOwn$1(column, key)) columnConfig[key] = column[key];
125803
- };
125804
- const registerWatchers = () => {
125805
- Object.keys(props).forEach((k) => (0, vue.watch)(() => props[k], (v) => columnConfig[k] = v));
125806
- (0, vue.watch)(() => props.fixed, () => {
125807
- table.store.scheduleLayout(true);
125808
- });
125809
- (0, vue.watch)(() => realWidth.value, (v) => {
125810
- columnConfig["width"] = v;
125811
- columnConfig["realWidth"] = v;
125812
- table.store.scheduleLayout(false);
125813
- });
125814
- (0, vue.watch)(() => realMinWidth.value, () => {
125815
- table.store.scheduleLayout(false);
125816
- });
125817
- };
125818
126219
  (0, vue.onBeforeMount)(() => {
125819
- registerColumn();
125820
- registerWatchers();
126220
+ columnNode.init(props, slots, attrs);
125821
126221
  });
125822
126222
  (0, vue.onMounted)(() => {
125823
- const columnIndex = [...isSubColumn ? parent.vnode.el.children : parent.hiddenColumns.value.children].indexOf(instance.vnode.el);
125824
- table.store.insertColumn(columnConfig, columnIndex, isSubColumn && parent.columnConfig);
126223
+ const columnIndex = [...isSubColumn ? parentNode.instance.vnode.el.children : table.hiddenColumns.value.children].indexOf(instance.vnode.el);
126224
+ table.store.column.insert(columnNode, columnIndex, parentNode);
125825
126225
  });
125826
126226
  (0, vue.onUnmounted)(() => {
125827
126227
  if (!instance.parent) return;
125828
- table.store.removeColumn(columnConfig, isSubColumn && parent.columnConfig);
126228
+ table.store.column.remove(columnNode, parentNode);
125829
126229
  });
125830
126230
  (0, vue.provide)("vc-table-column", {
125831
- columnId,
125832
- columnConfig
126231
+ columnId: (0, vue.computed)(() => columnNode.states.id),
126232
+ columnNode
125833
126233
  });
125834
126234
  /**
125835
126235
  * 可以计算 columnIndex(外层需要标签元素), 即h('div')
@@ -125846,7 +126246,7 @@ ${p}
125846
126246
  rowIndex: -1
125847
126247
  });
125848
126248
  if (renderDefault instanceof Array) {
125849
- for (const childNode of renderDefault) if (/^vcm?-table-column$/.test(childNode.type?.name)) children.push(childNode);
126249
+ for (const childNode of renderDefault) if (/^vcm?-table-column$/.test(childNode.type?.name || "")) children.push(childNode);
125850
126250
  else if (childNode.type === vue.Fragment && childNode.children instanceof Array) renderDefault.push(...childNode.children);
125851
126251
  }
125852
126252
  } catch {