@zat-design/sisyphus-react 4.5.8 → 4.5.9-beta.1
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/dist/index.esm.css +1 -1
- package/dist/less.esm.css +1 -1
- package/es/ProEditTable/components/RenderField/index.js +28 -27
- package/es/ProEditTable/propsType.d.ts +4 -4
- package/es/ProEditTable/utils/useShouldUpdateForTable.d.ts +2 -0
- package/es/ProEditTable/utils/useShouldUpdateForTable.js +4 -1
- package/es/ProForm/components/combination/ProModalSelect/hooks/useRequestList.js +4 -2
- package/es/ProLayout/components/TabsManager/style/index.less +1 -2
- package/es/ProTable/components/EditableCell/EditIcon.js +3 -2
- package/es/ProTable/components/EditableCell/index.js +3 -2
- package/es/ProTable/style/index.less +26 -0
- package/package.json +1 -1
- package/es/ProTable/components/EditableCell/index.less +0 -24
|
@@ -26,7 +26,7 @@ import { getDefaultProps } from "../../utils/getDefaultProps";
|
|
|
26
26
|
import ListChangedWrapper from "./ListChangedWrapper";
|
|
27
27
|
import useShouldUpdateForTable from "../../utils/useShouldUpdateForTable";
|
|
28
28
|
import { OMIT_FORM_ITEM_AND_DOM_KEYS, arePropsEqual, hasRowFunctionDependency, mergeOnFieldChangeRow } from "./tools";
|
|
29
|
-
import {
|
|
29
|
+
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
30
30
|
const RenderField = ({
|
|
31
31
|
text: value,
|
|
32
32
|
record,
|
|
@@ -90,6 +90,8 @@ const RenderField = ({
|
|
|
90
90
|
|
|
91
91
|
// type类型 首字母转大写
|
|
92
92
|
type = type?.replace?.(type[0], type[0].toUpperCase()) || 'Input';
|
|
93
|
+
const fallbackType = type;
|
|
94
|
+
const hasCustomComponent = 'component' in column || 'editRender' in column;
|
|
93
95
|
|
|
94
96
|
// 自定义组件时 防止默认值影像后续判断
|
|
95
97
|
if ('component' in column) {
|
|
@@ -176,7 +178,7 @@ const RenderField = ({
|
|
|
176
178
|
|
|
177
179
|
// component 处理 - 优先使用 hook 返回的值
|
|
178
180
|
if (_isFunction(lastComponent)) {
|
|
179
|
-
lastComponent = dynamicProps.component
|
|
181
|
+
lastComponent = dynamicProps.componentResolved ? dynamicProps.component : lastComponent(rowData, reactiveParams);
|
|
180
182
|
}
|
|
181
183
|
|
|
182
184
|
// 更新 lastEditRender 为处理后的 lastComponent
|
|
@@ -198,6 +200,23 @@ const RenderField = ({
|
|
|
198
200
|
|
|
199
201
|
// 多态:可能是内置组件类型、自定义 component,或已渲染的 ReactElement(lastEditRender),保留显式 any
|
|
200
202
|
let TargetComponent;
|
|
203
|
+
const fallbackTargetComponent = typeof fallbackType === 'string' ? componentMap[fallbackType] : undefined;
|
|
204
|
+
const invalidComponentWarnedRef = useRef(false);
|
|
205
|
+
const resolveEditTargetComponent = candidate => {
|
|
206
|
+
if ( /*#__PURE__*/React.isValidElement(candidate)) {
|
|
207
|
+
invalidComponentWarnedRef.current = false;
|
|
208
|
+
return candidate;
|
|
209
|
+
}
|
|
210
|
+
if (hasCustomComponent && !invalidComponentWarnedRef.current && process.env.NODE_ENV !== 'production') {
|
|
211
|
+
const columnName = dataIndex ?? column?.name ?? title ?? originTitle ?? 'unknown';
|
|
212
|
+
console.warn('[ProEditTable] component 必须返回合法的 ReactElement,已回退到内置组件。', {
|
|
213
|
+
column: Array.isArray(columnName) ? columnName.join('.') : String(columnName),
|
|
214
|
+
received: candidate
|
|
215
|
+
});
|
|
216
|
+
invalidComponentWarnedRef.current = true;
|
|
217
|
+
}
|
|
218
|
+
return fallbackTargetComponent;
|
|
219
|
+
};
|
|
201
220
|
|
|
202
221
|
// 将Hooks调用移到组件顶层
|
|
203
222
|
const proConfig = useProConfig();
|
|
@@ -320,20 +339,9 @@ const RenderField = ({
|
|
|
320
339
|
...valueTypeTransform()
|
|
321
340
|
}, form, names, namesStr, type);
|
|
322
341
|
}, [names, baseName, index, dataIndex, lastFormItemProps, type]);
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
TargetComponent =
|
|
326
|
-
}
|
|
327
|
-
if (isEditable && isEditing) {
|
|
328
|
-
// lastEditRender 已经是处理后的值(通过 dynamicProps.component 或直接计算)
|
|
329
|
-
// 如果原本是函数,此时 lastEditRender 已经是执行后的 ReactNode
|
|
330
|
-
// 如果原本是 ReactElement,lastEditRender 就是 ReactElement
|
|
331
|
-
if ( /*#__PURE__*/React.isValidElement(lastEditRender)) {
|
|
332
|
-
TargetComponent = lastEditRender;
|
|
333
|
-
} else if (lastEditRender) {
|
|
334
|
-
// 其他情况(可能是字符串或其他类型的 ReactNode)
|
|
335
|
-
TargetComponent = lastEditRender;
|
|
336
|
-
}
|
|
342
|
+
TargetComponent = fallbackTargetComponent;
|
|
343
|
+
if (isEditable && isEditing && hasCustomComponent) {
|
|
344
|
+
TargetComponent = resolveEditTargetComponent(lastEditRender);
|
|
337
345
|
}
|
|
338
346
|
|
|
339
347
|
// 查看模式
|
|
@@ -729,10 +737,7 @@ const RenderField = ({
|
|
|
729
737
|
onChange: handleChange,
|
|
730
738
|
onBlur: handleBlur
|
|
731
739
|
};
|
|
732
|
-
let latestTargetComponent = TargetComponent;
|
|
733
|
-
if (!canReuseCurrentState && !latestComponent && typeof type === 'string') {
|
|
734
|
-
latestTargetComponent = componentMap[type] ?? /*#__PURE__*/_jsx(_Fragment, {});
|
|
735
|
-
}
|
|
740
|
+
let latestTargetComponent = canReuseCurrentState ? TargetComponent : fallbackTargetComponent;
|
|
736
741
|
|
|
737
742
|
// 然后处理自定义 component
|
|
738
743
|
const latestIsView = !latestIsEditable || record?.['is-view'] || config.isView || virtualKey && !isEditing || getDisabled({
|
|
@@ -744,12 +749,8 @@ const RenderField = ({
|
|
|
744
749
|
params: latestRowParams,
|
|
745
750
|
rowDisabled: rowDisabled || 'empty'
|
|
746
751
|
});
|
|
747
|
-
if (!canReuseCurrentState && latestIsEditable && isEditing) {
|
|
748
|
-
|
|
749
|
-
latestTargetComponent = latestComponent;
|
|
750
|
-
} else if (latestComponent) {
|
|
751
|
-
latestTargetComponent = latestComponent;
|
|
752
|
-
}
|
|
752
|
+
if (!canReuseCurrentState && latestIsEditable && isEditing && hasCustomComponent) {
|
|
753
|
+
latestTargetComponent = resolveEditTargetComponent(latestComponent);
|
|
753
754
|
}
|
|
754
755
|
|
|
755
756
|
// 查看模式
|
|
@@ -936,7 +937,7 @@ const RenderField = ({
|
|
|
936
937
|
}) : /*#__PURE__*/_jsx(Container, {
|
|
937
938
|
viewEmpty: viewEmpty
|
|
938
939
|
});
|
|
939
|
-
if (type === 'FormList') {
|
|
940
|
+
if (type === 'FormList' && !hasCustomComponent && TargetComponent) {
|
|
940
941
|
FormItem = /*#__PURE__*/_jsx(Form.List, {
|
|
941
942
|
name: formNamePath ? cellName.slice(formNamePath?.length - 1) : cellName,
|
|
942
943
|
..._omit(activeFinalFormItemProps, ['render', 'key', 'width', 'hiddenNames', 'name']),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AffixProps, ModalFuncProps } from 'antd';
|
|
2
|
-
import { Key, ReactNode } from 'react';
|
|
2
|
+
import { Key, ReactElement, ReactNode } from 'react';
|
|
3
3
|
import { DragEndEvent } from '@dnd-kit/core';
|
|
4
4
|
import type { ButtonProps } from 'antd/es/button';
|
|
5
5
|
import type { TooltipProps } from 'antd/es/tooltip';
|
|
@@ -134,7 +134,7 @@ export type viewRenderFn<T = any> = (text?: any, record?: T, options?: OptionsPr
|
|
|
134
134
|
* 组件渲染函数类型(与 ReactiveFunction 保持一致)
|
|
135
135
|
* @template T 记录类型
|
|
136
136
|
*/
|
|
137
|
-
export type ComponentRenderFn<T = any> = ReactiveFunction<T,
|
|
137
|
+
export type ComponentRenderFn<T = any> = ReactiveFunction<T, ReactElement>;
|
|
138
138
|
/**
|
|
139
139
|
* 表格列属性接口
|
|
140
140
|
* @template Values 值类型
|
|
@@ -157,8 +157,8 @@ export interface ProColumnsProps<Values = any, T = any> extends Omit<FormItemPro
|
|
|
157
157
|
tooltip?: string | ({
|
|
158
158
|
icon?: string | ReactNode;
|
|
159
159
|
} & TooltipProps);
|
|
160
|
-
/**
|
|
161
|
-
component?:
|
|
160
|
+
/** 自定义组件,或返回合法 ReactElement 的响应式渲染函数 */
|
|
161
|
+
component?: ReactElement | ComponentRenderFn<T>;
|
|
162
162
|
/** 视图渲染 */
|
|
163
163
|
viewRender?: string | number | ReactNode | viewRenderFn<T>;
|
|
164
164
|
/** 隐藏的字段名 */
|
|
@@ -11,6 +11,8 @@ interface Result {
|
|
|
11
11
|
desensitization: any;
|
|
12
12
|
valueType: any;
|
|
13
13
|
component: any;
|
|
14
|
+
/** 动态 component 是否已经执行过,用于区分“返回 undefined”和“尚未计算”。 */
|
|
15
|
+
componentResolved: boolean;
|
|
14
16
|
/** 当前缓存结果对应的行浅快照,供 RenderField 判断是否可安全复用。 */
|
|
15
17
|
rowSnapshot: Record<string, any> | undefined;
|
|
16
18
|
}
|
|
@@ -19,6 +19,7 @@ const useShouldUpdateForTable = props => {
|
|
|
19
19
|
const desensitizationRef = useRef(undefined);
|
|
20
20
|
const valueTypeRef = useRef(undefined);
|
|
21
21
|
const componentRef = useRef(undefined);
|
|
22
|
+
const componentResolvedRef = useRef(false);
|
|
22
23
|
const resolvedRowSnapshotRef = useRef(undefined);
|
|
23
24
|
const [, reRender] = useState({});
|
|
24
25
|
const debouncedUpdateRef = useRef(null);
|
|
@@ -101,6 +102,7 @@ const useShouldUpdateForTable = props => {
|
|
|
101
102
|
const componentOrEditRender = column.component || column.editRender;
|
|
102
103
|
if (_isFunction(componentOrEditRender)) {
|
|
103
104
|
const newComponent = componentOrEditRender(values, reactiveParams);
|
|
105
|
+
componentResolvedRef.current = true;
|
|
104
106
|
// 对于 ReactNode 类型的返回值,使用深度比较
|
|
105
107
|
if (!_isEqualWith(componentRef.current, newComponent, customEqualForFunction)) {
|
|
106
108
|
componentRef.current = newComponent;
|
|
@@ -170,7 +172,8 @@ const useShouldUpdateForTable = props => {
|
|
|
170
172
|
fieldProps: fieldPropsRef.current ?? column.fieldProps,
|
|
171
173
|
desensitization: desensitizationRef.current ?? column.desensitization,
|
|
172
174
|
valueType: valueTypeRef.current ?? column.valueType,
|
|
173
|
-
component: componentRef.current
|
|
175
|
+
component: componentResolvedRef.current ? componentRef.current : column.component || column.editRender,
|
|
176
|
+
componentResolved: componentResolvedRef.current,
|
|
174
177
|
rowSnapshot: resolvedRowSnapshotRef.current
|
|
175
178
|
};
|
|
176
179
|
};
|
|
@@ -81,9 +81,11 @@ export function useRequestList(service, options, useRequestOptions) {
|
|
|
81
81
|
});
|
|
82
82
|
}, [onPageChange]);
|
|
83
83
|
const onSearch = useCallback(values => {
|
|
84
|
+
if (page.pageNum !== 1) {
|
|
85
|
+
// 查询或重置都从第一页开始,保留当前每页条数
|
|
86
|
+
onChange(1, page.pageSize);
|
|
87
|
+
}
|
|
84
88
|
if (!_isEqual(searchValues, values)) {
|
|
85
|
-
// 保留当前页码和每页条数
|
|
86
|
-
onChange(page.pageNum, page.pageSize);
|
|
87
89
|
setSearchValues(values);
|
|
88
90
|
}
|
|
89
91
|
}, [onChange, searchValues, page]);
|
|
@@ -171,12 +171,11 @@
|
|
|
171
171
|
padding: 4px 0 5px !important;
|
|
172
172
|
margin-right: 8px !important;
|
|
173
173
|
margin-left: 0;
|
|
174
|
-
background: #
|
|
174
|
+
background: #F5F5F5;
|
|
175
175
|
transition: none;
|
|
176
176
|
border-color: #e7e8ee;
|
|
177
177
|
&.@{ant-prefix}-tabs-tab-active {
|
|
178
178
|
background: #ffffff;
|
|
179
|
-
border-top: 2px solid var(--zaui-brand, #006aff);
|
|
180
179
|
}
|
|
181
180
|
}
|
|
182
181
|
.ant-tabs-nav {
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { EditOutlined } from '@ant-design/icons';
|
|
2
|
+
import classNames from 'classnames';
|
|
2
3
|
import React from 'react';
|
|
3
|
-
import styles from "./index.less";
|
|
4
4
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
5
5
|
const EditIcon = ({
|
|
6
6
|
onClick
|
|
7
7
|
}) => {
|
|
8
|
+
const cls = classNames('pro-table-editable-cell-edit-icon');
|
|
8
9
|
return /*#__PURE__*/_jsx("span", {
|
|
9
|
-
className:
|
|
10
|
+
className: cls,
|
|
10
11
|
onClick: onClick,
|
|
11
12
|
children: /*#__PURE__*/_jsx(EditOutlined, {})
|
|
12
13
|
});
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import _isEqual from "lodash/isEqual";
|
|
2
2
|
import React, { useState, useRef } from 'react';
|
|
3
3
|
import { Form } from 'antd';
|
|
4
|
+
import classNames from 'classnames';
|
|
4
5
|
import * as componentMap from "../../../ProForm/components";
|
|
5
6
|
import EditIcon from "./EditIcon";
|
|
6
|
-
import styles from "./index.less";
|
|
7
7
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
8
8
|
const InternalCell = ({
|
|
9
9
|
value,
|
|
@@ -29,6 +29,7 @@ const InternalCell = ({
|
|
|
29
29
|
...restFieldProps
|
|
30
30
|
} = fieldProps;
|
|
31
31
|
const Component = componentMap[type] ?? componentMap.Input;
|
|
32
|
+
const wrapperClassName = classNames('pro-table-editable-cell-wrapper');
|
|
32
33
|
const handleEditIconClick = () => {
|
|
33
34
|
snapshotRef.current = value;
|
|
34
35
|
form.setFieldValue(fieldName, value);
|
|
@@ -57,7 +58,7 @@ const InternalCell = ({
|
|
|
57
58
|
};
|
|
58
59
|
if (!editing) {
|
|
59
60
|
return /*#__PURE__*/_jsxs("span", {
|
|
60
|
-
className:
|
|
61
|
+
className: wrapperClassName,
|
|
61
62
|
children: [/*#__PURE__*/_jsx("span", {
|
|
62
63
|
children: displayContent ?? '-'
|
|
63
64
|
}), /*#__PURE__*/_jsx(EditIcon, {
|
|
@@ -624,6 +624,32 @@
|
|
|
624
624
|
}
|
|
625
625
|
}
|
|
626
626
|
}
|
|
627
|
+
|
|
628
|
+
.pro-table-editable-cell-wrapper {
|
|
629
|
+
display: flex;
|
|
630
|
+
align-items: center;
|
|
631
|
+
width: 100%;
|
|
632
|
+
justify-content: space-between;
|
|
633
|
+
gap: 4px;
|
|
634
|
+
white-space: nowrap;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
.pro-table-editable-cell-edit-icon {
|
|
638
|
+
display: inline-flex;
|
|
639
|
+
align-items: center;
|
|
640
|
+
color: #d8d8d8;
|
|
641
|
+
cursor: pointer;
|
|
642
|
+
visibility: hidden;
|
|
643
|
+
flex-shrink: 0;
|
|
644
|
+
|
|
645
|
+
&:hover {
|
|
646
|
+
color: var(--zaui-brand, #006aff);
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
td:hover .pro-table-editable-cell-edit-icon {
|
|
651
|
+
visibility: visible;
|
|
652
|
+
}
|
|
627
653
|
}
|
|
628
654
|
|
|
629
655
|
.@{ant-prefix}-dropdown-placement-bottomLeft {
|
package/package.json
CHANGED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
.editable-cell-wrapper {
|
|
2
|
-
display: flex;
|
|
3
|
-
align-items: center;
|
|
4
|
-
width: 100%;
|
|
5
|
-
justify-content: space-between;
|
|
6
|
-
gap: 4px;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
.editable-cell-edit-icon {
|
|
10
|
-
display: inline-flex;
|
|
11
|
-
align-items: center;
|
|
12
|
-
cursor: pointer;
|
|
13
|
-
visibility: hidden;
|
|
14
|
-
color: rgba(0, 0, 0, 0.65);
|
|
15
|
-
flex-shrink: 0;
|
|
16
|
-
|
|
17
|
-
&:hover {
|
|
18
|
-
color: var(--zaui-brand, #006aff);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
td:hover .editable-cell-edit-icon {
|
|
23
|
-
visibility: visible;
|
|
24
|
-
}
|