Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions demos/field/issue-regression-gallery.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import {
ProCard,
ProForm,
ProFormDigit,
ProFormSelect,
ProFormTreeSelect,
} from '@ant-design/pro-components';
import { Alert, Space, Typography } from 'antd';
import { useState } from 'react';

const remoteOptions = ['Alpha', 'Beta', 'Gamma', 'Delta'];

export default () => {
const [lastSearch, setLastSearch] = useState('(尚未搜索)');
const [treeOpen, setTreeOpen] = useState(false);

return (
<ProCard direction="column" ghost gutter={[0, 16]}>
<Alert
type="info"
showIcon
message="字段回归场景"
description="覆盖对象形式 showSearch、受控 TreeSelect、只读空值、数字前后缀及混合 valueEnum。"
/>
<ProCard title="SearchSelect 回调与远程请求(#9711)">
<Space direction="vertical" style={{ width: '100%' }}>
<Typography.Text type="secondary">
输入关键字时,自定义 onSearch 与 request 会同时收到关键字。
</Typography.Text>
<ProForm submitter={false}>
<ProFormSelect.SearchSelect
name="keyword"
label="远程搜索"
debounceTime={100}
request={async ({ keyWords }) => {
const keyword = keyWords ?? '';
return remoteOptions
.filter((item) =>
item.toLowerCase().includes(keyword.toLowerCase()),
)
.map((item) => ({ label: item, value: item }));
}}
fieldProps={{
showSearch: {
onSearch: (value) => setLastSearch(value || '(空)'),
},
}}
/>
</ProForm>
<Typography.Text code>onSearch: {lastSearch}</Typography.Text>
</Space>
</ProCard>
<ProCard title="字段数据流与只读展示(B7–B10)">
<ProForm
submitter={false}
initialValues={{ amount: 128, status: 0, category: 'frontend' }}
layout="horizontal"
>
<ProFormDigit
name="amount"
label="带前后缀数字"
fieldProps={{ prefix: '¥', addonAfter: '元' }}
/>
<ProFormSelect
name="status"
label="混合值 valueEnum"
valueEnum={
new Map<string | number, React.ReactNode>([
[0, '未开始'],
['1', '进行中'],
[2, '已完成'],
])
}
/>
<ProFormTreeSelect
name="category"
label="受控 TreeSelect"
fieldProps={{
open: treeOpen,
onOpenChange: setTreeOpen,
treeData: [
{
title: '研发',
value: 'development',
children: [
{ title: '前端', value: 'frontend' },
{ title: '后端', value: 'backend' },
],
},
],
}}
/>
<ProFormDigit
label="只读空值"
name="empty"
readonly
fieldProps={{ addonAfter: '次' }}
/>
</ProForm>
</ProCard>
</ProCard>
);
};
152 changes: 152 additions & 0 deletions demos/form/issue-regression-gallery.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import type { ProFormInstance } from '@ant-design/pro-components';
import {
BetaSchemaForm,
ModalForm,
ProCard,
ProForm,
ProFormList,
ProFormText,
} from '@ant-design/pro-components';
import { Alert, Button, Space, Tabs, Typography, message } from 'antd';
import { useRef, useState } from 'react';

const toList = (value: Record<string, string>) =>
Object.entries(value).map(([key, itemValue]) => ({
key,
value: itemValue,
}));

const ListConvertValue = () => {
const formRef = useRef<ProFormInstance>();
return (
<ProForm
formRef={formRef}
submitter={false}
initialValues={{ configs: { first: 'one', second: 'two' } }}
>
<Space style={{ marginBlockEnd: 16 }}>
<Button
onClick={() =>
formRef.current?.setFieldsValue({ configs: { third: 'three' } })
}
>
setFieldsValue 写入对象
</Button>
<Typography.Text type="secondary">
对象会在初始值及外部写入时转换为列表。
</Typography.Text>
</Space>
<ProFormList name="configs" convertValue={toList}>
<ProFormText name="key" label="Key" />
<ProFormText name="value" label="Value" />
</ProFormList>
</ProForm>
);
};

const RequestReuse = () => {
const [id, setId] = useState(0);
return (
<Space direction="vertical" style={{ width: '100%' }}>
<Space>
{[0, 1, 0].map((value, index) => (
<Button key={`${value}-${index}`} onClick={() => setId(value)}>
参数 {value}
</Button>
))}
</Space>
<ProForm
key="request-reuse-form"
params={{ id }}
request={async ({ id: requestId }) => ({
name: `服务端返回:参数 ${requestId}(${new Date().toLocaleTimeString()})`,
})}
submitter={false}
>
<ProFormText name="name" label="请求结果" width="lg" />
</ProForm>
</Space>
);
};

const OverlayInitialization = () => {
const [open, setOpen] = useState(false);
const [record, setRecord] = useState({ name: 'Alice' });
return (
<Space>
{['Alice', 'Bob'].map((name) => (
<Button
key={name}
onClick={() => {
setRecord({ name });
setOpen(true);
}}
>
编辑 {name}
</Button>
))}
<ModalForm
open={open}
onOpenChange={setOpen}
initialValues={record}
request={async () => record}
title="受控弹窗初始化"
onFinish={async ({ name }) => {
message.success(`已保存 ${name}`);
return true;
}}
>
<ProFormText name="name" label="姓名" />
</ModalForm>
</Space>
);
};

