Skip to content

Commit

Permalink
fix(form): fix ModalForm ref less error
Browse files Browse the repository at this point in the history
close #7004
  • Loading branch information
chenshuai2144 committed May 5, 2023
1 parent b540053 commit 06721c3
Show file tree
Hide file tree
Showing 7 changed files with 484 additions and 70 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import type { ProFormColumnsType, ProFormLayoutType } from '@ant-design/pro-components';
import { BetaSchemaForm, ProFormSelect } from '@ant-design/pro-components';
import { Alert, Button, DatePicker, Space } from 'antd';
import dayjs from 'dayjs';
import { useState } from 'react';

const valueEnum = {
all: { text: '全部', status: 'Default' },
open: {
text: '未解决',
status: 'Error',
},
closed: {
text: '已解决',
status: 'Success',
disabled: true,
},
processing: {
text: '解决中',
status: 'Processing',
},
};

type DataItem = {
name: string;
state: string;
};

export default () => {
const [layoutType, setLayoutType] = useState<ProFormLayoutType>('ModalForm');
return (
<>
<Space
style={{
width: '100%',
}}
direction="vertical"
>
<Alert
type="warning"
message="QueryFilter 和 lightFilter 暂不支持grid模式"
style={{
marginBlockEnd: 24,
}}
/>
<ProFormSelect
label="布局方式"
options={['ModalForm', 'DrawerForm']}
fieldProps={{
value: layoutType,
onChange: (e) => setLayoutType(e),
}}
/>
</Space>
<BetaSchemaForm<DataItem>
trigger={<Button>点击我</Button>}
layoutType={layoutType as 'ModalForm'}
onFinish={async (values) => {
console.log(values);
}}
{...(layoutType === 'ModalForm'
? {
modalProps: { destroyOnClose: true },
}
: {
drawerProps: { destroyOnClose: true },
})}
columns={[
{
title: '标题',
dataIndex: 'title',
formItemProps: {
rules: [
{
required: true,
message: '此项为必填项',
},
],
},
width: 'md',
},
]}
/>
</>
);
};
26 changes: 7 additions & 19 deletions packages/form/src/components/SchemaForm/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,32 +65,20 @@ SchemaForm 表单最重要就是 Schema 的类型定义,我们使用了与 tab

## 代码示例

### JSON 来生成表单

<code src="./demos/schema.tsx" title="schema 表单"></code>

### JSON 来生成分步表单

<code src="./demos/steps-form.tsx" title="schema 表单"></code>

### 嵌入到 ProForm 中
<code src="./demos/ModalAndDrawerForm.tsx" title="浮层窗口"></code>

<code src="./demos/embed.tsx" title="schema 表单"></code>
<code src="./demos/steps-form.tsx" title="JSON 来生成分步表单"></code>

### 使用 ProFormDependency
<code src="./demos/embed.tsx" title="嵌入到 ProForm 中"></code>

<code src="./demos/dependency.tsx" title="schema 表单"></code>
<code src="./demos/dependency.tsx" title="使用 ProFormDependency"></code>

## 高性能代码示例

### 结合 shouldUpdate=false 和 dependencies 触发更新

<code src="./demos/dependencies.tsx" title="schema dependencies"></code>

### 动态控制是否重渲染

<code src="./demos/dynamic-rerender.tsx" title="dynamic rerender"></code>
<code src="./demos/dependencies.tsx" title="结合 shouldUpdate=false 和 dependencies 触发更新"></code>

### form-list-required
<code src="./demos/dynamic-rerender.tsx" title="动态控制是否重渲染"></code>

<code src="./demos/form-list-required.tsx" title="required" debug></code>
<code src="./demos/form-list-required.tsx" title="required" debug title="form-list-required"></code>
1 change: 0 additions & 1 deletion packages/form/src/components/SchemaForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,6 @@ function BetaSchemaForm<T, ValueType = 'text'>(props: FormSchema<T, ValueType>)
if (!formRef.current) return;
// like StepsForm's columns but not only for StepsForm
if (columns.length && Array.isArray(columns[0])) return;

