#Form Playground
#Form 的 layout 切换
ProForm 的主要功能是预设了很多 layout,如果需要切换只需要改变外面包裹的 Layout 即可,以下是个 demo。
import {
AlipayCircleOutlined,
LockOutlined,
PlusOutlined,
TaobaoCircleOutlined,
UserOutlined,
WeiboCircleOutlined,
} from '@ant-design/icons';
import {
DrawerForm,
LightFilter,
LoginForm,
ModalForm,
ProForm,
ProFormDateRangePicker,
ProFormDigit,
ProFormRadio,
ProFormSelect,
ProFormText,
QueryFilter,
StepsForm,
} from '@ant-design/pro-components';
import { Button, Space, message } from 'antd';
import { useState } from 'react';
const iconStyles = {
marginInlineStart: '16px',
color: 'rgba(0, 0, 0, 0.2)',
fontSize: '24px',
verticalAlign: 'middle',
cursor: 'pointer',
};
const waitTime = (time: number = 100) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(true);
}, time);
});
};
const Demo = () => {
const Components = {
ProForm,
ModalForm,
DrawerForm,
QueryFilter,
LightFilter,
StepsForm,
LoginForm,
};
const [type, setType] = useState<keyof typeof Components>('ProForm');
if (type === 'StepsForm') {
return (
<>
<ProFormRadio.Group
style={{
margin: 16,
}}
radioType="button"
fieldProps={{
value: type,
onChange: (e) => setType(e.target.value),
}}
options={[
'LightFilter',
'ProForm',
'ModalForm',
'DrawerForm',
'QueryFilter',
'StepsForm',
'LoginForm',
]}
/>
<StepsForm
onFinish={async () => {
await waitTime(2000);
message.success('Submission successful');
}}
>
<StepsForm.StepForm title="Step One">
<ProForm.Group>
<ProFormText
width="md"
name="name"
label="Contract Customer Name"
tooltip="Up to 24 characters"
placeholder="Please enter a name"
/>
<ProFormText
width="md"
name="company"
label="Our Company Name"
placeholder="Please enter a name"
/>
</ProForm.Group>
<ProForm.Group>
<ProFormText
name={['contract', 'name']}
width="md"
label="Contract Name"
placeholder="Please enter a name"
/>
<ProFormDateRangePicker
width="md"
name={['contract', 'createTime']}
label="Contract Effective Time"
/>
</ProForm.Group>
</StepsForm.StepForm>
<StepsForm.StepForm title="Step Two">
<ProForm.Group>
<ProFormSelect
options={[
{
value: 'chapter',
label: 'Effective after stamping',
},
]}
readonly
width="xs"
name="useMode"
label="Contract Agreed Effective Method"
/>
<ProFormSelect
width="xs"
options={[
{
value: 'time',
label: 'Terminate after performance',
},
]}
name="unusedMode"
label="Contract Agreed Invalid Method"
/>
</ProForm.Group>
</StepsForm.StepForm>
<StepsForm.StepForm title="Step Three">
<ProFormText width="sm" name="id" label="Main Contract Number" />
<ProFormText
name="project"
width="md"
disabled
label="Project Name"
initialValue="示例项目"
/>
<ProFormText
width="xs"
name="mangerName"
disabled
label="Business Manager"
initialValue="书琰"
/>
</StepsForm.StepForm>
</StepsForm>
</>
);
}
const FormComponents = Components[type as 'LoginForm'];
if (type === 'LoginForm') {
return (
<>
<ProFormRadio.Group
style={{
margin: 16,
}}
radioType="button"
fieldProps={{
value: type,
onChange: (e) => setType(e.target.value),
}}
options={[
'LightFilter',
'ProForm',
'ModalForm',
'DrawerForm',
'QueryFilter',
'StepsForm',
'LoginForm',
]}
/>
<FormComponents
title="Github"
subTitle="The world's largest code hosting platform"
actions={
<Space>
Other login methods
<AlipayCircleOutlined style={iconStyles} />
<TaobaoCircleOutlined style={iconStyles} />
<WeiboCircleOutlined style={iconStyles} />
</Space>
}
>
<ProFormText
name="username"
fieldProps={{
size: 'large',
prefix: <UserOutlined className={'prefixIcon'} />,
}}
placeholder={'Username: admin or user'}
rules={[
{
required: true,
message: 'Please enter your username!',
},
]}
/>
<ProFormText.Password
name="password"
fieldProps={{
size: 'large',
prefix: <LockOutlined className={'prefixIcon'} />,
}}
placeholder={'Password: ant.design'}
rules={[
{
required: true,
message: 'Please enter your password!',
},
]}
/>
</FormComponents>
</>
);
}
return (
<>
<ProFormRadio.Group
style={{
margin: 16,
}}
radioType="button"
fieldProps={{
value: type,
onChange: (e) => setType(e.target.value),
}}
options={[
'LightFilter',
'ProForm',
'ModalForm',
'DrawerForm',
'QueryFilter',
'StepsForm',
'LoginForm',
]}
/>
<div
style={{
margin: 24,
}}
>
<FormComponents
// @ts-ignore
labelWidth="auto"
trigger={
<Button type="primary">
<PlusOutlined />
New Form
</Button>
}
onFinish={async () => {
await waitTime(500);
message.success('Submission successful');
}}
initialValues={{
name: 'Ant Design Co., Ltd.',
useMode: 'chapter',
}}
>
<ProForm.Group>
<ProFormText
width="md"
name="name"
label="Contract Customer Name"
tooltip="Up to 24 characters"
placeholder="Please enter a name"
/>
<ProFormText
width="md"
name="company"
label="Our Company Name"
placeholder="Please enter a name"
/>
</ProForm.Group>
<ProForm.Group>
<ProFormText
name={['contract', 'name']}
width="md"
label="Contract Name"
placeholder="Please enter a name"
/>
<ProFormDateRangePicker
width="md"
name={['contract', 'createTime']}
label="Contract Effective Time"
/>
</ProForm.Group>
<ProForm.Group>
<ProFormSelect
options={[
{
value: 'chapter',
label: 'Effective after stamping',
},
]}
readonly
width="xs"
name="useMode"
label="Contract Agreed Effective Method"
/>
<ProFormSelect
width="xs"
options={[
{
value: 'time',
label: 'Terminate after performance',
},
]}
name="unusedMode"
label="Contract Agreed Invalid Method"
/>
</ProForm.Group>
<ProFormText width="sm" name="id" label="Main Contract Number" />
<ProFormText
name="project"
width="md"
disabled
label="Project Name"
initialValue="示例项目"
/>
<ProFormText
width="xs"
name="mangerName"
disabled
label="Business Manager"
initialValue="书琰"
/>
<ProFormDigit
name="percent"
label="Percent"
width="xs"
min={1}
max={10}
fieldProps={{
precision: 2,
addonAfter: '%',
}}
/>
</FormComponents>
</div>
</>
);
};
export default () => (
<div style={{ padding: 24 }}>
<Demo />
</div>
);
#FormList
ProForm.List
import {
CopyOutlined,
DeleteOutlined,
HeartOutlined,
HomeOutlined,
PlusOutlined,
SettingFilled,
SmileOutlined,
SyncOutlined,
} from '@ant-design/icons';
import {
ProCard,
ProForm,
ProFormDependency,
ProFormField,
ProFormList,
ProFormSelect,
ProFormSwitch,
ProFormText,
} from '@ant-design/pro-components';
import { useState } from 'react';
const IconMap = {
PlusOutlined,
HeartOutlined,
DeleteOutlined,
CopyOutlined,
HomeOutlined,
SettingFilled,
SmileOutlined,
SyncOutlined,
};
const initialValue = {
copyIconProps: {
show: true,
Icon: 'CopyOutlined',
tooltipText: '复制此项',
},
deleteIconProps: {
show: true,
Icon: 'DeleteOutlined',
tooltipText: '删除此项',
},
creatorButtonProps: {
show: true,
creatorButtonText: '新建一行',
position: 'button',
type: 'dashed',
icon: 'PlusOutlined',
},
};
const Demo = () => {
const [stateValue, setStateValue] = useState({});
const [json, setJson] = useState(() => JSON.stringify(initialValue));
return (
<ProCard variant="outlined" split="vertical" headerBordered>
<ProCard colSpan="calc(100% - 400px)">
<ProForm name="group-customize-demo-1">
<ProFormList
name="users"
label="用户信息"
initialValue={[
{
name: '1111',
},
]}
creatorButtonProps={{
position: 'bottom',
}}
{...stateValue}
>
<ProForm.Group key="group" size={8}>
<ProFormText name="name" label="姓名" />
<ProFormText name="nickName" label="姓名" />
</ProForm.Group>
</ProFormList>
</ProForm>
</ProCard>
<ProCard colSpan="400px" title="配置菜单">
<ProForm
name="group-customize-demo-2"
submitter={false}
initialValues={initialValue}
onValuesChange={(_, values) => {
if (values?.creatorButtonProps?.show === false) {
values.creatorButtonProps = false;
}
if (values?.copyIconProps?.show === false) {
values.copyIconProps = false;
}
if (values?.deleteIconProps?.show === false) {
values.deleteIconProps = false;
}
delete values.creatorButtonProps.show;
delete values.deleteIconProps.show;
delete values.creatorButtonProps.show;
setJson(JSON.stringify(values));
if (values?.copyIconProps?.Icon) {
values.copyIconProps.Icon =
IconMap[values?.copyIconProps?.Icon as 'PlusOutlined'];
}
if (values?.deleteIconProps?.Icon) {
values.deleteIconProps.Icon =
IconMap[values?.deleteIconProps?.Icon as 'PlusOutlined'];
}
if (values?.creatorButtonProps?.icon) {
const Icon =
IconMap[values?.creatorButtonProps?.icon as 'PlusOutlined'];
values.creatorButtonProps.icon = <Icon />;
}
setStateValue(values);
}}
>
<ProForm.Group
title="新建按钮配置"
extra={
<ProFormSwitch
fieldProps={{
size: 'small',
}}
noStyle
name={['creatorButtonProps', 'show']}
/>
}
>
<ProFormDependency name={['creatorButtonProps']}>
{({ creatorButtonProps }) => {
if (!creatorButtonProps.show) {
return null;
}
return (
<ProForm.Group size={8}>
<ProFormText
width="sm"
name={['creatorButtonProps', 'creatorButtonText']}
label="按钮文字"
/>
<ProFormSelect
width="xs"
name={['creatorButtonProps', 'icon']}
label="图标"
request={async () => {
return Object.keys(IconMap).map((value) => {
const Icon = IconMap[value as 'PlusOutlined'];
return {
label: <Icon />,
value,
};
});
}}
/>
<ProFormSelect
width="xs"
name={['creatorButtonProps', 'position']}
label="按钮位置"
request={async () => {
return ['bottom', 'top'].map((value) => {
return {
label: value,
value,
};
});
}}
/>
<ProFormSelect
width="xs"
name={['creatorButtonProps', 'type']}
label="按钮类型"
request={async () => {
return [
'default',
'primary',
'ghost',
'dashed',
'link',
'text',
].map((value) => {
return {
label: value,
value,
};
});
}}
/>
</ProForm.Group>
);
}}
</ProFormDependency>
</ProForm.Group>
<ProForm.Group
title="复制按钮配置"
extra={
<ProFormSwitch
fieldProps={{
size: 'small',
}}
noStyle
name={['copyIconProps', 'show']}
/>
}
>
<ProFormDependency name={['copyIconProps']}>
{({ copyIconProps }) => {
if (!copyIconProps.show) {
return null;
}
return (
<ProForm.Group size={8}>
<ProFormText
width="sm"
name={['copyIconProps', 'tooltipText']}
label=" tooltip 提示文字"
/>
<ProFormSelect
width="xs"
name={['copyIconProps', 'Icon']}
label="图标"
request={async () => {
return Object.keys(IconMap).map((value) => {
const Icon = IconMap[value as 'PlusOutlined'];
return {
label: <Icon />,
value,
};
});
}}
/>
</ProForm.Group>
);
}}
</ProFormDependency>
</ProForm.Group>
<ProForm.Group
title="删除按钮配置"
extra={
<ProFormSwitch
fieldProps={{
size: 'small',
}}
noStyle
name={['deleteIconProps', 'show']}
/>
}
>
<ProFormDependency name={['deleteIconProps']}>
{({ deleteIconProps }) => {
if (!deleteIconProps.show) {
return null;
}
return (
<ProForm.Group size={8}>
<ProFormText
width="sm"
name={['deleteIconProps', 'tooltipText']}
label=" tooltip 提示文字"
/>
<ProFormSelect
width="xs"
name={['deleteIconProps', 'Icon']}
label="图标"
request={async () => {
return Object.keys(IconMap).map((value) => {
const Icon = IconMap[value as 'PlusOutlined'];
return {
label: <Icon />,
value,
};
});
}}
/>
</ProForm.Group>
);
}}
</ProFormDependency>
</ProForm.Group>
<ProFormField
ignoreFormItem
valueType="jsonCode"
text={json}
mode="read"
/>
</ProForm>
</ProCard>
</ProCard>
);
};
export default () => (
<div style={{ padding: 24 }}>
<Demo />
</div>
);