Skip to content

Commit

Permalink
fix: 修复 contentNode 中 props.enhancedAction 未定义错误 (#3)
Browse files Browse the repository at this point in the history
* fix: 修复 contentNode 中 props.enhancedAction 未定义错误

* docs: 补充 content 文档
  • Loading branch information
Wxh16144 committed Jul 24, 2023
1 parent 91b17db commit 7394edf
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 7 deletions.
6 changes: 6 additions & 0 deletions .dumi/app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { App } from 'antd';
import * as React from 'react';

export function rootContainer(container: React.ReactNode) {
return React.createElement(App, null, container);
}
59 changes: 59 additions & 0 deletions docs/examples/advanced-content/ContentForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { App, Button, Form, Input, InputNumber } from 'antd';
import type { PropsWithModalEnhanced } from 'easy-antd-modal';
import * as React from 'react';

const ContentForm: React.FC<PropsWithModalEnhanced> = ({ enhancedAction }) => {
const { message } = App.useApp();
const [loading, setLoading] = React.useState(false);

const onFinish = (values: any) => {
setLoading(true);
globalThis.console.log(JSON.stringify(values, null, 2));
message.success({
content: 'Please check the console',
duration: 1,
onClose() {
setLoading(false);
enhancedAction?.close(); // close the modal after message is closed
},
});
};

return (
<Form
labelCol={{ span: 6 }}
wrapperCol={{ span: 14 }}
name="nest-messages"
onFinish={onFinish}
initialValues={{
user: {
name: 'John Doe',
age: Math.floor(Math.random() * 100),
},
}}
>
<Form.Item name={['user', 'name']} label="Name" rules={[{ required: true }]}>
<Input />
</Form.Item>
<Form.Item name={['user', 'email']} label="Email" rules={[{ type: 'email' }]}>
<Input />
</Form.Item>
<Form.Item name={['user', 'age']} label="Age" rules={[{ type: 'number', min: 0, max: 99 }]}>
<InputNumber />
</Form.Item>
<Form.Item name={['user', 'website']} label="Website">
<Input />
</Form.Item>
<Form.Item name={['user', 'introduction']} label="Introduction">
<Input.TextArea />
</Form.Item>
<Form.Item wrapperCol={{ span: 14, offset: 6 }}>
<Button type="primary" htmlType="submit" loading={loading}>
Submit
</Button>
</Form.Item>
</Form>
);
};

export default ContentForm;
16 changes: 16 additions & 0 deletions docs/examples/advanced-content/drawer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Button } from 'antd';
import { Drawer } from 'easy-antd-modal';
import ContentFrom from './ContentForm';

export default () => (
<Drawer
width={480}
title="Personal information"
trigger={<Button type="primary">Open Form Drawer</Button>}
destroyOnClose
bodyStyle={{ maxHeight: '80vh', overflowY: 'auto' }}
footer={null}
>
<ContentFrom />
</Drawer>
);
14 changes: 14 additions & 0 deletions docs/examples/advanced-content/modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Button } from 'antd';
import Modal from 'easy-antd-modal';
import ContentFrom from './ContentForm';

export default () => (
<Modal
title="Personal information"
trigger={<Button type="primary">Open Form Modal</Button>}
destroyOnClose
footer={null}
>
<ContentFrom />
</Modal>
);
16 changes: 16 additions & 0 deletions docs/guide/advanced.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
title: 进阶使用
group:
title: 快速上手
order: 4
---

### Content 内部关闭

在一些场景下, 我们需要在 Modal 内部关闭 Modal, 例如: 表单提交成功后, 需要关闭 Modal, 这时候我们可以通过 `Content` 组件来实现, `Content` 组件会将 `children` 作为 Modal 的内容, 并且会自动添加关闭按钮, 例如:

<code src="../examples/advanced-content/modal.tsx"></code>

同样的, 这个 `<ContentForm />` 组件也可以应用在 Drawer 中, 例如:

<code src="../examples/advanced-content/drawer.tsx"></code>
13 changes: 6 additions & 7 deletions src/hooks/useModalEnhanced.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,20 @@ import type { AnyFunction, AnyObj } from '../types';
import { isDOMTypeElement, isElement, omit } from '../util';
import useBoolean from './useBoolean';

export type PropsWithModalEnhanced<T extends AnyObj> = {
// eslint-disable-next-line @typescript-eslint/ban-types
export type PropsWithModalEnhanced<T extends AnyObj = {}> = {
enhancedAction?: ModalEnhancedAction;
} & T;

type TriggerType = React.ReactNode;
type ContentType =
| React.ReactNode
| (<P extends AnyObj>(props: PropsWithModalEnhanced<P>) => React.ReactNode);
type HandleCallback = (e: React.MouseEvent<HTMLElement>, action: ModalEnhancedAction) => void;
// eslint-disable-next-line @typescript-eslint/ban-types
| (<P extends AnyObj = {}>(props: PropsWithModalEnhanced<P>) => React.ReactNode);

export interface UseModalEnhancedProps {
defaultOpen?: boolean;
onClick?: HandleCallback;
onClick?: (e: React.MouseEvent<HTMLElement>, action: ModalEnhancedAction) => void;
actionRef?: React.RefObject<ModalEnhancedAction>;
content?: ContentType;
trigger?: TriggerType;
Expand Down Expand Up @@ -51,7 +52,7 @@ function useModalEnhanced(props: UseModalEnhancedProps = {}) {
trigger = React.cloneElement<any>(mergedTrigger, { onClick: handleClick });

// ======================== Content ========================
let contentNode: React.ReactNode = null;
let contentNode: React.ReactNode = mergedContent as React.ReactNode;
if (isElement<PropsWithModalEnhanced<any>>(contentNode) && !isDOMTypeElement(contentNode)) {
contentNode = React.cloneElement<PropsWithModalEnhanced<any>>(contentNode, {
enhancedAction: actionRef.current,
Expand All @@ -60,8 +61,6 @@ function useModalEnhanced(props: UseModalEnhancedProps = {}) {
contentNode = (mergedContent as AnyFunction)({
enhancedAction: actionRef.current,
});
} else {
contentNode = mergedContent as any;
}

const contextHolder = { trigger, content: contentNode };
Expand Down

0 comments on commit 7394edf

Please sign in to comment.