export default () => (
<ProCard direction="column" ghost gutter={[0, 16]}>
<Alert
type="info"
showIcon
message="表单初始化与转换回归场景"
description="覆盖弹层初始化、ProFormList convertValue、SchemaForm 独立宽度及重复参数请求。"
/>
<ProCard>
<Tabs
items={[
{
key: 'overlay',
label: '弹层初始化',
children: <OverlayInitialization />,
},
{
key: 'list',
label: '列表转换 #8702',
children: <ListConvertValue />,
},
{
key: 'schema',
label: 'SchemaForm 宽度 #9061',
children: (
<BetaSchemaForm
submitter={false}
columns={[
{
title: '表格列宽 80,表单宽度 328',
dataIndex: 'title',
width: 80,
formWidth: 328,
},
]}
/>
),
},
{
key: 'request',
label: '重复参数请求 #8375',
children: <RequestReuse />,
},
]}
/>
</ProCard>
</ProCard>
);
73 changes: 73 additions & 0 deletions demos/layout/issue-regression-gallery.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import {
CheckCard,
PageContainer,
ProCard,
ProConfigProvider,
ProLayout,
} from '@ant-design/pro-components';
import { Alert, ConfigProvider, Segmented, Space } from 'antd';
import { useState } from 'react';

const routes = [
{
path: '/dashboard',
name: 'Dashboard',
children: [
{ path: '/dashboard/analysis', name: 'Analysis' },
{ path: '/dashboard/monitor', name: 'Monitor' },
],
},
{ path: '/settings', name: 'Settings' },
];

export default () => {
const [navTheme, setNavTheme] = useState<'light' | 'realDark'>('light');

return (
<Space direction="vertical" size={16} style={{ width: '100%' }}>
<Alert
type="info"
showIcon
message="布局与主题 token 回归场景"
description="切换导航主题并悬停 Dashboard,检查深色菜单、弹层背景和 Card token。缩窄窗口可验证移动抽屉。"
/>
<Segmented
value={navTheme}
options={[
{ label: '浅色导航', value: 'light' },
{ label: '真实深色', value: 'realDark' },
]}
onChange={(value) => setNavTheme(value as 'light' | 'realDark')}
/>
<ConfigProvider theme={{ components: { Card: { headerFontSize: 22 } } }}>
<ProConfigProvider
token={{
colorPrimary: '#722ed1',
components: { Card: { headerBg: '#f9f0ff' } },
layout: {
header: { colorBgMenuElevated: '#141414' },
},
}}
>
<ProCard title="ProConfigProvider Card token">
<CheckCard title="CheckCard 继承主题" description="#8929 #9125" />
</ProCard>
<div style={{ height: 480, marginBlockStart: 16 }}>
<ProLayout
title="Regression Demo"
layout="top"
navTheme={navTheme}
route={{ routes }}
location={{ pathname: '/dashboard/analysis' }}
menu={{ request: async () => routes }}
>
<PageContainer title="首屏布局稳定">
移动端抽屉、菜单分组、SSR 与首屏 padding 由对应自动化测试覆盖。
</PageContainer>
</ProLayout>
</div>
</ProConfigProvider>
</ConfigProvider>
</Space>
);
};
65 changes: 65 additions & 0 deletions demos/list/issue-regression-gallery.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import type { ActionType, ProColumns } from '@ant-design/pro-components';
import { ProCard, ProList } from '@ant-design/pro-components';
import { Alert, Button, Space, Typography } from 'antd';
import { useRef, useState } from 'react';

type Item = { id: number; title: string; description: string };

const columns: ProColumns<Item>[] = [
{ dataIndex: 'title', title: '标题', listSlot: 'title' },
{ dataIndex: 'description', title: '说明', listSlot: 'description' },
{
title: '操作',
listSlot: 'actions',
render: () => [<a key="edit">编辑</a>],
},
];

export default () => {
const actionRef = useRef<ActionType>();
const [pageInfo, setPageInfo] = useState('等待请求完成');

return (
<ProCard direction="column" ghost gutter={[0, 16]}>
<Alert
type="info"
showIcon
message="ProList 展示与实时分页状态"
description="覆盖操作区 hover、grid itemRender gutter 及 actionRef.pageInfo。"
/>
<ProList<Item>
actionRef={actionRef}
rowKey="id"
columns={columns}
showActions="hover"
grid={{ column: 2, gutter: [16, 24] }}
pagination={{ pageSize: 2 }}
request={async () => ({
success: true,
total: 42,
data: [
{ id: 1, title: '项目 A', description: '悬停显示操作区' },
{ id: 2, title: '项目 B', description: '卡片间距保持一致' },
],
})}
itemRender={(item, index, defaultDom) => (
<ProCard title={`自定义 itemRender ${index + 1}`}>
{defaultDom}
</ProCard>
)}
toolBarRender={() => [
<Space key="page-info">
<Button
onClick={() =>
setPageInfo(JSON.stringify(actionRef.current?.pageInfo))
}
>
读取 pageInfo
</Button>
<Typography.Text code>{pageInfo}</Typography.Text>
</Space>,
]}
/>
</ProCard>
);
};
Loading
Loading