Skip to content

Commit 7b4530d

Browse files
fix: resolve 6 issues - valueType priority, select ellipsis, vi-VN locale, onFinish error visibility
- #9002: explicit valueType is no longer overridden by valueEnum/request inference. Added isDefaultValueType marker in ProFieldCore; FormRender and columnRender now pass valueType: undefined when unset to preserve the default marker (4 regression tests) - #8978: select read-mode enum output wrapped in span so Typography.Text ellipsis works with ellipsis+copyable (regression test) - #9016: empty-string locale messages (e.g. vi-VN pagination range) are now respected instead of falling back to zh-CN (2 tests) - #9019: onFinish errors are no longer silently swallowed; exposed via console.error while keeping loading-state behavior (test updated) - #8973: verified array shape preserved after reset on antd6; locked with regression test - #9033: verified SchemaForm formList renders labels on every row; locked with regression test Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 0315cb9 commit 7b4530d

16 files changed

Lines changed: 303 additions & 17 deletions

‎src/field/AllProField.tsx‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,11 @@ function renderDefaultValueTypeLeaf(
352352

353353
if (
354354
valueType === 'select' ||
355-
(valueType === 'text' && (props.valueEnum || props.request))
355+
// #9002 仅缺省 valueType(未显式指定)时才根据 valueEnum/request 推断为 select,
356+
// 显式传入 valueType: 'text' 的列即使带 valueEnum 也按文本渲染
357+
(valueType === 'text' &&
358+
props.isDefaultValueType &&
359+
(props.valueEnum || props.request))
356360
) {
357361
return wrapProFieldLight(
358362
props.light,

‎src/field/ProFieldCore.tsx‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ export function createProField(
6666
> = (
6767
{
6868
text,
69-
valueType = 'text',
69+
valueType,
7070
mode = 'read',
7171
onChange,
7272
formItemRender,
@@ -98,6 +98,11 @@ export function createProField(
9898
options.pickProPropsWithValueTypeMap &&
9999
Object.keys(context.valueTypeMap || {}).includes(String(valueType));
100100

101+
// #9002 显式传入的 valueType 不再被 valueEnum/request 智能推断覆盖:
102+
// 仅当调用方未设置 valueType(缺省 'text')时才允许推断为 select 等类型,
103+
// 用于区分「用户显式要 text」与「历史默认行为(有 valueEnum 就渲染 select)」
104+
const isDefaultValueType = valueType === undefined;
105+
101106
const effectiveMode = readonly ? 'read' : mode;
102107
/** 取值顺序仍以原始 mode 为准(readonly + mode=edit 时仍按编辑态取 fieldProps.value) */
103108
const dataValue =
@@ -115,6 +120,10 @@ export function createProField(
115120
omitUndefined({
116121
ref,
117122
...rest,
123+
// #9002 标记 valueType 是否为缺省值(undefined 时补 'text')。
124+
// AllProField / ValueTypeToComponent 依据此标记决定是否做
125+
// 「valueEnum/request → select」的智能推断,显式 valueType 优先。
126+
isDefaultValueType,
118127
mode: effectiveMode,
119128
formItemRender: formItemRender
120129
? (

‎src/field/ValueTypeToComponent.tsx‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,8 @@ const ValueTypeToComponentMap: Record<
268268
wrapProFieldLight(props.light, <FieldSelect {...props} text={text} />),
269269
),
270270
text: sameRenderPair((text, props) =>
271-
'valueEnum' in props ? (
271+
// #9002 仅缺省 valueType 时才根据 valueEnum 推断为 select(与 AllProField 行为一致)
272+
'valueEnum' in props && props.isDefaultValueType ? (
272273
wrapProFieldLight(props.light, <FieldSelect {...props} text={text} />)
273274
) : (
274275
<FieldText {...props} text={text as string} />

‎src/field/components/Select/FieldSelectRead.tsx‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,18 @@ type Props = Parameters<
1919
export function FieldSelectRead(props: Props) {
2020
const { mode, render, fieldProps, valueEnum, optionsValueEnum, ...rest } =
2121
props;
22+
// #8978 用单个 span 包裹枚举渲染结果(多选时是一串 Badge):
23+
// Typography.Text 的 ellipsis 只对纯文本子节点生效,
24+
// Fragment 列表会让省略失效,包一层后省略/复制行为恢复正常
2225
const dom = (
23-
<>
26+
<span className="pro-field-select-read">
2427
{proFieldParsingText(
2528
rest.text,
2629
objectToMap(
2730
valueEnum || optionsValueEnum,
2831
) as unknown as ProSchemaValueEnumObj,
2932
)}
30-
</>
33+
</span>
3134
);
3235

3336
if (render) {

‎src/field/types.ts‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ export type ProFieldRenderProps = Omit<
4141
emptyText?: React.ReactNode;
4242
open?: boolean;
4343
onOpenChange?: (open: boolean) => void;
44+
/**
45+
* #9002 内部标记:valueType 为缺省值(调用方未显式传入)时为 true。
46+
* 渲染函数依据它决定是否做「valueEnum/request → select」智能推断,
47+
* 显式传入的 valueType 永远优先。外部无需关心此字段。
48+
*/
49+
isDefaultValueType?: boolean;
4450
[key: string]: any;
4551
};
4652

‎src/form/BaseForm/BaseForm.tsx‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,12 @@ export function BaseForm<T = Record<string, any>, U = Record<string, any>>(
714714
}
715715
} catch (error) {
716716
setLoading(false);
717+
// #9019 不再静默吞掉 onFinish 的异常:
718+
// 保留错误可见性(console.error),同时避免 async 事件回调里 re-throw
719+
// 造成的 unhandled rejection(会中断用户页面)。若需要感知失败,
720+
// 推荐在 onFinish 内部自行 try/catch。
721+
// eslint-disable-next-line no-console
722+
console.error('[ProForm] onFinish error:', error);
717723
}
718724
});
719725

‎src/form/components/Field/index.tsx‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ const BaseProFormField = React.forwardRef<
123123
text={fieldProps?.[valuePropName]}
124124
render={render as any}
125125
formItemRender={formItemRender as any}
126-
valueType={(valueType ?? 'text') as ProFieldValueTypeInput}
126+
// #9002 保持 valueType 为 undefined 透传(缺省标记),不要在此处补 'text':
127+
// ProFieldCore 依据「是否显式传入」决定 valueEnum → select 的智能推断
128+
valueType={valueType as ProFieldValueTypeInput}
127129
cacheForSwr={cacheForSwr}
128130
fieldProps={memoFieldProps}
129131
valueEnum={runFunction(valueEnum)}

‎src/provider/intl.ts‎

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,18 @@ const zhCNMessages: Record<string, any> = zhCN;
5151
* 从 locale messages 中按 id 取值的工具。id 支持点号路径和方括号下标:
5252
* - `a.b.c`
5353
* - `a.b[0].c`
54+
* 返回 undefined 表示「该 locale 未定义此 key」;空字符串是合法文案(如 vi-VN
55+
* 的 `pagination.total.range: ' '`),不应被当作缺失而回落到 zh-CN(#9016)。
5456
*/
5557
const getMessageByPath = (
5658
messages: Record<string, any>,
5759
id: string,
58-
): string => {
59-
return (get(messages, id.replace(/\[(\d+)\]/g, '.$1').split('.')) ||
60-
'') as string;
60+
): string | undefined => {
61+
const value = get(
62+
messages,
63+
id.replace(/\[(\d+)\]/g, '.$1').split('.'),
64+
) as unknown;
65+
return typeof value === 'string' ? value : undefined;
6166
};
6267

6368
/**
@@ -76,7 +81,8 @@ export const createIntl = (
7681
): IntlType => ({
7782
getMessage: (id: string, defaultMessage: string) => {
7883
const msg = getMessageByPath(localeMap, id);
79-
if (msg) return msg;
84+
// 空字符串是合法文案(故意留空,如 vi-VN 分页范围前缀),直接返回
85+
if (msg !== undefined) return msg;
8086
const localeKeyDashed = locale.replace('_', '-');
8187
if (localeKeyDashed === 'zh-CN') {
8288
return defaultMessage;

‎src/table/components/Form/FormRender.tsx‎

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -153,12 +153,15 @@ const FormRender = <T, U = any>({
153153
return true;
154154
})
155155
.map((item) => {
156-
const finalValueType =
157-
!item.valueType ||
158-
(['textarea', 'jsonCode', 'code'].includes(item?.valueType) &&
159-
type === 'table')
160-
? 'text'
161-
: (item?.valueType as 'text');
156+
// #9002 未显式配置 valueType 时保留 undefined(缺省标记),
157+
// 让 ProFieldCore 依据「是否显式传入」决定 valueEnum → select 的推断;
158+
// 仅 table 场景下的 textarea/jsonCode/code 需要强转为 text
159+
const isTableOnlyCodeType =
160+
['textarea', 'jsonCode', 'code'].includes(item?.valueType) &&
161+
type === 'table';
162+
const finalValueType = isTableOnlyCodeType
163+
? 'text'
164+
: (item?.valueType as 'text' | undefined);
162165
const columnKey = item?.key || item?.dataIndex?.toString();
163166

164167
return {

‎src/table/utils/columnRender.tsx‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,9 @@ export function columnRender<T extends AnyObject>({
130130

131131
const textDom = cellRenderToFromItem<T>({
132132
text: renderTextStr,
133-
valueType: (columnProps.valueType as ProFieldValueType) || 'text',
133+
// #9002 未显式配置 valueType 时传 undefined(保留缺省标记),
134+
// 由 ProFieldCore 决定是否按 valueEnum 推断 select,不要在此处补 'text'
135+
valueType: columnProps.valueType as ProFieldValueType | undefined,
134136
index,
135137
rowData,
136138
subName,

0 commit comments

Comments
 (0)