@deot/vc 1.0.69 → 1.0.71

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