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