return genItems(columns as ProFormColumnsType<T, ValueType>[]);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [columns, genItems, formDomsDeps]);
Expand Down
17 changes: 15 additions & 2 deletions packages/form/src/layouts/ModalForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@ import { ConfigProvider, Modal } from 'antd';
import merge from 'lodash.merge';
import useMergedState from 'rc-util/lib/hooks/useMergedState';
import { noteOnce } from 'rc-util/lib/warning';
import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
import React, {
useCallback,
useContext,
useEffect,
useImperativeHandle,
useMemo,
useRef,
useState,
} from 'react';
import { createPortal } from 'react-dom';
import type { CommonFormProps, ProFormInstance } from '../../BaseForm';
import { BaseForm } from '../../BaseForm';
Expand Down Expand Up @@ -107,6 +115,11 @@ function ModalForm<T = Record<string, any>>({
}
}, [modalProps?.destroyOnClose, rest.form, rest.formRef]);

if (rest.formRef) {
(rest.formRef as React.MutableRefObject<ProFormInstance<T> | undefined>).current =
formRef.current;
}

useEffect(() => {
if (open && (propsOpen || propVisible)) {
onOpenChange?.(true);
Expand Down Expand Up @@ -237,8 +250,8 @@ function ModalForm<T = Record<string, any>>({
<BaseForm
formComponentType="ModalForm"
layout="vertical"
formRef={formRef}
{...rest}
formRef={formRef}
submitter={submitterConfig}
onFinish={async (values) => {
const result = await onFinishHandle(values);
Expand Down
164 changes: 164 additions & 0 deletions tests/form/__snapshots__/demo.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -28322,6 +28322,170 @@ exports[`form demos 📸 renders ./packages/form/src/components/QueryFilter/demo
</DocumentFragment>
`;

exports[`form demos 📸 renders ./packages/form/src/components/SchemaForm/demos/ModalAndDrawerForm.tsx correctly 1`] = `
<DocumentFragment>
<div>
test
</div>
<div
class="ant-space ant-space-vertical"
style="width: 100%;"
>
<div
class="ant-space-item"
style="margin-bottom: 8px;"
>
<div
class="ant-alert ant-alert-warning ant-alert-no-icon"
data-show="true"
role="alert"
style="margin-block-end: 24px;"
>
<div
class="ant-alert-content"
>
<div
class="ant-alert-message"
>
QueryFilter 和 lightFilter 暂不支持grid模式
</div>
</div>
</div>
</div>
<div
class="ant-space-item"
>
<div
class="ant-form-item"
>
<div
class="ant-row ant-form-item-row"
>
<div
class="ant-col ant-form-item-label"
>
<label
class=""
title="布局方式"
>
布局方式
</label>
</div>
<div
class="ant-col ant-form-item-control"
>
<div
class="ant-form-item-control-input"
>
<div
class="ant-form-item-control-input-content"
>
<div
class="ant-select ant-select-in-form-item ant-pro-filed-search-select ant-select-single ant-select-allow-clear ant-select-show-arrow"
style="min-width: 100px;"
>
<div
class="ant-select-selector"
>
<span
class="ant-select-selection-search"
>
<input
aria-activedescendant="rc_select_TEST_OR_SSR_list_0"
aria-autocomplete="list"
aria-controls="rc_select_TEST_OR_SSR_list"
aria-expanded="false"
aria-haspopup="listbox"
aria-owns="rc_select_TEST_OR_SSR_list"
autocomplete="off"
class="ant-select-selection-search-input"
id="rc_select_TEST_OR_SSR"
readonly=""
role="combobox"
style="opacity: 0;"
type="search"
unselectable="on"
value=""
/>
</span>
<span
class="ant-select-selection-item"
title="ModalForm"
>
ModalForm
</span>
</div>
<span
aria-hidden="true"
class="ant-select-arrow"
style="user-select: none;"
unselectable="on"
>
<span
aria-label="down"
class="anticon anticon-down ant-select-suffix"
role="img"
>
<svg
aria-hidden="true"
data-icon="down"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
/>
</svg>
</span>
</span>
<span
aria-hidden="true"
class="ant-select-clear"
style="user-select: none;"
unselectable="on"
>
<span
aria-label="close-circle"
class="anticon anticon-close-circle"
role="img"
>
<svg
aria-hidden="true"
data-icon="close-circle"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 01-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z"
/>
</svg>
</span>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<button
class="ant-btn ant-btn-default"
type="button"
>
<span>
点击我
</span>
</button>
</DocumentFragment>
`;

exports[`form demos 📸 renders ./packages/form/src/components/SchemaForm/demos/customization-value-type.tsx correctly 1`] = `
<DocumentFragment>
<div>
Expand Down
Loading

0 comments on commit 06721c3

Please sign in to comment.