qidian-vue-ui 2.0.26 → 2.0.28

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.
@@ -1,4 +1,4 @@
1
- import type { TableEditableCellPropsParams, TableRowData, TableRowValue } from 'tdesign-vue-next';
1
+ import type { AllValidateResult, TableEditableCellPropsParams, TableRowData, TableRowValue } from 'tdesign-vue-next';
2
2
  import type { PropType } from 'vue';
3
3
  import type { QdFormBeforeSubmitQueueItem } from '../../form';
4
4
  import type { QdServiceTableFormItem } from './types';
@@ -23,6 +23,8 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
23
23
  label: PropType<unknown>;
24
24
  lazy: BooleanConstructor;
25
25
  active: BooleanConstructor;
26
+ autofocus: BooleanConstructor;
27
+ validationErrors: PropType<AllValidateResult[]>;
26
28
  renderCell: {
27
29
  type: PropType<() => unknown>;
28
30
  required: true;
@@ -31,6 +33,10 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
31
33
  type: PropType<() => void>;
32
34
  required: true;
33
35
  };
36
+ consumeAutofocus: {
37
+ type: PropType<() => void>;
38
+ required: true;
39
+ };
34
40
  registerBeforeSubmit: {
35
41
  type: PropType<RegisterBeforeSubmit>;
36
42
  required: true;
@@ -43,6 +49,14 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
43
49
  type: PropType<() => void>;
44
50
  required: true;
45
51
  };
