mirror of
https://github.com/ant-design/ant-design.git
synced 2025-01-18 22:36:31 +08:00
feat: Modal support loading (#48848)
* feat: Modal support loading * feat: Modal support loading * chore: update skeleton className * fix: fix * demo: add LoadingOutlined * fix: revert icon * fix: fix * fix: renderFooter * fix: renderFooter * demo: update demo * demo: update demo * demo: update demo * chore: clear * Update loading.tsx Signed-off-by: 二货爱吃白萝卜 <smith3816@gmail.com> * fix: fix --------- Signed-off-by: 二货爱吃白萝卜 <smith3816@gmail.com> Co-authored-by: 二货爱吃白萝卜 <smith3816@gmail.com>
This commit is contained in:
parent
05f587a6ce
commit
7cdeecfe1e
@ -12,6 +12,7 @@ import zIndexContext from '../_util/zindexContext';
|
|||||||
import { ConfigContext } from '../config-provider';
|
import { ConfigContext } from '../config-provider';
|
||||||
import useCSSVarCls from '../config-provider/hooks/useCSSVarCls';
|
import useCSSVarCls from '../config-provider/hooks/useCSSVarCls';
|
||||||
import { NoFormStyle } from '../form/context';
|
import { NoFormStyle } from '../form/context';
|
||||||
|
import Skeleton from '../skeleton';
|
||||||
import { NoCompactStyle } from '../space/Compact';
|
import { NoCompactStyle } from '../space/Compact';
|
||||||
import { usePanelRef } from '../watermark/context';
|
import { usePanelRef } from '../watermark/context';
|
||||||
import type { ModalProps, MousePosition } from './interface';
|
import type { ModalProps, MousePosition } from './interface';
|
||||||
@ -86,6 +87,8 @@ const Modal: React.FC<ModalProps> = (props) => {
|
|||||||
footer,
|
footer,
|
||||||
classNames: modalClassNames,
|
classNames: modalClassNames,
|
||||||
styles: modalStyles,
|
styles: modalStyles,
|
||||||
|
children,
|
||||||
|
loading,
|
||||||
...restProps
|
...restProps
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
@ -100,9 +103,10 @@ const Modal: React.FC<ModalProps> = (props) => {
|
|||||||
[`${prefixCls}-wrap-rtl`]: direction === 'rtl',
|
[`${prefixCls}-wrap-rtl`]: direction === 'rtl',
|
||||||
});
|
});
|
||||||
|
|
||||||
const dialogFooter = footer !== null && (
|
const dialogFooter =
|
||||||
<Footer {...props} onOk={handleOk} onCancel={handleCancel} />
|
footer !== null && !loading ? (
|
||||||
);
|
<Footer {...props} onOk={handleOk} onCancel={handleCancel} />
|
||||||
|
) : null;
|
||||||
|
|
||||||
const [mergedClosable, mergedCloseIcon] = useClosable(
|
const [mergedClosable, mergedCloseIcon] = useClosable(
|
||||||
pickClosable(props),
|
pickClosable(props),
|
||||||
@ -149,12 +153,20 @@ const Modal: React.FC<ModalProps> = (props) => {
|
|||||||
...modalClassNames,
|
...modalClassNames,
|
||||||
wrapper: classNames(wrapClassNameExtended, modalClassNames?.wrapper),
|
wrapper: classNames(wrapClassNameExtended, modalClassNames?.wrapper),
|
||||||
}}
|
}}
|
||||||
styles={{
|
styles={{ ...modalContext?.styles, ...modalStyles }}
|
||||||
...modalContext?.styles,
|
|
||||||
...modalStyles,
|
|
||||||
}}
|
|
||||||
panelRef={panelRef}
|
panelRef={panelRef}
|
||||||
/>
|
>
|
||||||
|
{loading ? (
|
||||||
|
<Skeleton
|
||||||
|
active
|
||||||
|
title={false}
|
||||||
|
paragraph={{ rows: 4 }}
|
||||||
|
className={`${prefixCls}-body-skeleton`}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
children
|
||||||
|
)}
|
||||||
|
</Dialog>
|
||||||
</zIndexContext.Provider>
|
</zIndexContext.Provider>
|
||||||
</NoFormStyle>
|
</NoFormStyle>
|
||||||
</NoCompactStyle>,
|
</NoCompactStyle>,
|
||||||
|
@ -630,6 +630,19 @@ exports[`renders components/modal/demo/hooks.tsx extend context correctly 1`] =
|
|||||||
|
|
||||||
exports[`renders components/modal/demo/hooks.tsx extend context correctly 2`] = `[]`;
|
exports[`renders components/modal/demo/hooks.tsx extend context correctly 2`] = `[]`;
|
||||||
|
|
||||||
|
exports[`renders components/modal/demo/loading.tsx extend context correctly 1`] = `
|
||||||
|
<button
|
||||||
|
class="ant-btn ant-btn-primary"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
Open Modal
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`renders components/modal/demo/loading.tsx extend context correctly 2`] = `[]`;
|
||||||
|
|
||||||
exports[`renders components/modal/demo/locale.tsx extend context correctly 1`] = `
|
exports[`renders components/modal/demo/locale.tsx extend context correctly 1`] = `
|
||||||
<div
|
<div
|
||||||
class="ant-space ant-space-horizontal ant-space-align-center ant-space-gap-row-small ant-space-gap-col-small"
|
class="ant-space ant-space-horizontal ant-space-align-center ant-space-gap-row-small ant-space-gap-col-small"
|
||||||
|
@ -606,6 +606,17 @@ exports[`renders components/modal/demo/hooks.tsx correctly 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`renders components/modal/demo/loading.tsx correctly 1`] = `
|
||||||
|
<button
|
||||||
|
class="ant-btn ant-btn-primary"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
Open Modal
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`renders components/modal/demo/locale.tsx correctly 1`] = `
|
exports[`renders components/modal/demo/locale.tsx correctly 1`] = `
|
||||||
<div
|
<div
|
||||||
class="ant-space ant-space-horizontal ant-space-align-center ant-space-gap-row-small ant-space-gap-col-small"
|
class="ant-space ant-space-horizontal ant-space-align-center ant-space-gap-row-small ant-space-gap-col-small"
|
||||||
|
7
components/modal/demo/loading.md
Normal file
7
components/modal/demo/loading.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
## zh-CN
|
||||||
|
|
||||||
|
设置对话框加载状态。
|
||||||
|
|
||||||
|
## en-US
|
||||||
|
|
||||||
|
Set the loading status of Modal.
|
42
components/modal/demo/loading.tsx
Normal file
42
components/modal/demo/loading.tsx
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Button, Modal } from 'antd';
|
||||||
|
|
||||||
|
const App: React.FC = () => {
|
||||||
|
const [open, setOpen] = React.useState<boolean>(false);
|
||||||
|
const [loading, setLoading] = React.useState<boolean>(true);
|
||||||
|
|
||||||
|
const showLoading = () => {
|
||||||
|
setOpen(true);
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
// Simple loading mock. You should add cleanup logic in real world.
|
||||||
|
setTimeout(() => {
|
||||||
|
setLoading(false);
|
||||||
|
}, 2000);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Button type="primary" onClick={showLoading}>
|
||||||
|
Open Modal
|
||||||
|
</Button>
|
||||||
|
<Modal
|
||||||
|
title={<p>Loading Modal</p>}
|
||||||
|
footer={
|
||||||
|
<Button type="primary" onClick={showLoading}>
|
||||||
|
Reload
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
loading={loading}
|
||||||
|
open={open}
|
||||||
|
onCancel={() => setOpen(false)}
|
||||||
|
>
|
||||||
|
<p>Some contents...</p>
|
||||||
|
<p>Some contents...</p>
|
||||||
|
<p>Some contents...</p>
|
||||||
|
</Modal>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default App;
|
@ -21,6 +21,7 @@ Additionally, if you need to show a simple confirmation dialog, you can use [`Ap
|
|||||||
<code src="./demo/basic.tsx">Basic</code>
|
<code src="./demo/basic.tsx">Basic</code>
|
||||||
<code src="./demo/async.tsx">Asynchronously close</code>
|
<code src="./demo/async.tsx">Asynchronously close</code>
|
||||||
<code src="./demo/footer.tsx">Customized Footer</code>
|
<code src="./demo/footer.tsx">Customized Footer</code>
|
||||||
|
<code src="./demo/loading.tsx" version="5.18.0">Loading</code>
|
||||||
<code src="./demo/footer-render.tsx">Customized Footer render function</code>
|
<code src="./demo/footer-render.tsx">Customized Footer render function</code>
|
||||||
<code src="./demo/hooks.tsx">Use hooks to get context</code>
|
<code src="./demo/hooks.tsx">Use hooks to get context</code>
|
||||||
<code src="./demo/locale.tsx">Internationalization</code>
|
<code src="./demo/locale.tsx">Internationalization</code>
|
||||||
@ -67,6 +68,7 @@ Common props ref:[Common props](/docs/react/common-props)
|
|||||||
| okText | Text of the OK button | ReactNode | `OK` | |
|
| okText | Text of the OK button | ReactNode | `OK` | |
|
||||||
| okType | Button `type` of the OK button | string | `primary` | |
|
| okType | Button `type` of the OK button | string | `primary` | |
|
||||||
| style | Style of floating layer, typically used at least for adjusting the position | CSSProperties | - | |
|
| style | Style of floating layer, typically used at least for adjusting the position | CSSProperties | - | |
|
||||||
|
| loading | Show the skeleton | boolean | | 5.18.0 |
|
||||||
| title | The modal dialog's title | ReactNode | - | |
|
| title | The modal dialog's title | ReactNode | - | |
|
||||||
| open | Whether the modal dialog is visible or not | boolean | false | |
|
| open | Whether the modal dialog is visible or not | boolean | false | |
|
||||||
| width | Width of the modal dialog | string \| number | 520 | |
|
| width | Width of the modal dialog | string \| number | 520 | |
|
||||||
|
@ -22,6 +22,7 @@ demo:
|
|||||||
<code src="./demo/basic.tsx">基本</code>
|
<code src="./demo/basic.tsx">基本</code>
|
||||||
<code src="./demo/async.tsx">异步关闭</code>
|
<code src="./demo/async.tsx">异步关闭</code>
|
||||||
<code src="./demo/footer.tsx">自定义页脚</code>
|
<code src="./demo/footer.tsx">自定义页脚</code>
|
||||||
|
<code src="./demo/loading.tsx" version="5.18.0">加载中</code>
|
||||||
<code src="./demo/footer-render.tsx">自定义页脚渲染函数</code>
|
<code src="./demo/footer-render.tsx">自定义页脚渲染函数</code>
|
||||||
<code src="./demo/hooks.tsx">使用 hooks 获得上下文</code>
|
<code src="./demo/hooks.tsx">使用 hooks 获得上下文</code>
|
||||||
<code src="./demo/locale.tsx">国际化</code>
|
<code src="./demo/locale.tsx">国际化</code>
|
||||||
@ -68,6 +69,7 @@ demo:
|
|||||||
| okText | 确认按钮文字 | ReactNode | `确定` | |
|
| okText | 确认按钮文字 | ReactNode | `确定` | |
|
||||||
| okType | 确认按钮类型 | string | `primary` | |
|
| okType | 确认按钮类型 | string | `primary` | |
|
||||||
| style | 可用于设置浮层的样式,调整浮层位置等 | CSSProperties | - | |
|
| style | 可用于设置浮层的样式,调整浮层位置等 | CSSProperties | - | |
|
||||||
|
| loading | 显示骨架屏 | boolean | | 5.18.0 |
|
||||||
| title | 标题 | ReactNode | - | |
|
| title | 标题 | ReactNode | - | |
|
||||||
| open | 对话框是否可见 | boolean | - | |
|
| open | 对话框是否可见 | boolean | - | |
|
||||||
| width | 宽度 | string \| number | 520 | |
|
| width | 宽度 | string \| number | 520 | |
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import type { FC } from 'react';
|
import type React from 'react';
|
||||||
import type { DialogProps } from 'rc-dialog';
|
import type { DialogProps } from 'rc-dialog';
|
||||||
|
|
||||||
import type { ClosableType } from '../_util/hooks/useClosable';
|
import type { ClosableType } from '../_util/hooks/useClosable';
|
||||||
@ -7,7 +7,7 @@ import type { DirectionType } from '../config-provider';
|
|||||||
|
|
||||||
export type ModalFooterRender = (
|
export type ModalFooterRender = (
|
||||||
originNode: React.ReactNode,
|
originNode: React.ReactNode,
|
||||||
extra: { OkBtn: FC; CancelBtn: FC },
|
extra: { OkBtn: React.FC; CancelBtn: React.FC },
|
||||||
) => React.ReactNode;
|
) => React.ReactNode;
|
||||||
interface ModalCommonProps {
|
interface ModalCommonProps {
|
||||||
styles?: Omit<NonNullable<DialogProps['styles']>, 'wrapper'>;
|
styles?: Omit<NonNullable<DialogProps['styles']>, 'wrapper'>;
|
||||||
@ -73,6 +73,10 @@ export interface ModalProps extends ModalCommonProps {
|
|||||||
// Legacy
|
// Legacy
|
||||||
/** @deprecated Please use `open` instead. */
|
/** @deprecated Please use `open` instead. */
|
||||||
visible?: boolean;
|
visible?: boolean;
|
||||||
|
/**
|
||||||
|
* @since 5.18.0
|
||||||
|
*/
|
||||||
|
loading?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
type getContainerFunc = () => HTMLElement;
|
type getContainerFunc = () => HTMLElement;
|
||||||
|
@ -270,6 +270,14 @@ const genModalStyle: GenerateStyle<ModalToken> = (token) => {
|
|||||||
lineHeight: token.lineHeight,
|
lineHeight: token.lineHeight,
|
||||||
wordWrap: 'break-word',
|
wordWrap: 'break-word',
|
||||||
padding: token.bodyPadding,
|
padding: token.bodyPadding,
|
||||||
|
[`${componentCls}-body-skeleton`]: {
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
margin: `${unit(token.margin)} auto`,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
[`${componentCls}-footer`]: {
|
[`${componentCls}-footer`]: {
|
||||||
|
Loading…
Reference in New Issue
Block a user