@ant-design/pro-components 3.1.1-0 → 3.1.1-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/pro-components.min.js +1 -1
- package/es/field/components/Cascader/index.d.ts +1 -1
- package/es/field/components/Cascader/index.js +8 -7
- package/es/field/components/Checkbox/index.d.ts +1 -1
- package/es/field/components/ColorPicker/index.d.ts +1 -1
- package/es/field/components/DatePicker/index.d.ts +1 -1
- package/es/field/components/Percent/util.d.ts +1 -1
- package/es/field/components/RangePicker/index.d.ts +1 -1
- package/es/field/components/Select/index.d.ts +1 -1
- package/es/field/components/TreeSelect/index.d.ts +1 -1
- package/es/form/components/Cascader/index.d.ts +1 -1
- package/es/form/components/ColorPicker/index.d.ts +1 -1
- package/es/form/components/Digit/DigitRange.d.ts +2 -2
- package/es/form/components/Digit/index.d.ts +1 -1
- package/es/form/components/Money/index.d.ts +1 -1
- package/es/form/components/Radio/index.d.ts +2 -2
- package/es/form/components/Rate/index.d.ts +1 -1
- package/es/form/components/Slider/index.d.ts +1 -1
- package/es/form/components/TextArea/index.d.ts +1 -1
- package/es/form/layouts/ProForm/index.d.ts +1 -1
- package/es/utils/useMediaQuery/index.d.ts +2 -2
- package/es/utils/useMediaQuery/index.js +21 -16
- package/guidelines/Guidelines.md +33 -0
- package/guidelines/components/drawer-form.md +90 -0
- package/guidelines/components/editable-pro-table.md +150 -0
- package/guidelines/components/modal-form.md +88 -0
- package/guidelines/components/pro-card.md +90 -0
- package/guidelines/components/pro-form.md +96 -0
- package/guidelines/components/pro-layout.md +84 -0
- package/guidelines/components/pro-table.md +142 -0
- package/guidelines/components/steps-form.md +105 -0
- package/guidelines/design-tokens/colors.md +58 -0
- package/guidelines/design-tokens/layout.md +53 -0
- package/guidelines/design-tokens/typography.md +49 -0
- package/guidelines/overview-components.md +55 -0
- package/guidelines/overview-icons.md +23 -0
- package/lib/field/components/Cascader/index.js +8 -7
- package/lib/utils/useMediaQuery/index.js +21 -16
- package/package.json +5 -5
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
### ModalForm
|
|
2
|
+
|
|
3
|
+
**Purpose**: A form wrapped in a Modal, used for creating or editing data in a dialog.
|
|
4
|
+
|
|
5
|
+
**When to use**:
|
|
6
|
+
|
|
7
|
+
- For "Create" or "Edit" actions that don't require a full page.
|
|
8
|
+
- When you need a quick interaction without leaving the current context.
|
|
9
|
+
- When the form content is relatively short.
|
|
10
|
+
|
|
11
|
+
**Semantic**:
|
|
12
|
+
|
|
13
|
+
- Combines `antd` Modal and `ProForm`.
|
|
14
|
+
- Automatically handles the `visible` (via `trigger`) and `loading` states.
|
|
15
|
+
|
|
16
|
+
**API Overview**:
|
|
17
|
+
|
|
18
|
+
- `trigger`: ReactNode. The element that opens the modal when clicked.
|
|
19
|
+
- `title`: Modal title.
|
|
20
|
+
- `width`: Modal width.
|
|
21
|
+
- `open`: Controlled visibility state (optional).
|
|
22
|
+
- `onOpenChange`: Callback when visibility changes.
|
|
23
|
+
- `onFinish`: Async function. The modal closes automatically if this returns `true`.
|
|
24
|
+
- `modalProps`: Props passed to the underlying `antd` Modal.
|
|
25
|
+
|
|
26
|
+
**Usage Pattern**:
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
import {
|
|
30
|
+
ModalForm,
|
|
31
|
+
ProFormText,
|
|
32
|
+
ProFormSelect,
|
|
33
|
+
} from '@ant-design/pro-components';
|
|
34
|
+
import { Button, message } from 'antd';
|
|
35
|
+
import { PlusOutlined } from '@ant-design/icons';
|
|
36
|
+
|
|
37
|
+
export default () => {
|
|
38
|
+
return (
|
|
39
|
+
<ModalForm<{
|
|
40
|
+
name: string;
|
|
41
|
+
company: string;
|
|
42
|
+
}>
|
|
43
|
+
title="Create New Entry"
|
|
44
|
+
trigger={
|
|
45
|
+
<Button type="primary">
|
|
46
|
+
<PlusOutlined />
|
|
47
|
+
New Entry
|
|
48
|
+
</Button>
|
|
49
|
+
}
|
|
50
|
+
autoFocusFirstInput
|
|
51
|
+
modalProps={{
|
|
52
|
+
destroyOnClose: true,
|
|
53
|
+
onCancel: () => console.log('run'),
|
|
54
|
+
}}
|
|
55
|
+
onFinish={async (values) => {
|
|
56
|
+
await waitTime(2000);
|
|
57
|
+
console.log(values.name);
|
|
58
|
+
message.success('Submitted successfully');
|
|
59
|
+
return true;
|
|
60
|
+
}}
|
|
61
|
+
>
|
|
62
|
+
<ProFormText
|
|
63
|
+
width="md"
|
|
64
|
+
name="name"
|
|
65
|
+
label="Name"
|
|
66
|
+
placeholder="Please enter name"
|
|
67
|
+
rules={[{ required: true, message: 'This is required' }]}
|
|
68
|
+
/>
|
|
69
|
+
<ProFormSelect
|
|
70
|
+
width="md"
|
|
71
|
+
name="type"
|
|
72
|
+
label="Type"
|
|
73
|
+
options={[
|
|
74
|
+
{ value: '1', label: 'Type 1' },
|
|
75
|
+
{ value: '2', label: 'Type 2' },
|
|
76
|
+
]}
|
|
77
|
+
/>
|
|
78
|
+
</ModalForm>
|
|
79
|
+
);
|
|
80
|
+
};
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Best Practices**:
|
|
84
|
+
|
|
85
|
+
- Always use `trigger` when possible to avoid managing `open` state manually.
|
|
86
|
+
- Return `true` in `onFinish` to close the modal. Return `false` or nothing to keep it open (e.g. if validation fails).
|
|
87
|
+
- Use `modalProps={{ destroyOnClose: true }}` to reset the form when closed.
|
|
88
|
+
- Keep the form simple. If the form is very long, consider using `DrawerForm` or `StepsForm`.
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
### ProCard
|
|
2
|
+
|
|
3
|
+
**Purpose**: An extended Card component that supports grid layout, splitting, and tabs.
|
|
4
|
+
|
|
5
|
+
**When to use**:
|
|
6
|
+
|
|
7
|
+
- To organize content into sections.
|
|
8
|
+
- To create dashboard layouts with multiple cards.
|
|
9
|
+
- When you need a card that can be split vertically or horizontally.
|
|
10
|
+
- When you need tabs inside a card.
|
|
11
|
+
|
|
12
|
+
**API Overview**:
|
|
13
|
+
|
|
14
|
+
- `title`: Card title.
|
|
15
|
+
- `extra`: Action area in top right.
|
|
16
|
+
- `split`: 'vertical' | 'horizontal'. Split the card into multiple sections.
|
|
17
|
+
- `colSpan`: Grid width (like `antd` Col).
|
|
18
|
+
- `gutter`: Spacing between grid items.
|
|
19
|
+
- `tabs`: Configure tabs inside the card.
|
|
20
|
+
- `collapsible`: Whether the card can be collapsed.
|
|
21
|
+
- `ghost`: Transparent background.
|
|
22
|
+
|
|
23
|
+
**Usage Pattern**:
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
import { ProCard } from '@ant-design/pro-components';
|
|
27
|
+
|
|
28
|
+
export default () => {
|
|
29
|
+
return (
|
|
30
|
+
<ProCard
|
|
31
|
+
title="Card Title"
|
|
32
|
+
extra="More"
|
|
33
|
+
split="vertical"
|
|
34
|
+
bordered
|
|
35
|
+
headerBordered
|
|
36
|
+
>
|
|
37
|
+
<ProCard title="Left Details" colSpan="50%">
|
|
38
|
+
Left Content
|
|
39
|
+
</ProCard>
|
|
40
|
+
<ProCard title="Right Details">
|
|
41
|
+
<div style={{ height: 360 }}>Right Content</div>
|
|
42
|
+
</ProCard>
|
|
43
|
+
</ProCard>
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**Grid Layout**:
|
|
49
|
+
|
|
50
|
+
```tsx
|
|
51
|
+
<ProCard gutter={16} ghost>
|
|
52
|
+
<ProCard colSpan={12} layout="center" bordered>
|
|
53
|
+
Col 12
|
|
54
|
+
</ProCard>
|
|
55
|
+
<ProCard colSpan={6} layout="center" bordered>
|
|
56
|
+
Col 6
|
|
57
|
+
</ProCard>
|
|
58
|
+
<ProCard colSpan={6} layout="center" bordered>
|
|
59
|
+
Col 6
|
|
60
|
+
</ProCard>
|
|
61
|
+
</ProCard>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Tabs**:
|
|
65
|
+
|
|
66
|
+
```tsx
|
|
67
|
+
<ProCard
|
|
68
|
+
tabs={{
|
|
69
|
+
type: 'card',
|
|
70
|
+
items: [
|
|
71
|
+
{
|
|
72
|
+
label: 'Tab 1',
|
|
73
|
+
key: 'tab1',
|
|
74
|
+
children: 'Content 1',
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
label: 'Tab 2',
|
|
78
|
+
key: 'tab2',
|
|
79
|
+
children: 'Content 2',
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
}}
|
|
83
|
+
/>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**Best Practices**:
|
|
87
|
+
|
|
88
|
+
- Use `ghost` mode when placing cards on a gray background (like in `ProLayout`).
|
|
89
|
+
- Use `split` to create master-detail views.
|
|
90
|
+
- Use `colSpan` for responsive layouts.
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
### ProForm
|
|
2
|
+
|
|
3
|
+
**Purpose**: High-performance form component with layout capabilities and preset fields.
|
|
4
|
+
|
|
5
|
+
**When to use**:
|
|
6
|
+
|
|
7
|
+
- For standard data entry forms on a page.
|
|
8
|
+
- When you need a simple, direct form without modal or drawer wrappers.
|
|
9
|
+
|
|
10
|
+
**Note**:
|
|
11
|
+
|
|
12
|
+
- For forms in a Modal, see [ModalForm](modal-form.md).
|
|
13
|
+
- For forms in a Drawer, see [DrawerForm](drawer-form.md).
|
|
14
|
+
- For multi-step forms, see [StepsForm](steps-form.md).
|
|
15
|
+
|
|
16
|
+
**API Overview**:
|
|
17
|
+
|
|
18
|
+
- `onFinish`: Triggered on form submission. `(values) => Promise<boolean | void>`
|
|
19
|
+
- `initialValues`: Initial values.
|
|
20
|
+
- `submitter`: Configure the submit/reset buttons.
|
|
21
|
+
- `layout`: Form layout ('horizontal', 'vertical', 'inline').
|
|
22
|
+
- `grid`: Enable grid layout for children.
|
|
23
|
+
|
|
24
|
+
**Field Components**:
|
|
25
|
+
|
|
26
|
+
- `ProFormText`
|
|
27
|
+
- `ProFormTextArea`
|
|
28
|
+
- `ProFormSelect`
|
|
29
|
+
- `ProFormDatePicker`
|
|
30
|
+
- `ProFormDateRangePicker`
|
|
31
|
+
- `ProFormDigit`
|
|
32
|
+
- `ProFormSwitch`
|
|
33
|
+
- `ProFormUploadButton`
|
|
34
|
+
- ...and many more.
|
|
35
|
+
|
|
36
|
+
**Usage Pattern**:
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
import {
|
|
40
|
+
ProForm,
|
|
41
|
+
ProFormText,
|
|
42
|
+
ProFormSelect,
|
|
43
|
+
ProFormDateRangePicker,
|
|
44
|
+
} from '@ant-design/pro-components';
|
|
45
|
+
import { message } from 'antd';
|
|
46
|
+
|
|
47
|
+
export default () => {
|
|
48
|
+
return (
|
|
49
|
+
<ProForm
|
|
50
|
+
onFinish={async (values) => {
|
|
51
|
+
console.log(values);
|
|
52
|
+
message.success('Submitted successfully');
|
|
53
|
+
}}
|
|
54
|
+
initialValues={{
|
|
55
|
+
name: 'Ant Design',
|
|
56
|
+
useMode: 'chapter',
|
|
57
|
+
}}
|
|
58
|
+
>
|
|
59
|
+
<ProForm.Group>
|
|
60
|
+
<ProFormText
|
|
61
|
+
width="md"
|
|
62
|
+
name="name"
|
|
63
|
+
label="Contract Name"
|
|
64
|
+
tooltip="The name of the contract"
|
|
65
|
+
placeholder="Please enter a name"
|
|
66
|
+
rules={[{ required: true, message: 'Please enter a name' }]}
|
|
67
|
+
/>
|
|
68
|
+
<ProFormText
|
|
69
|
+
width="md"
|
|
70
|
+
name="company"
|
|
71
|
+
label="Company"
|
|
72
|
+
placeholder="Please enter a company"
|
|
73
|
+
/>
|
|
74
|
+
</ProForm.Group>
|
|
75
|
+
<ProForm.Group>
|
|
76
|
+
<ProFormSelect
|
|
77
|
+
request={async () => [
|
|
78
|
+
{ label: 'Chapter', value: 'chapter' },
|
|
79
|
+
{ label: 'Section', value: 'section' },
|
|
80
|
+
]}
|
|
81
|
+
width="xs"
|
|
82
|
+
name="useMode"
|
|
83
|
+
label="Contract Mode"
|
|
84
|
+
/>
|
|
85
|
+
<ProFormDateRangePicker name="contractTime" label="Contract Time" />
|
|
86
|
+
</ProForm.Group>
|
|
87
|
+
</ProForm>
|
|
88
|
+
);
|
|
89
|
+
};
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**Best Practices**:
|
|
93
|
+
|
|
94
|
+
- Use `ProForm.Group` to group related fields.
|
|
95
|
+
- Use `width` prop to control field width (`xs`, `sm`, `md`, `lg`, `xl`) instead of raw pixels for consistency.
|
|
96
|
+
- Use `request` in `ProFormSelect` to load options asynchronously.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
### ProLayout
|
|
2
|
+
|
|
3
|
+
**Purpose**: A heavy-duty layout component that provides a complete application frame including Sidebar, Header, Content, and Footer.
|
|
4
|
+
|
|
5
|
+
**When to use**:
|
|
6
|
+
|
|
7
|
+
- As the root component of your admin application.
|
|
8
|
+
- When you need a responsive layout with collapsible sidebar.
|
|
9
|
+
- When you need automatic menu generation from routes.
|
|
10
|
+
|
|
11
|
+
**API Overview**:
|
|
12
|
+
|
|
13
|
+
- `layout`: 'side' | 'top' | 'mix'.
|
|
14
|
+
- `route`: Route configuration object.
|
|
15
|
+
- `location`: Current location (usually from router).
|
|
16
|
+
- `menuItemRender`: Custom render for menu items.
|
|
17
|
+
- `headerContentRender`: Custom content in the header.
|
|
18
|
+
- `rightContentRender`: Custom content in the top right (user profile, settings).
|
|
19
|
+
- `footerRender`: Custom footer.
|
|
20
|
+
- `token`: Design tokens for customization.
|
|
21
|
+
|
|
22
|
+
**Usage Pattern**:
|
|
23
|
+
|
|
24
|
+
```tsx
|
|
25
|
+
import { ProLayout } from '@ant-design/pro-components';
|
|
26
|
+
import { Button } from 'antd';
|
|
27
|
+
|
|
28
|
+
export default (props) => {
|
|
29
|
+
return (
|
|
30
|
+
<ProLayout
|
|
31
|
+
title="My Application"
|
|
32
|
+
logo="https://gw.alipayobjects.com/zos/antfincdn/upvrAjAPQX/Logo_Tech%252520UI.svg"
|
|
33
|
+
layout="mix"
|
|
34
|
+
splitMenus={false}
|
|
35
|
+
route={{
|
|
36
|
+
routes: [
|
|
37
|
+
{
|
|
38
|
+
path: '/welcome',
|
|
39
|
+
name: 'Welcome',
|
|
40
|
+
icon: 'smile',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
path: '/admin',
|
|
44
|
+
name: 'Admin',
|
|
45
|
+
icon: 'crown',
|
|
46
|
+
routes: [
|
|
47
|
+
{
|
|
48
|
+
path: '/admin/sub-page',
|
|
49
|
+
name: 'Sub Page',
|
|
50
|
+
icon: 'smile',
|
|
51
|
+
component: './Welcome',
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
}}
|
|
57
|
+
location={{
|
|
58
|
+
pathname: '/welcome',
|
|
59
|
+
}}
|
|
60
|
+
avatarProps={{
|
|
61
|
+
src: 'https://gw.alipayobjects.com/zos/antfincdn/efFD%24IOql2/weixintupian_20170331104822.jpg',
|
|
62
|
+
title: 'User Name',
|
|
63
|
+
size: 'small',
|
|
64
|
+
}}
|
|
65
|
+
actionsRender={(props) => {
|
|
66
|
+
if (props.isMobile) return [];
|
|
67
|
+
return [
|
|
68
|
+
<Button key="key" type="text">
|
|
69
|
+
Action
|
|
70
|
+
</Button>,
|
|
71
|
+
];
|
|
72
|
+
}}
|
|
73
|
+
>
|
|
74
|
+
{props.children}
|
|
75
|
+
</ProLayout>
|
|
76
|
+
);
|
|
77
|
+
};
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Common Mistakes**:
|
|
81
|
+
|
|
82
|
+
- Not passing `location` causing the menu highlight to fail.
|
|
83
|
+
- Forgetting to handle `menuItemRender` when using a router (like `react-router-dom`) to use `Link` instead of `a` tags.
|
|
84
|
+
- Using `mix` layout without setting `splitMenus` correctly for the desired behavior.
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
### ProTable
|
|
2
|
+
|
|
3
|
+
**Purpose**: Advanced table component that solves common table issues like search, filter, sort, and pagination.
|
|
4
|
+
|
|
5
|
+
**When to use**:
|
|
6
|
+
|
|
7
|
+
- For admin interfaces displaying lists of data.
|
|
8
|
+
- When you need built-in search/filter forms.
|
|
9
|
+
- When you need to handle server-side sorting and pagination easily.
|
|
10
|
+
|
|
11
|
+
**Note**: If you need an editable table, please refer to [EditableProTable](editable-pro-table.md).
|
|
12
|
+
|
|
13
|
+
**Semantic**:
|
|
14
|
+
|
|
15
|
+
- Uses `antd` Table under the hood but adds a search form above and toolbars.
|
|
16
|
+
- `dataSource` can be fetched automatically via `request` prop.
|
|
17
|
+
|
|
18
|
+
**API Overview**:
|
|
19
|
+
|
|
20
|
+
- `columns`: Array of `ProColumns`. Defines table columns and search form fields.
|
|
21
|
+
- `request`: Function to fetch data. `(params, sort, filter) => Promise<{ data, success, total }>`
|
|
22
|
+
- `rowKey`: Unique key for each row (required).
|
|
23
|
+
- `headerTitle`: Title of the table.
|
|
24
|
+
- `toolBarRender`: Render custom actions in the toolbar.
|
|
25
|
+
- `actionRef`: Ref to trigger table actions like `reload()`.
|
|
26
|
+
|
|
27
|
+
**ProColumns Configuration**:
|
|
28
|
+
|
|
29
|
+
- `dataIndex`: Key in the data object.
|
|
30
|
+
- `title`: Column header title.
|
|
31
|
+
- `valueType`: Type of the data (e.g. `date`, `money`, `select`).
|
|
32
|
+
- `hideInSearch`: Hide this field in the search form.
|
|
33
|
+
- `hideInTable`: Hide this column in the table.
|
|
34
|
+
- `search`: Configure search behavior (transform, etc.).
|
|
35
|
+
- `render`: Custom render function.
|
|
36
|
+
- `valueEnum`: Map of values for `select` type.
|
|
37
|
+
|
|
38
|
+
**Usage Pattern**:
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
import { ProTable } from '@ant-design/pro-components';
|
|
42
|
+
import { useRef } from 'react';
|
|
43
|
+
|
|
44
|
+
// Define the data type
|
|
45
|
+
type GithubIssueItem = {
|
|
46
|
+
id: number;
|
|
47
|
+
number: number;
|
|
48
|
+
title: string;
|
|
49
|
+
state: string;
|
|
50
|
+
created_at: string;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export default () => {
|
|
54
|
+
const actionRef = useRef();
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<ProTable<GithubIssueItem>
|
|
58
|
+
columns={[
|
|
59
|
+
{
|
|
60
|
+
title: 'Title',
|
|
61
|
+
dataIndex: 'title',
|
|
62
|
+
copyable: true,
|
|
63
|
+
ellipsis: true,
|
|
64
|
+
tip: 'Title is too long',
|
|
65
|
+
formItemProps: {
|
|
66
|
+
rules: [
|
|
67
|
+
{
|
|
68
|
+
required: true,
|
|
69
|
+
message: 'This is required',
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
title: 'State',
|
|
76
|
+
dataIndex: 'state',
|
|
77
|
+
valueType: 'select',
|
|
78
|
+
valueEnum: {
|
|
79
|
+
open: { text: 'Open', status: 'Error' },
|
|
80
|
+
closed: { text: 'Closed', status: 'Success' },
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
title: 'Created At',
|
|
85
|
+
dataIndex: 'created_at',
|
|
86
|
+
valueType: 'date',
|
|
87
|
+
sorter: true,
|
|
88
|
+
hideInSearch: true,
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
title: 'Option',
|
|
92
|
+
valueType: 'option',
|
|
93
|
+
render: (text, record, _, action) => [
|
|
94
|
+
<a
|
|
95
|
+
key="view"
|
|
96
|
+
onClick={() => {
|
|
97
|
+
// View action
|
|
98
|
+
}}
|
|
99
|
+
>
|
|
100
|
+
View
|
|
101
|
+
</a>,
|
|
102
|
+
],
|
|
103
|
+
},
|
|
104
|
+
]}
|
|
105
|
+
actionRef={actionRef}
|
|
106
|
+
cardBordered
|
|
107
|
+
request={async (params = {}, sort, filter) => {
|
|
108
|
+
// Mock request
|
|
109
|
+
return {
|
|
110
|
+
data: [],
|
|
111
|
+
success: true,
|
|
112
|
+
total: 0,
|
|
113
|
+
};
|
|
114
|
+
}}
|
|
115
|
+
columnsState={{
|
|
116
|
+
persistenceKey: 'pro-table-singe-demos',
|
|
117
|
+
persistenceType: 'localStorage',
|
|
118
|
+
defaultValue: {
|
|
119
|
+
option: { fixed: 'right', disable: true },
|
|
120
|
+
},
|
|
121
|
+
}}
|
|
122
|
+
rowKey="id"
|
|
123
|
+
search={{
|
|
124
|
+
labelWidth: 'auto',
|
|
125
|
+
}}
|
|
126
|
+
pagination={{
|
|
127
|
+
pageSize: 5,
|
|
128
|
+
onChange: (page) => console.log(page),
|
|
129
|
+
}}
|
|
130
|
+
dateFormatter="string"
|
|
131
|
+
headerTitle="Advanced Table"
|
|
132
|
+
/>
|
|
133
|
+
);
|
|
134
|
+
};
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Common Mistakes**:
|
|
138
|
+
|
|
139
|
+
- Forgetting `rowKey`.
|
|
140
|
+
- Manually managing `dataSource` and `loading` when `request` is better.
|
|
141
|
+
- Not using `valueType` and writing custom `render` for everything.
|
|
142
|
+
- Modifying `params` directly in `request` without returning the correct structure.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
### StepsForm
|
|
2
|
+
|
|
3
|
+
**Purpose**: A multi-step form wizard.
|
|
4
|
+
|
|
5
|
+
**When to use**:
|
|
6
|
+
|
|
7
|
+
- For very long or complex processes that need to be broken down into chunks.
|
|
8
|
+
- When there is a logical sequence of data entry (e.g. Account Info -> Profile Info -> Confirmation).
|
|
9
|
+
|
|
10
|
+
**Semantic**:
|
|
11
|
+
|
|
12
|
+
- Manages the state between steps.
|
|
13
|
+
- Validates each step before proceeding to the next.
|
|
14
|
+
|
|
15
|
+
**API Overview**:
|
|
16
|
+
|
|
17
|
+
- `StepsForm`: The container component.
|
|
18
|
+
- `onFinish`: Triggered after the LAST step is submitted.
|
|
19
|
+
- `stepsProps`: Props for the Steps component (e.g. `current`).
|
|
20
|
+
- `StepsForm.StepForm`: Individual step component.
|
|
21
|
+
- `title`: Step title.
|
|
22
|
+
- `onFinish`: Triggered when THIS step is completed. Return `true` to proceed.
|
|
23
|
+
|
|
24
|
+
**Usage Pattern**:
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
import { StepsForm, ProFormText, ProFormDatePicker } from '@ant-design/pro-components';
|
|
28
|
+
import { Button, message, Modal } from 'antd';
|
|
29
|
+
|
|
30
|
+
export default () => {
|
|
31
|
+
return (
|
|
32
|
+
<StepsForm
|
|
33
|
+
onFinish={async (values) => {
|
|
34
|
+
console.log(values);
|
|
35
|
+
await waitTime(1000);
|
|
36
|
+
message.success('Submission successful');
|
|
37
|
+
}}
|
|
38
|
+
formProps={{
|
|
39
|
+
validateMessages: {
|
|
40
|
+
required: 'This is required',
|
|
41
|
+
},
|
|
42
|
+
}}
|
|
43
|
+
submitter={{
|
|
44
|
+
render: (props) => {
|
|
45
|
+
if (props.step === 0) {
|
|
46
|
+
return (
|
|
47
|
+
<Button type="primary" onClick={() => props.onSubmit?.()}>
|
|
48
|
+
Next >
|
|
49
|
+
</Button>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
if (props.step === 1) {
|
|
53
|
+
return [
|
|
54
|
+
<Button key="pre" onClick={() => props.onPre?.()}>
|
|
55
|
+
< Previous
|
|
56
|
+
</Button>,
|
|
57
|
+
<Button key="goToTree" type="primary" onClick={() => props.onSubmit?.()}>
|
|
58
|
+
Submit
|
|
59
|
+
</Button>,
|
|
60
|
+
];
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
},
|
|
64
|
+
}}
|
|
65
|
+
>
|
|
66
|
+
<StepsForm.StepForm
|
|
67
|
+
name="base"
|
|
68
|
+
title="Basic Info"
|
|
69
|
+
stepProps={{
|
|
70
|
+
description: 'Enter basic details',
|
|
71
|
+
}}
|
|
72
|
+
onFinish={async () => {
|
|
73
|
+
console.log('Step 1 finished');
|
|
74
|
+
await waitTime(1000);
|
|
75
|
+
return true;
|
|
76
|
+
}}
|
|
77
|
+
>
|
|
78
|
+
<ProFormText
|
|
79
|
+
name="name"
|
|
80
|
+
label="Name"
|
|
81
|
+
width="md"
|
|
82
|
+
placeholder="Please enter name"
|
|
83
|
+
rules={[{ required: true }]}
|
|
84
|
+
/>
|
|
85
|
+
<ProFormDatePicker name="date" label="Date" />
|
|
86
|
+
</StepsForm.StepForm>
|
|
87
|
+
<StepsForm.StepForm
|
|
88
|
+
name="checkbox"
|
|
89
|
+
title="Configuration"
|
|
90
|
+
stepProps={{
|
|
91
|
+
description: 'Enter configuration',
|
|
92
|
+
}}
|
|
93
|
+
>
|
|
94
|
+
<ProFormText name="config" label="Config" width="md" />
|
|
95
|
+
</StepsForm.StepForm>
|
|
96
|
+
</StepsForm>
|
|
97
|
+
);
|
|
98
|
+
};
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Best Practices**:
|
|
102
|
+
|
|
103
|
+
- Break down complex forms into 3-5 logical steps.
|
|
104
|
+
- Use `onFinish` in `StepForm` to validate or save intermediate data.
|
|
105
|
+
- Ensure the final `onFinish` handles the aggregation of all data.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Color Design Tokens
|
|
2
|
+
|
|
3
|
+
ProComponents inherits the Design Token system from Ant Design v5.
|
|
4
|
+
|
|
5
|
+
## Token Categories
|
|
6
|
+
|
|
7
|
+
### Brand Color (`colorPrimary`)
|
|
8
|
+
|
|
9
|
+
The primary color of the application.
|
|
10
|
+
|
|
11
|
+
- `colorPrimary`: Main brand color.
|
|
12
|
+
- `colorPrimaryBg`: Background color for light brand elements.
|
|
13
|
+
- `colorPrimaryText`: Text color for brand elements.
|
|
14
|
+
|
|
15
|
+
### Functional Colors
|
|
16
|
+
|
|
17
|
+
- `colorSuccess`: Success state (Green).
|
|
18
|
+
- `colorWarning`: Warning state (Gold).
|
|
19
|
+
- `colorError`: Error state (Red).
|
|
20
|
+
- `colorInfo`: Info state (Blue).
|
|
21
|
+
|
|
22
|
+
### Neutral Colors
|
|
23
|
+
|
|
24
|
+
- `colorText`: Default text color.
|
|
25
|
+
- `colorTextSecondary`: Secondary text color.
|
|
26
|
+
- `colorTextTertiary`: Tertiary text color.
|
|
27
|
+
- `colorBgContainer`: Container background color (usually white).
|
|
28
|
+
- `colorBgLayout`: Layout background color (usually light gray).
|
|
29
|
+
- `colorBorder`: Default border color.
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
|
|
33
|
+
You can access these tokens using `useToken` hook from `antd`.
|
|
34
|
+
|
|
35
|
+
```tsx
|
|
36
|
+
import { theme } from 'antd';
|
|
37
|
+
|
|
38
|
+
const { useToken } = theme;
|
|
39
|
+
|
|
40
|
+
const MyComponent = () => {
|
|
41
|
+
const { token } = useToken();
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<div
|
|
45
|
+
style={{
|
|
46
|
+
backgroundColor: token.colorPrimary,
|
|
47
|
+
color: token.colorTextLightSolid,
|
|
48
|
+
}}
|
|
49
|
+
>
|
|
50
|
+
Brand Content
|
|
51
|
+
</div>
|
|
52
|
+
);
|
|
53
|
+
};
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## ProComponents Specifics
|
|
57
|
+
|
|
58
|
+
ProComponents may use additional tokens for specific layouts, which are documented in [layout.md](layout.md).
|