52
+ getHorizontalScroll: {
53
+ type: PropType<() => number | undefined>;
54
+ required: true;
55
+ };
56
+ setHorizontalScroll: {
57
+ type: PropType<(scrollLeft: number) => void>;
58
+ required: true;
59
+ };
46
60
  sourceRow: {
47
61
  type: PropType<TableRowData>;
48
62
  default: undefined;
@@ -67,6 +81,8 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
67
81
  label: PropType<unknown>;
68
82
  lazy: BooleanConstructor;
69
83
  active: BooleanConstructor;
84
+ autofocus: BooleanConstructor;
85
+ validationErrors: PropType<AllValidateResult[]>;
70
86
  renderCell: {
71
87
  type: PropType<() => unknown>;
72
88
  required: true;
@@ -75,6 +91,10 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
75
91
  type: PropType<() => void>;
76
92
  required: true;
77
93
  };
94
+ consumeAutofocus: {
95
+ type: PropType<() => void>;
96
+ required: true;
97
+ };
78
98
  registerBeforeSubmit: {
79
99
  type: PropType<RegisterBeforeSubmit>;
80
100
  required: true;
@@ -87,12 +107,21 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
87
107
  type: PropType<() => void>;
88
108
  required: true;
89
109
  };
110
+ getHorizontalScroll: {
111
+ type: PropType<() => number | undefined>;
112
+ required: true;
113
+ };
114
+ setHorizontalScroll: {
115
+ type: PropType<(scrollLeft: number) => void>;
116
+ required: true;
117
+ };
90
118
  sourceRow: {
91
119
  type: PropType<TableRowData>;
92
120
  default: undefined;
93
121
  };
94
122
  }>> & Readonly<{}>, {
95
123
  lazy: boolean;
124
+ autofocus: boolean;
96
125
  active: boolean;
97
126
  sourceRow: TableRowData;
98
127
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
@@ -1,5 +1,5 @@
1
1
  import { isEmpty } from "qidian-shared";
2
- import { defineComponent, computed, provide, onBeforeUnmount, h } from "vue";
2
+ import { defineComponent, computed, onBeforeUnmount, provide, h } from "vue";
3
3
  import { useConfig } from "../../config-provider/useConfig.mjs";
4
4
  import { qdUseComputeValue } from "../../config-renderer/compute.mjs";
5
5
  import { resolveQdFormItemOptions } from "../../form/utils.mjs";
@@ -94,6 +94,8 @@ const QdServiceTableEditCell = /* @__PURE__ */ defineComponent({
94
94
  label: [String, Function, Object],
95
95
  lazy: Boolean,
96
96
  active: Boolean,
97
+ autofocus: Boolean,
98
+ validationErrors: Array,
97
99
  renderCell: {
98
100
  type: Function,
99
101
  required: true
@@ -102,6 +104,10 @@ const QdServiceTableEditCell = /* @__PURE__ */ defineComponent({
102
104
  type: Function,
103
105
  required: true
104
106
  },
107
+ consumeAutofocus: {
108
+ type: Function,
109
+ required: true
110
+ },
105
111
  registerBeforeSubmit: {
106
112
  type: Function,
107
113
  required: true
@@ -114,6 +120,14 @@ const QdServiceTableEditCell = /* @__PURE__ */ defineComponent({
114
120
  type: Function,
115
121
  required: true
116
122
  },
123
+ getHorizontalScroll: {
124
+ type: Function,
125
+ required: true
126
+ },
127
+ setHorizontalScroll: {
128
+ type: Function,
129
+ required: true
130
+ },
117
131
  sourceRow: {
118
132
  type: Object,
119
133
  default: void 0
@@ -122,17 +136,27 @@ const QdServiceTableEditCell = /* @__PURE__ */ defineComponent({
122
136
  setup(props, {
123
137
  attrs
124
138
  }) {
139
+ const horizontalScroll = props.getHorizontalScroll();
140
+ const restoreHorizontalScrollOnFocus = props.autofocus;
141
+ let autofocusScrollRestored = false;
142
+ let unmounting = false;
125
143
  const currentContext = computed(() => createRowEditContext(props.sourceRow ?? props.row, () => props.row, props.colKey, props.updateEditedCellValue, props.notifyDataChange, (value) => {
126
144
  if (typeof attrs.onChange === "function") attrs.onChange(value);
127
145
  }));
128
146
  const {
129
147
  t
130
148
  } = useConfig("form");
149
+ const validationError = computed(() => props.validationErrors?.[0]);
131
150
  const validationStatus = computed(() => {
132
- const status = attrs.status;
151
+ const status = attrs.status ?? validationError.value?.type;
133
152
  if (status === "error" || status === "warning" || status === "success") return status;
153
+ if (validationError.value) return "error";
134
154
  return void 0;
135
155
  });
156
+ const validationTips = computed(() => {
157
+ const tips = attrs.tips ?? validationError.value?.message;
158
+ return typeof tips === "string" ? tips : void 0;
159
+ });
136
160
  const reIfRender = computed(() => {
137
161
  const ifRender = props.formItem.ifRender;
138
162
  if (isEmpty(ifRender)) return true;
@@ -154,7 +178,7 @@ const QdServiceTableEditCell = /* @__PURE__ */ defineComponent({
154
178
  if (!resolved) return;
155
179
  return {
156
180
  ...resolved,
157
- ...props.lazy && props.active ? {
181
+ ...props.autofocus ? {
158
182
  autofocus: true
159
183
  } : {},
160
184
  ...validationStatus.value ? {
@@ -162,6 +186,29 @@ const QdServiceTableEditCell = /* @__PURE__ */ defineComponent({
162
186
  } : {}
163
187
  };
164
188
  });
189
+ function handleFocusin() {
190
+ props.activate();
191
+ if (!props.lazy || !props.active || !restoreHorizontalScrollOnFocus || autofocusScrollRestored || horizontalScroll === void 0) {
192
+ return;
193
+ }
194
+ autofocusScrollRestored = true;
195
+ props.setHorizontalScroll(horizontalScroll);
196
+ queueMicrotask(() => props.setHorizontalScroll(horizontalScroll));
197
+ }
198
+ function handleFocusout(event) {
199
+ const currentTarget = event.currentTarget;
200
+ const nextTarget = event.relatedTarget;
201
+ if (nextTarget instanceof Node && currentTarget.contains(nextTarget)) return;
202
+ requestAnimationFrame(() => {
203
+ if (unmounting || !currentTarget.isConnected || currentTarget.contains(document.activeElement)) {
204
+ return;
205
+ }
206
+ props.consumeAutofocus();
207
+ });
208
+ }
209
+ onBeforeUnmount(() => {
210
+ unmounting = true;
211
+ });
165
212
  provide(PROVIDE_FORM_ADD_BEFORE_SUBMIT_QUEUE, (item) => {
166
213
  const cleanup = props.registerBeforeSubmit(props.rowValue, item);
167
214
  onBeforeUnmount(cleanup);
@@ -180,16 +227,17 @@ const QdServiceTableEditCell = /* @__PURE__ */ defineComponent({
180
227
  return h("div", {
181
228
  ...rendererAttrs,
182
229
  class: ["qd-service-table__cell-editor", "t-form__controls", status ? `t-is-${status}` : void 0, status === "success" ? "t-form--success-border" : void 0],
183
- onFocusin: props.activate
230
+ onFocusin: handleFocusin,
231
+ onFocusout: handleFocusout
184
232
  }, [h("div", {
185
233
  class: "t-form__controls-content"
186
234
  }, [h(_sfc_main, {
187
235
  config: component.value,
188
236
  context: currentContext.value,
189
237
  crudMode: props.formItem.crudMode
190
- })]), attrs.tips ? h("div", {
238
+ })]), validationTips.value ? h("div", {
191
239
  class: ["t-tips", status ? `t-is-${status}` : "t-is-default"]
192
- }, attrs.tips) : void 0]);
240
+ }, validationTips.value) : void 0]);
193
241
  };
194
242
  }
195
243
  });
@@ -1,88 +1,88 @@
1
- .qd-service-table[data-v-b2ceb5c8] {
1
+ .qd-service-table[data-v-ffc43b16] {
2
2
  height: 100%;
3
3
  display: flex;
4
4
  flex-direction: column;
5
5
  }
6
- .qd-service-table[data-v-b2ceb5c8] > .t-table__content {
6
+ .qd-service-table[data-v-ffc43b16] > .t-table__content {
7
7
  flex: 1;
8
8
  }
9
- .qd-service-table--mini[data-v-b2ceb5c8] {
9
+ .qd-service-table--mini[data-v-ffc43b16] {
10
10
  font: var(--td-font-body-small);
11
11
  }
12
- .qd-service-table--mini[data-v-b2ceb5c8] th,
13
- .qd-service-table--mini[data-v-b2ceb5c8] tr:not(.t-table__expanded-row) > td {
12
+ .qd-service-table--mini[data-v-ffc43b16] th,
13
+ .qd-service-table--mini[data-v-ffc43b16] tr:not(.t-table__expanded-row) > td {
14
14
  padding: var(--td-comp-paddingTB-xxs) var(--td-comp-paddingLR-xxs);
15
15
  line-height: var(--td-line-height-body-small);
16
16
  }
17
- .qd-service-table--mini[data-v-b2ceb5c8] .t-table__row-full-element {
17
+ .qd-service-table--mini[data-v-ffc43b16] .t-table__row-full-element {
18
18
  padding: var(--td-comp-paddingTB-xs) var(--td-comp-paddingLR-s);
19
19
  }
20
- .qd-service-table--hide-empty-image[data-v-b2ceb5c8] .t-table__empty {
20
+ .qd-service-table--hide-empty-image[data-v-ffc43b16] .t-table__empty {
21
21
  min-height: auto;
22
22
  }
23
- .qd-service-table--hide-empty-image[data-v-b2ceb5c8] .t-table__empty .t-empty {
23
+ .qd-service-table--hide-empty-image[data-v-ffc43b16] .t-table__empty .t-empty {
24
24
  padding: 0 !important;
25
25
  }
26
- .qd-service-table--hide-empty-image[data-v-b2ceb5c8] .t-table__empty .t-empty__image {
26
+ .qd-service-table--hide-empty-image[data-v-ffc43b16] .t-table__empty .t-empty__image {
27
27
  display: none;
28
28
  }
29
- .qd-service-table--hide-empty-image[data-v-b2ceb5c8] .t-table__empty .t-empty__title {
29
+ .qd-service-table--hide-empty-image[data-v-ffc43b16] .t-table__empty .t-empty__title {
30
30
  margin-top: 0;
31
31
  }
32
- .qd-service-table[data-v-b2ceb5c8] .t-table__tree-col:not(:has(.t-table__tree-op-icon)) {
32
+ .qd-service-table[data-v-ffc43b16] .t-table__tree-col:not(:has(.t-table__tree-op-icon)) {
33
33
  margin-left: calc(var(--td-font-size-body-large) + var(--td-comp-margin-s));
34
34
  }
35
- .qd-service-table[data-v-b2ceb5c8] .t-table__tree-leaf-node .t-table__tree-op-icon:empty {
35
+ .qd-service-table[data-v-ffc43b16] .t-table__tree-leaf-node .t-table__tree-op-icon:empty {
36
36
  width: calc(var(--td-font-size-body-large) + var(--td-comp-margin-s));
37
37
  }
38
- .qd-service-table[data-v-b2ceb5c8] .t-affix > .t-table__affixed-header-elm-wrap,
39
- .qd-service-table[data-v-b2ceb5c8] .t-affix > .t-table__scrollbar--obvious {
40
- transform: var(--v5d7945e0);
38
+ .qd-service-table[data-v-ffc43b16] .t-affix > .t-table__affixed-header-elm-wrap,
39
+ .qd-service-table[data-v-ffc43b16] .t-affix > .t-table__scrollbar--obvious {
40
+ transform: var(--v366f53ea);
41
41
  }
42
- .qd-service-table--horizontal-bar-static[data-v-b2ceb5c8] .t-table__scrollbar--obvious {
42
+ .qd-service-table--horizontal-bar-static[data-v-ffc43b16] .t-table__scrollbar--obvious {
43
43
  visibility: hidden;
44
44
  pointer-events: none;
45
45
  }
46
- .qd-service-table[data-v-b2ceb5c8] .t-table__expanded-row .qd-service-table--horizontal-bar-static > div:has(> div > .t-table__scrollbar--obvious) {
46
+ .qd-service-table[data-v-ffc43b16] .t-table__expanded-row .qd-service-table--horizontal-bar-static > div:has(> div > .t-table__scrollbar--obvious) {
47
47
  display: none;
48
48
  }
49
- .qd-service-table[data-v-b2ceb5c8] .t-table__expanded-row > td {
49
+ .qd-service-table[data-v-ffc43b16] .t-table__expanded-row > td {
50
50
  height: 0;
51
51
  }
52
- .qd-service-table[data-v-b2ceb5c8] .t-table__affixed-header-elm-wrap {
52
+ .qd-service-table[data-v-ffc43b16] .t-table__affixed-header-elm-wrap {
53
53
  height: auto !important;
54
54
  }
55
- .qd-service-table[data-v-b2ceb5c8] .t-table__affixed-header-elm {
55
+ .qd-service-table[data-v-ffc43b16] .t-table__affixed-header-elm {
56
56
  position: relative;
57
57
  scrollbar-width: none;
58
58
  }
59
- .qd-service-table[data-v-b2ceb5c8] .t-table__affixed-header-elm::-webkit-scrollbar {
59
+ .qd-service-table[data-v-ffc43b16] .t-table__affixed-header-elm::-webkit-scrollbar {
60
60
  display: none;
61
61
  width: 0;
62
62
  height: 0;
63
63
  }
64
- .qd-service-table[data-v-b2ceb5c8] .t-table__virtual-scroll-cursor + table {
64
+ .qd-service-table[data-v-ffc43b16] .t-table__virtual-scroll-cursor + table {
65
65
  border-collapse: separate;
66
66
  }
67
- .qd-service-table[data-v-b2ceb5c8] .t-table__expanded-row-inner {
67
+ .qd-service-table[data-v-ffc43b16] .t-table__expanded-row-inner {
68
68
  display: block;
69
69
  position: sticky;
70
70
  left: 0;
71
- width: var(--v410d3656) !important;
71
+ width: var(--v12b6b140) !important;
72
72
  }
73
- .qd-service-table[data-v-b2ceb5c8] .t-table__cell-wrap > .t-form__controls > .t-form__controls-content > *:not(.t-switch):not(.t-tag):not(.t-icon):not(.qd-file-icon) {
73
+ .qd-service-table[data-v-ffc43b16] .t-table__cell-wrap > .t-form__controls > .t-form__controls-content > *:not(.t-switch):not(.t-tag):not(.t-icon):not(.qd-file-icon) {
74
74
  width: 100%;
75
75
  }
76
- .qd-service-table[data-v-b2ceb5c8] .qd-service-table__non-editable-col {
76
+ .qd-service-table[data-v-ffc43b16] .qd-service-table__non-editable-col {
77
77
  background-color: color-mix(in srgb, var(--td-bg-color-component) 50%, transparent);
78
78
  }
79
- .qd-service-table[data-v-b2ceb5c8] .qd-service-table__non-editable-col:is(
79
+ .qd-service-table[data-v-ffc43b16] .qd-service-table__non-editable-col:is(
80
80
  .t-table__cell--fixed-left,
81
81
  .t-table__cell--fixed-right
82
82
  ) {
83
83
  background-color: inherit;
84
84
  background-image: linear-gradient(color-mix(in srgb, var(--td-bg-color-secondarycontainer) 50%, transparent), color-mix(in srgb, var(--td-bg-color-secondarycontainer) 50%, transparent));
85
85
  }
86
- .qd-service-table--disable-horizontal-scroll[data-v-b2ceb5c8] colgroup > col {
86
+ .qd-service-table--disable-horizontal-scroll[data-v-ffc43b16] colgroup > col {
87
87
  width: auto !important;
88
88
  }
@@ -2,7 +2,7 @@ import './index.css'
2
2
  import _sfc_main from "./index.vue2.mjs";
3
3
  /* empty css */
4
4
  import _export_sfc from "../../../_virtual/_plugin-vue_export-helper.mjs";
5
- const QdServiceTable = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-b2ceb5c8"]]);
5
+ const QdServiceTable = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-ffc43b16"]]);
6
6
  export {
7
7
  QdServiceTable as default
8
8
  };
@@ -324,8 +324,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
324
324
  emit: __emit
325
325
  }) {
326
326
  useCssVars((_ctx) => ({
327
- "v5d7945e0": affixedHeaderTransform.value,
328
- "v410d3656": expandedRowWidth.value
327
+ "v366f53ea": affixedHeaderTransform.value,
328
+ "v12b6b140": expandedRowWidth.value
329
329
  }));
330
330
  const props = __props;
331
331
  const emit = __emit;
@@ -379,6 +379,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
379
379
  const treeLoadIds = ref([]);
380
380
  const editingCells = shallowRef([]);
381
381
  const activeEditingCell = shallowRef();
382
+ const autofocusEditingCell = shallowRef();
383
+ const editingCellValidationErrors = shallowRef(/* @__PURE__ */ new Map());
384
+ const expandedRowProxyMap = /* @__PURE__ */ new WeakMap();
382
385
  let dataChangePending = false;
383
386
  const {
384
387
  activated
@@ -405,6 +408,52 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
405
408
  data.value = [...data.value];
406
409
  });
407
410
  }
411
+ function isExpandedRowProxyable(value) {
412
+ if (!value || typeof value !== "object") return false;
413
+ if (Array.isArray(value)) return true;
414
+ const prototype = Object.getPrototypeOf(value);
415
+ return prototype === Object.prototype || prototype === null;
416
+ }
417
+ function getExpandedRowProxy(row) {
418
+ const sourceRow = data.value.find((item) => getRowValue(item) === getRowValue(row)) ?? row;
419
+ const cached = expandedRowProxyMap.get(sourceRow);
420
+ if (cached) return cached;
421
+ const proxies = /* @__PURE__ */ new WeakMap();
422
+ function wrap(target) {
423
+ if (!isExpandedRowProxyable(target)) return target;
424
+ const cachedProxy = proxies.get(target);
425
+ if (cachedProxy) return cachedProxy;
426
+ const proxy2 = new Proxy(target, {
427
+ get(currentTarget, key, receiver) {
428
+ return wrap(Reflect.get(currentTarget, key, receiver));
429
+ },
430
+ set(currentTarget, key, value, receiver) {
431
+ const previous = Reflect.get(currentTarget, key, receiver);
432
+ const result = Reflect.set(currentTarget, key, value, receiver);
433
+ if (result && !Object.is(previous, value)) notifyDataChange();
434
+ return result;
435
+ },
436
+ deleteProperty(currentTarget, key) {
437
+ const hadKey = Reflect.has(currentTarget, key);
438
+ const result = Reflect.deleteProperty(currentTarget, key);
439
+ if (result && hadKey) notifyDataChange();
440
+ return result;
441
+ }
442
+ });
443
+ proxies.set(target, proxy2);
444
+ return proxy2;
445
+ }
446
+ const proxy = wrap(sourceRow);
447
+ expandedRowProxyMap.set(sourceRow, proxy);
448
+ return proxy;
449
+ }
450
+ function resolveForwardedSlotProps(name, slotProps) {
451
+ if (name !== "expandedRow" || !slotProps.row) return slotProps;
452
+ return {
453
+ ...slotProps,
454
+ row: getExpandedRowProxy(slotProps.row)
455
+ };
456
+ }
408
457
  const isVirtualScroll = computed(() => props.scroll?.type === "virtual");
409
458
  const currentInstance = getCurrentInstance();
410
459
  const offscreenAppContext = currentInstance ? {
@@ -530,6 +579,23 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
530
579
  ...scrollOptions
531
580
  } : scroll;
532
581
  const reTableOptions = tableOptions;
582
+ const onValidate = reTableOptions.onValidate;
583
+ const onRowValidate = reTableOptions.onRowValidate;
584
+ reTableOptions.onValidate = (context) => {
585
+ replaceTableValidationErrors(context.result);
586
+ onValidate?.(context);
587
+ };
588
+ reTableOptions.onRowValidate = (context) => {
589
+ syncCellValidationErrors(context.result);
590
+ onRowValidate?.(context);
591
+ };
592
+ const expandedRow = reTableOptions.expandedRow;
593
+ if (expandedRow) {
594
+ reTableOptions.expandedRow = (h2, context) => expandedRow(h2, {
595
+ ...context,
596
+ row: getExpandedRowProxy(context.row)
597
+ });
598
+ }
533
599
  let reTransformRes = transformRes;
534
600
  const reTree = tree ? {
535
601
  ...tree,
@@ -958,6 +1024,74 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
958
1024
  function getCellKey(row, colKey) {
959
1025
  return `${String(getRowValue(row))}__${String(colKey)}`;
960
1026
  }
1027
+ function syncCellValidationErrors(results) {
1028
+ if (!results.length) return;
1029
+ const nextErrors = new Map(editingCellValidationErrors.value);
1030
+ for (const result of results) {
1031
+ const rowValue = getRowValue(result.row);
1032
+ const colKey = String(result.col.colKey);
1033
+ const rowErrors = new Map(nextErrors.get(rowValue));
1034
+ if (result.errorList.length) rowErrors.set(colKey, result.errorList);
1035
+ else rowErrors.delete(colKey);
1036
+ if (rowErrors.size) nextErrors.set(rowValue, rowErrors);
1037
+ else nextErrors.delete(rowValue);
1038
+ }
1039
+ editingCellValidationErrors.value = nextErrors;
1040
+ }
1041
+ function replaceTableValidationErrors(result) {
1042
+ const nextErrors = /* @__PURE__ */ new Map();
1043
+ for (const row of data.value) {
1044
+ const rowValue = getRowValue(row);
1045
+ const rowErrors = /* @__PURE__ */ new Map();
1046
+ for (const {
1047
+ column
1048
+ } of editableColumns.value) {
1049
+ const colKey = String(column.colKey);
1050
+ const errors = result[getCellKey(row, colKey)] ?? result[`${String(rowValue)}_${colKey}`];
1051
+ if (errors?.length) rowErrors.set(colKey, errors);
1052
+ }
1053
+ if (rowErrors.size) nextErrors.set(rowValue, rowErrors);
1054
+ }
1055
+ editingCellValidationErrors.value = nextErrors;
1056
+ }
1057
+ function replaceRowValidationErrors(rowValue, results) {
1058
+ const nextErrors = new Map(editingCellValidationErrors.value);
1059
+ const rowErrors = /* @__PURE__ */ new Map();
1060
+ for (const result of results) {
1061
+ if (!result.errorList.length) continue;
1062
+ rowErrors.set(String(result.col.colKey), result.errorList);
1063
+ }
1064
+ if (rowErrors.size) nextErrors.set(rowValue, rowErrors);
1065
+ else nextErrors.delete(rowValue);
1066
+ editingCellValidationErrors.value = nextErrors;
1067
+ }
1068
+ function pruneCellValidationErrors(rows) {
1069
+ const currentErrors = editingCellValidationErrors.value;
1070
+ if (!currentErrors.size) return;
1071
+ const validColKeys = new Set(editableColumns.value.map(({
1072
+ column
1073
+ }) => String(column.colKey)));
1074
+ const validErrorRows = /* @__PURE__ */ new Set();
1075
+ for (const row of rows) {
1076
+ const rowValue = getRowValue(row);
1077
+ if (!currentErrors.has(rowValue)) continue;
1078
+ validErrorRows.add(rowValue);
1079
+ if (validErrorRows.size === currentErrors.size) break;
1080
+ }
1081
+ let changed = false;
1082
+ const nextErrors = /* @__PURE__ */ new Map();
1083
+ for (const [rowValue, rowErrors] of currentErrors) {
1084
+ if (!validErrorRows.has(rowValue)) {
1085
+ changed = true;
1086
+ continue;
1087
+ }
1088
+ const validRowErrors = new Map([...rowErrors].filter(([colKey]) => validColKeys.has(colKey)));
1089
+ if (validRowErrors.size !== rowErrors.size) changed = true;
1090
+ if (validRowErrors.size) nextErrors.set(rowValue, validRowErrors);
1091
+ }
1092
+ if (!changed) return;
1093
+ editingCellValidationErrors.value = nextErrors;
1094
+ }
961
1095
  function isSameEditingCell(first, second) {
962
1096
  return getRowValue(first.row) === getRowValue(second.row) && first.colKey === second.colKey;
963
1097
  }
@@ -1006,9 +1140,16 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1006
1140
  }
1007
1141
  function removeEditingCell(target) {
1008
1142
  editingCells.value = editingCells.value.filter((item) => !isSameEditingCell(item, target));
1143
+ clearAutofocusEditingCell(target);
1009
1144
  if (!activeEditingCell.value || !isSameEditingCell(activeEditingCell.value, target)) return;
1010
1145
  activeEditingCell.value = editingCells.value.at(-1);
1011
1146
  }
1147
+ function clearAutofocusEditingCell(target) {
1148
+ if (!autofocusEditingCell.value || !isSameEditingCell(autofocusEditingCell.value, target)) {
1149
+ return;
1150
+ }
1151
+ autofocusEditingCell.value = void 0;
1152
+ }
1012
1153
  let suppressEnterCellKey = null;
1013
1154
  async function exitEditingCell(target) {
1014
1155
  const cellKey = getCellKey(target.row, target.colKey);
@@ -1027,14 +1168,16 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1027
1168
  if (suppressEnterCellKey === cellKey) suppressEnterCellKey = null;
1028
1169
  }, 0);
1029
1170
  }
1030
- function enterEditingCell(target) {
1171
+ function enterEditingCell(target, autofocus = true) {
1031
1172
  const currentActiveCell = activeEditingCell.value;
1032
1173
  if (currentActiveCell && !isSameEditingCell(currentActiveCell, target)) {
1174
+ clearAutofocusEditingCell(currentActiveCell);
1033
1175
  void exitEditingCell(currentActiveCell);
1034
1176
  }
1035
1177
  const editingCell = findEditingCell(target.row, target.colKey);
1036
1178
  if (!editingCell) editingCells.value = [...editingCells.value, target];
1037
1179
  activeEditingCell.value = editingCell ?? target;
1180
+ if (autofocus) autofocusEditingCell.value = activeEditingCell.value;
1038
1181
  }
1039
1182
  async function exitAllEditingCells() {
1040
1183
  for (const editingCell of [...editingCells.value]) {
@@ -1049,7 +1192,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1049
1192
  const column = context.col;
1050
1193
  if (column.formItem) {
1051
1194
  const editingCell = findEditingCell(context.row, column.colKey);
1052
- if (editingCell) activeEditingCell.value = editingCell;
1195
+ if (editingCell) enterEditingCell(editingCell, false);
1053
1196
  else exitActiveEditingCell();
1054
1197
  return;
1055
1198
  }
@@ -1375,9 +1518,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1375
1518
  }
1376
1519
  async function validateTableData(params) {
1377
1520
  const result = isVirtualScroll.value ? await serializeOffscreen(() => validateTableViaOffscreenForm()) : (await tableRef.value?.validateTableData())?.result ?? {};
1378
- if (isVirtualScroll.value) props.onValidate?.({
1379
- result
1380
- });
1521
+ if (isVirtualScroll.value) {
1522
+ replaceTableValidationErrors(result);
1523
+ props.onValidate?.({
1524
+ result
1525
+ });
1526
+ }
1381
1527
  const cellResults = resolveValidationResults(result);
1382
1528
  const context = {
1383
1529
  result,
@@ -1390,10 +1536,13 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1390
1536
  }
1391
1537
  async function validateRowData(rowValue, params) {
1392
1538
  const result = isVirtualScroll.value ? await serializeOffscreen(() => validateSingleRowViaOffscreenForm(rowValue)) : (await tableRef.value?.validateRowData(rowValue))?.result ?? [];
1393
- if (isVirtualScroll.value) props.onRowValidate?.({
1394
- result,
1395
- trigger: "parent"
1396
- });
1539
+ if (isVirtualScroll.value) {
1540
+ replaceRowValidationErrors(rowValue, result);
1541
+ props.onRowValidate?.({
1542
+ result,
1543
+ trigger: "parent"
1544
+ });
1545
+ }
1397
1546
  const context = {
1398
1547
  result,
1399
1548
  trigger: "parent",
@@ -1558,11 +1707,22 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1558
1707
  sourceRow: props.data?.find((item) => getRowValue(item) === rowValue) ?? data.value.find((item) => getRowValue(item) === rowValue) ?? row,
1559
1708
  updateEditedCellValue: context.updateEditedCellValue,
1560
1709
  notifyDataChange,
1710
+ getHorizontalScroll: () => getCurrentTableContentEl()?.scrollLeft,
1711
+ setHorizontalScroll: (scrollLeft) => {
1712
+ const scrollEl = getCurrentTableContentEl();
1713
+ if (!scrollEl || scrollEl.scrollLeft === scrollLeft) return;
1714
+ scrollEl.scrollLeft = scrollLeft;
1715
+ },
1561
1716
  lazy: resolveFormItemLazy(column),
1562
1717
  active: !!activeEditingCell.value && isSameEditingCell(activeEditingCell.value, {
1563
1718
  row,
1564
1719
  colKey
1565
1720
  }),
1721
+ autofocus: !!autofocusEditingCell.value && isSameEditingCell(autofocusEditingCell.value, {
1722
+ row,
1723
+ colKey
1724
+ }),
1725
+ validationErrors: editingCellValidationErrors.value.get(getRowValue(row))?.get(String(colKey)),
1566
1726
  renderCell: () => renderDisplayCell(h, column, cellContext),
1567
1727
  activate: () => {
1568
1728
  if (suppressEnterCellKey === getCellKey(row, colKey)) return;
@@ -1571,6 +1731,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1571
1731
  colKey
1572
1732
  });
1573
1733
  },
1734
+ consumeAutofocus: () => clearAutofocusEditingCell({
1735
+ row,
1736
+ colKey
1737
+ }),
1574
1738
  registerBeforeSubmit: registerBeforeSubmitQueue
1575
1739
  };
1576
1740
  }
@@ -1818,6 +1982,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1818
1982
  watch(expandedTreeNodes, adjustScrollWhenTreeExpanded, {
1819
1983
  flush: "post"
1820
1984
  });
1985
+ watch(data, pruneCellValidationErrors);
1821
1986
  watch(tableContentVisible, (visible) => {
1822
1987
  if (!visible) return;
1823
1988
  watchAnimatingTransformAncestor();
@@ -1953,7 +2118,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1953
2118
  }, [renderList(_ctx.$slots, (_, name) => {
1954
2119
  return {
1955
2120
  name,
1956
- fn: withCtx((slotProps) => [renderSlot(_ctx.$slots, name, normalizeProps(guardReactiveProps(slotProps)), void 0, true)])
2121
+ fn: withCtx((slotProps) => [renderSlot(_ctx.$slots, name, normalizeProps(guardReactiveProps(resolveForwardedSlotProps(String(name), slotProps))), void 0, true)])
1957
2122
  };
1958
2123
  })]), 1040, ["class", "selected-row-keys", "active-row-keys", "column-controller-visible", "display-columns", "expanded-row-keys", "filter-value", "sort", "expanded-tree-nodes", "columns", "loading", "data", "pagination"])), [[unref(vResize), onResize], [vHorizontalWheel]]);
1959
2124
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qidian-vue-ui",
3
- "version": "2.0.26",
3
+ "version": "2.0.28",
4
4
  "description": "基于 TDesign 的 QiDian Vue UI 组件库",
5
5
  "author": "qidian",
6
6
  "license": "MIT",