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