@zat-design/sisyphus-react 4.5.0-beta.1 → 4.5.0-beta.3
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.
- package/es/ProEditTable/components/Validator/index.js +3 -3
- package/es/ProEditTable/utils/tools.d.ts +13 -7
- package/es/ProEditTable/utils/tools.js +52 -24
- package/es/ProEditTable/utils/validateAll.d.ts +3 -0
- package/es/ProEditTable/utils/validateAll.js +8 -3
- package/es/ProForm/components/combination/Group/utils/index.d.ts +12 -12
- package/package.json +1 -1
|
@@ -22,7 +22,7 @@ const Validator = ({
|
|
|
22
22
|
const {
|
|
23
23
|
hasError,
|
|
24
24
|
firstErrorIndex,
|
|
25
|
-
|
|
25
|
+
firstErrorColumnKey
|
|
26
26
|
} = await runUnifiedValidation({
|
|
27
27
|
form: config.form,
|
|
28
28
|
name: config.name,
|
|
@@ -38,9 +38,9 @@ const Validator = ({
|
|
|
38
38
|
config?.tableRef?.current?.scrollTo?.({
|
|
39
39
|
index: firstErrorIndex
|
|
40
40
|
});
|
|
41
|
-
//
|
|
41
|
+
// 横向:把报错列滚入视口(虚拟表格列被虚拟化,按表头列宽算 scrollLeft,与行渲染无关)
|
|
42
42
|
requestAnimationFrame(() => {
|
|
43
|
-
scrollVirtualToErrorColumn(config?.tableRef,
|
|
43
|
+
scrollVirtualToErrorColumn(config?.tableRef, columns || [], firstErrorColumnKey);
|
|
44
44
|
});
|
|
45
45
|
});
|
|
46
46
|
}
|
|
@@ -90,16 +90,22 @@ export declare const getDisabled: ({ globalControl, formDisabled, column, tabled
|
|
|
90
90
|
*/
|
|
91
91
|
export declare const handleScrollToError: () => void;
|
|
92
92
|
/**
|
|
93
|
-
*
|
|
93
|
+
* 把「首个报错列的 cellKey」映射成它在表头 th 中的可见列索引。
|
|
94
|
+
* 列序 = [选择列?(hasSelection 时占位 1), ...用户列];names 列的 cellKey 用 splitNames 结果。
|
|
95
|
+
* @returns 表头 th 下标;未命中返回 -1
|
|
96
|
+
*/
|
|
97
|
+
export declare const resolveErrorColumnIndex: (columns: any[], cellKey: string, hasSelection: boolean) => number;
|
|
98
|
+
/**
|
|
99
|
+
* 虚拟表格:横向滚动定位到「首个报错列」。
|
|
94
100
|
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
101
|
+
* 背景:rc-table 虚拟表格对「列」也做了虚拟化(BodyGrid 仅渲染横向视口内的列),
|
|
102
|
+
* 保存校验失败时报错列可能根本未渲染进 body DOM,无法用单元格测量定位(旧实现据此失效)。
|
|
103
|
+
* 而表头(thead)不被列虚拟化——渲染全部列且为真实测量宽度,故改以表头为列宽来源:
|
|
104
|
+
* 累加报错列之前各列宽、减去 fixed-left 列宽(固定列悬浮,不占滚动偏移)得目标 scrollLeft。
|
|
99
105
|
*
|
|
100
|
-
*
|
|
106
|
+
* 注意:ref.nativeElement 仅为 body 滚动容器,表头在其外层 table-container 内,需向上查找。
|
|
101
107
|
*/
|
|
102
|
-
export declare const scrollVirtualToErrorColumn: (tableRef: React.MutableRefObject<any>,
|
|
108
|
+
export declare const scrollVirtualToErrorColumn: (tableRef: React.MutableRefObject<any>, columns: any[], cellKey?: string | null) => void;
|
|
103
109
|
/**
|
|
104
110
|
* 深copy一个对象,并过滤掉其中的React节点
|
|
105
111
|
* @param value 需要深拷贝的对象
|
|
@@ -276,6 +276,13 @@ export const getDisabled = ({
|
|
|
276
276
|
return convertToBoolean(column?.disabled ?? columnFieldProps?.disabled ?? tabledDisabled);
|
|
277
277
|
};
|
|
278
278
|
|
|
279
|
+
/**
|
|
280
|
+
* 判断单元格是否为「左固定列」。
|
|
281
|
+
* antd6 固定列类名为 *-cell-fix-start(逻辑属性,支持 RTL),不再是旧版的 *-cell-fix-left;
|
|
282
|
+
* 兼容两者,避免漏算固定列宽导致报错单元格被固定列遮挡。
|
|
283
|
+
*/
|
|
284
|
+
const isFixStartCell = el => /table-cell-fix-(start|left)/.test(el.className || '');
|
|
285
|
+
|
|
279
286
|
/**
|
|
280
287
|
* 表格自动滚动到报错位置
|
|
281
288
|
*/
|
|
@@ -297,7 +304,7 @@ export const handleScrollToError = () => {
|
|
|
297
304
|
width = 0
|
|
298
305
|
} = previousSibling.getBoundingClientRect() || {};
|
|
299
306
|
childOffsetLeft += width;
|
|
300
|
-
if (previousSibling
|
|
307
|
+
if (isFixStartCell(previousSibling)) {
|
|
301
308
|
childFixedLeft += width;
|
|
302
309
|
}
|
|
303
310
|
}
|
|
@@ -326,41 +333,62 @@ export const handleScrollToError = () => {
|
|
|
326
333
|
};
|
|
327
334
|
|
|
328
335
|
/**
|
|
329
|
-
*
|
|
336
|
+
* 把「首个报错列的 cellKey」映射成它在表头 th 中的可见列索引。
|
|
337
|
+
* 列序 = [选择列?(hasSelection 时占位 1), ...用户列];names 列的 cellKey 用 splitNames 结果。
|
|
338
|
+
* @returns 表头 th 下标;未命中返回 -1
|
|
339
|
+
*/
|
|
340
|
+
export const resolveErrorColumnIndex = (columns = [], cellKey, hasSelection) => {
|
|
341
|
+
const idx = (columns || []).findIndex(col => {
|
|
342
|
+
if (Array.isArray(col?.names)) {
|
|
343
|
+
return splitNames(col.names) === cellKey;
|
|
344
|
+
}
|
|
345
|
+
return String(col?.name ?? col?.dataIndex ?? col?.key) === cellKey;
|
|
346
|
+
});
|
|
347
|
+
if (idx < 0) {
|
|
348
|
+
return -1;
|
|
349
|
+
}
|
|
350
|
+
return hasSelection ? idx + 1 : idx;
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* 虚拟表格:横向滚动定位到「首个报错列」。
|
|
330
355
|
*
|
|
331
|
-
*
|
|
332
|
-
*
|
|
333
|
-
*
|
|
334
|
-
*
|
|
356
|
+
* 背景:rc-table 虚拟表格对「列」也做了虚拟化(BodyGrid 仅渲染横向视口内的列),
|
|
357
|
+
* 保存校验失败时报错列可能根本未渲染进 body DOM,无法用单元格测量定位(旧实现据此失效)。
|
|
358
|
+
* 而表头(thead)不被列虚拟化——渲染全部列且为真实测量宽度,故改以表头为列宽来源:
|
|
359
|
+
* 累加报错列之前各列宽、减去 fixed-left 列宽(固定列悬浮,不占滚动偏移)得目标 scrollLeft。
|
|
335
360
|
*
|
|
336
|
-
*
|
|
361
|
+
* 注意:ref.nativeElement 仅为 body 滚动容器,表头在其外层 table-container 内,需向上查找。
|
|
337
362
|
*/
|
|
338
|
-
export const scrollVirtualToErrorColumn = (tableRef,
|
|
363
|
+
export const scrollVirtualToErrorColumn = (tableRef, columns, cellKey) => {
|
|
339
364
|
const ref = tableRef?.current;
|
|
340
365
|
const root = ref?.nativeElement;
|
|
341
|
-
if (!ref?.scrollTo || !root ||
|
|
366
|
+
if (!ref?.scrollTo || !root || !cellKey) {
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
// body 容器在外层 table-container 内,表头与其同级,需从 container 取表头
|
|
370
|
+
const container = root.closest('[class*="table-container"]') || root.parentElement;
|
|
371
|
+
const headerCells = container?.querySelectorAll('thead [class*="table-cell"]');
|
|
372
|
+
if (!headerCells?.length) {
|
|
342
373
|
return;
|
|
343
374
|
}
|
|
344
|
-
const
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
if (
|
|
375
|
+
const hasSelection = !!container?.querySelector('thead [class*="selection-column"]');
|
|
376
|
+
const targetIndex = resolveErrorColumnIndex(columns, cellKey, hasSelection);
|
|
377
|
+
// -1 未命中 / 0 为首列(含 fixed-left),无需横向滚动
|
|
378
|
+
if (targetIndex <= 0 || targetIndex >= headerCells.length) {
|
|
348
379
|
return;
|
|
349
380
|
}
|
|
350
381
|
let offsetLeft = 0;
|
|
351
382
|
let fixedLeft = 0;
|
|
352
|
-
let
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
fixedLeft += width;
|
|
361
|
-
}
|
|
383
|
+
for (let i = 0; i < targetIndex; i += 1) {
|
|
384
|
+
const cell = headerCells[i];
|
|
385
|
+
const {
|
|
386
|
+
width = 0
|
|
387
|
+
} = cell.getBoundingClientRect() || {};
|
|
388
|
+
offsetLeft += width;
|
|
389
|
+
if (isFixStartCell(cell)) {
|
|
390
|
+
fixedLeft += width;
|
|
362
391
|
}
|
|
363
|
-
previousSibling = previousSibling.previousElementSibling;
|
|
364
392
|
}
|
|
365
393
|
ref.scrollTo({
|
|
366
394
|
left: Math.max(0, offsetLeft - fixedLeft)
|
|
@@ -46,6 +46,8 @@ export interface ValidateAllResult {
|
|
|
46
46
|
firstErrorPath: (string | number)[] | null;
|
|
47
47
|
/** 首个错误行的 rowKey(用于横向滚动时定位错误行 DOM),无错误为 null */
|
|
48
48
|
firstErrorRowKey: string | null;
|
|
49
|
+
/** 首个错误列的 cellKey(names 列为 splitNames,普通列为列名),用于横向滚动定位列,无错误为 null */
|
|
50
|
+
firstErrorColumnKey: string | null;
|
|
49
51
|
}
|
|
50
52
|
/**
|
|
51
53
|
* 对 form store 中 name 路径下的全量数组数据,逐行逐列用真实规则校验(脱离 DOM)。
|
|
@@ -82,5 +84,6 @@ export declare const runUnifiedValidation: ({ form, name, columns, config, error
|
|
|
82
84
|
hasError: boolean;
|
|
83
85
|
firstErrorIndex: number | null;
|
|
84
86
|
firstErrorRowKey: string | null;
|
|
87
|
+
firstErrorColumnKey: string | null;
|
|
85
88
|
}>;
|
|
86
89
|
export {};
|
|
@@ -199,6 +199,7 @@ export const validateAllRows = async ({
|
|
|
199
199
|
const errorMap = {};
|
|
200
200
|
let firstErrorPath = null;
|
|
201
201
|
let firstErrorRowKey = null;
|
|
202
|
+
let firstErrorColumnKey = null;
|
|
202
203
|
for (let index = 0; index < list.length; index += 1) {
|
|
203
204
|
const rowData = list[index];
|
|
204
205
|
// 行可能为空位(单行编辑增删残留),跳过
|
|
@@ -244,6 +245,7 @@ export const validateAllRows = async ({
|
|
|
244
245
|
if (!firstErrorPath) {
|
|
245
246
|
firstErrorPath = built.namePath;
|
|
246
247
|
firstErrorRowKey = rowKey;
|
|
248
|
+
firstErrorColumnKey = built.cellKey;
|
|
247
249
|
}
|
|
248
250
|
}
|
|
249
251
|
}
|
|
@@ -252,7 +254,8 @@ export const validateAllRows = async ({
|
|
|
252
254
|
hasError: !!firstErrorPath,
|
|
253
255
|
errorMap,
|
|
254
256
|
firstErrorPath,
|
|
255
|
-
firstErrorRowKey
|
|
257
|
+
firstErrorRowKey,
|
|
258
|
+
firstErrorColumnKey
|
|
256
259
|
};
|
|
257
260
|
};
|
|
258
261
|
|
|
@@ -301,7 +304,8 @@ export const runUnifiedValidation = async ({
|
|
|
301
304
|
hasError,
|
|
302
305
|
errorMap,
|
|
303
306
|
firstErrorPath,
|
|
304
|
-
firstErrorRowKey
|
|
307
|
+
firstErrorRowKey,
|
|
308
|
+
firstErrorColumnKey
|
|
305
309
|
} = await validateAllRows({
|
|
306
310
|
form,
|
|
307
311
|
name,
|
|
@@ -314,6 +318,7 @@ export const runUnifiedValidation = async ({
|
|
|
314
318
|
return {
|
|
315
319
|
hasError,
|
|
316
320
|
firstErrorIndex,
|
|
317
|
-
firstErrorRowKey
|
|
321
|
+
firstErrorRowKey,
|
|
322
|
+
firstErrorColumnKey
|
|
318
323
|
};
|
|
319
324
|
};
|
|
@@ -77,32 +77,33 @@ export declare const useFormItemProps: (column: FlexibleGroupColumnType, context
|
|
|
77
77
|
component?: React.ReactNode | ReactiveFunction<any, React.ReactNode>;
|
|
78
78
|
isView?: boolean;
|
|
79
79
|
style?: React.CSSProperties;
|
|
80
|
+
trim?: boolean;
|
|
81
|
+
normalize?: (value: any, prevValue: any, allValues: import("@rc-component/form/lib/interface").Store) => any;
|
|
80
82
|
children?: React.ReactNode | ((form: FormInstance<any>) => React.ReactNode);
|
|
83
|
+
prefixCls?: string;
|
|
84
|
+
trigger?: string;
|
|
85
|
+
id?: string;
|
|
81
86
|
className?: string;
|
|
87
|
+
rootClassName?: string;
|
|
88
|
+
status?: "" | "warning" | "error" | "success" | "validating";
|
|
89
|
+
getValueProps?: ((value: any) => Record<string, unknown>) & ((value: any) => Record<string, unknown>);
|
|
82
90
|
hidden?: boolean;
|
|
83
|
-
id?: string;
|
|
84
91
|
onReset?: () => void;
|
|
92
|
+
vertical?: boolean;
|
|
93
|
+
desensitization?: [number, number] | ReactiveFunction<any, [number, number]>;
|
|
85
94
|
validateTrigger?: string | false | string[];
|
|
86
95
|
preserve?: boolean;
|
|
87
|
-
trim?: boolean;
|
|
88
|
-
normalize?: (value: any, prevValue: any, allValues: import("@rc-component/form/lib/interface").Store) => any;
|
|
89
96
|
clearNotShow?: boolean;
|
|
90
97
|
labelAlign?: import("antd/es/form/interface").FormLabelAlign;
|
|
91
|
-
prefixCls?: string;
|
|
92
98
|
colon?: boolean;
|
|
93
99
|
layout?: import("antd/es/form/Form").FormItemLayout;
|
|
94
100
|
labelCol?: import("antd").ColProps;
|
|
95
101
|
wrapperCol?: import("antd").ColProps;
|
|
96
|
-
rootClassName?: string;
|
|
97
|
-
status?: "" | "validating" | "warning" | "error" | "success";
|
|
98
|
-
vertical?: boolean;
|
|
99
102
|
htmlFor?: string;
|
|
100
103
|
getValueFromEvent?: (...args: import("@rc-component/form/lib/interface").EventArgs) => any;
|
|
101
104
|
shouldUpdate?: import("@rc-component/form/lib/Field").ShouldUpdate<any>;
|
|
102
|
-
trigger?: string;
|
|
103
105
|
validateDebounce?: number;
|
|
104
106
|
valuePropName?: string;
|
|
105
|
-
getValueProps?: ((value: any) => Record<string, unknown>) & ((value: any) => Record<string, unknown>);
|
|
106
107
|
messageVariables?: Record<string, string>;
|
|
107
108
|
initialValue?: any;
|
|
108
109
|
onMetaChange?: (meta: import("@rc-component/form/lib/Field").MetaEvent) => void;
|
|
@@ -112,7 +113,7 @@ export declare const useFormItemProps: (column: FlexibleGroupColumnType, context
|
|
|
112
113
|
hasFeedback?: boolean | {
|
|
113
114
|
icons: import("antd/es/form/FormItem").FeedbackIcons;
|
|
114
115
|
};
|
|
115
|
-
validateStatus?: "" | "
|
|
116
|
+
validateStatus?: "" | "warning" | "error" | "success" | "validating";
|
|
116
117
|
help?: React.ReactNode;
|
|
117
118
|
fieldId?: string;
|
|
118
119
|
valueType?: import("../../../render/propsType").ProFormValueType;
|
|
@@ -126,7 +127,6 @@ export declare const useFormItemProps: (column: FlexibleGroupColumnType, context
|
|
|
126
127
|
upperCase?: boolean;
|
|
127
128
|
toISOString?: boolean;
|
|
128
129
|
toCSTString?: boolean;
|
|
129
|
-
desensitization?: [number, number] | ReactiveFunction<any, [number, number]>;
|
|
130
130
|
name: any;
|
|
131
131
|
dependencies: any[];
|
|
132
132
|
tooltip: string | {
|
|
@@ -141,7 +141,7 @@ export declare const useFormItemProps: (column: FlexibleGroupColumnType, context
|
|
|
141
141
|
* 创建组件属性
|
|
142
142
|
*/
|
|
143
143
|
export declare const createComponentProps: (column: FlexibleGroupColumnType, formItemProps: any) => {
|
|
144
|
-
componentProps: import("lodash").Omit<any, "
|
|
144
|
+
componentProps: import("lodash").Omit<any, "format" | "clearNotShow" | "valueType" | "switchValue" | "dependNames" | "toISOString" | "toCSTString" | "precision">;
|
|
145
145
|
formItemTransform: {
|
|
146
146
|
getValueProps: any;
|
|
147
147
|
normalize: any;
|