refactor: refactor Drawer loading (#48886)

* refactor: adjust Drawer loading area not include header area

* fix: fix snap

* fix: fix

* fix: fix
This commit is contained in:
lijianan 2024-05-14 14:15:33 +08:00 committed by GitHub
parent b49f70fb74
commit 0836497363
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 147 additions and 88 deletions

View File

@ -5,8 +5,7 @@ import type { DrawerProps as RCDrawerProps } from 'rc-drawer';
import useClosable, { pickClosable } from '../_util/hooks/useClosable';
import type { ClosableType } from '../_util/hooks/useClosable';
import { ConfigContext } from '../config-provider';
import Spin from '../spin';
import type { SpinProps } from '../spin';
import Skeleton from '../skeleton';
export interface DrawerClassNames extends NonNullable<RCDrawerProps['classNames']> {
header?: string;
@ -40,7 +39,7 @@ export interface DrawerPanelProps {
children?: React.ReactNode;
classNames?: DrawerClassNames;
styles?: DrawerStyles;
loading?: boolean | Omit<SpinProps, 'fullscreen' | 'tip'>;
loading?: boolean;
/** @deprecated Please use `styles.header` instead */
headerStyle?: React.CSSProperties;
@ -91,19 +90,6 @@ const DrawerPanel: React.FC<DrawerPanelProps> = (props) => {
},
);
// >>>>>>>>> Spinning
let spinProps: SpinProps | undefined;
if (typeof loading === 'boolean') {
spinProps = {
spinning: loading,
};
} else if (typeof loading === 'object') {
spinProps = {
spinning: true,
...loading,
};
}
const headerNode = React.useMemo<React.ReactNode>(() => {
if (!title && !mergedClosable) {
return null;
@ -156,15 +142,6 @@ const DrawerPanel: React.FC<DrawerPanelProps> = (props) => {
);
}, [footer, footerStyle, prefixCls]);
if (spinProps?.spinning) {
return (
<Spin
{...spinProps}
className={classNames(spinProps.className, `${prefixCls}-content-spin`)}
/>
);
}
return (
<>
{headerNode}
@ -174,13 +151,18 @@ const DrawerPanel: React.FC<DrawerPanelProps> = (props) => {
drawerClassNames?.body,
drawerContext?.classNames?.body,
)}
style={{
...drawerContext?.styles?.body,
...bodyStyle,
...drawerStyles?.body,
}}
style={{ ...drawerContext?.styles?.body, ...bodyStyle, ...drawerStyles?.body }}
>
{children}
{loading ? (
<Skeleton
active
title={false}
paragraph={{ rows: 5 }}
className={`${prefixCls}-body-skeleton`}
/>
) : (
children
)}
</div>
{footerNode}
</>

View File

@ -190,20 +190,14 @@ describe('Drawer', () => {
expect(wrapper.firstChild).toMatchSnapshot();
});
it('have a custom loading', () => {
const loadingContent = 'Custom Loading...';
const { container: wrapper } = render(
<Drawer
open
loading={{ indicator: <span>{loadingContent}</span>, spinning: true }}
getContainer={false}
>
const { container } = render(
<Drawer open loading getContainer={false}>
Here is content of Drawer
</Drawer>,
);
triggerMotion();
const [loadingWrapper] = wrapper.getElementsByClassName('ant-spin-dot');
expect(loadingWrapper).toHaveTextContent(loadingContent);
const wrapper = container.querySelector<HTMLDivElement>('.ant-skeleton');
expect(wrapper).toBeTruthy();
});
});

View File

@ -24,26 +24,61 @@ exports[`Drawer Drawer loading have a spinner 1`] = `
role="dialog"
>
<div
aria-busy="true"
aria-live="polite"
class="ant-spin ant-spin-spinning ant-drawer-content-spin"
class="ant-drawer-header ant-drawer-header-close-only"
>
<span
class="ant-spin-dot ant-spin-dot-spin"
<div
class="ant-drawer-header-title"
>
<i
class="ant-spin-dot-item"
/>
<i
class="ant-spin-dot-item"
/>
<i
class="ant-spin-dot-item"
/>
<i
class="ant-spin-dot-item"
/>
</span>
<button
aria-label="Close"
class="ant-drawer-close"
type="button"
>
<span
aria-label="close"
class="anticon anticon-close"
role="img"
>
<svg
aria-hidden="true"
data-icon="close"
fill="currentColor"
fill-rule="evenodd"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M799.86 166.31c.02 0 .04.02.08.06l57.69 57.7c.04.03.05.05.06.08a.12.12 0 010 .06c0 .03-.02.05-.06.09L569.93 512l287.7 287.7c.04.04.05.06.06.09a.12.12 0 010 .07c0 .02-.02.04-.06.08l-57.7 57.69c-.03.04-.05.05-.07.06a.12.12 0 01-.07 0c-.03 0-.05-.02-.09-.06L512 569.93l-287.7 287.7c-.04.04-.06.05-.09.06a.12.12 0 01-.07 0c-.02 0-.04-.02-.08-.06l-57.69-57.7c-.04-.03-.05-.05-.06-.07a.12.12 0 010-.07c0-.03.02-.05.06-.09L454.07 512l-287.7-287.7c-.04-.04-.05-.06-.06-.09a.12.12 0 010-.07c0-.02.02-.04.06-.08l57.7-57.69c.03-.04.05-.05.07-.06a.12.12 0 01.07 0c.03 0 .05.02.09.06L512 454.07l287.7-287.7c.04-.04.06-.05.09-.06a.12.12 0 01.07 0z"
/>
</svg>
</span>
</button>
</div>
</div>
<div
class="ant-drawer-body"
>
<div
class="ant-skeleton ant-skeleton-active ant-drawer-body-skeleton"
>
<div
class="ant-skeleton-content"
>
<ul
class="ant-skeleton-paragraph"
>
<li />
<li />
<li />
<li />
<li
style="width: 61%;"
/>
</ul>
</div>
</div>
</div>
</div>
</div>

View File

@ -2814,26 +2814,66 @@ Array [
role="dialog"
>
<div
aria-busy="true"
aria-live="polite"
class="ant-spin ant-spin-spinning ant-drawer-content-spin"
class="ant-drawer-header"
>
<span
class="ant-spin-dot ant-spin-dot-spin"
<div
class="ant-drawer-header-title"
>
<i
class="ant-spin-dot-item"
/>
<i
class="ant-spin-dot-item"
/>
<i
class="ant-spin-dot-item"
/>
<i
class="ant-spin-dot-item"
/>
</span>
<button
aria-label="Close"
class="ant-drawer-close"
type="button"
>
<span
aria-label="close"
class="anticon anticon-close"
role="img"
>
<svg
aria-hidden="true"
data-icon="close"
fill="currentColor"
fill-rule="evenodd"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M799.86 166.31c.02 0 .04.02.08.06l57.69 57.7c.04.03.05.05.06.08a.12.12 0 010 .06c0 .03-.02.05-.06.09L569.93 512l287.7 287.7c.04.04.05.06.06.09a.12.12 0 010 .07c0 .02-.02.04-.06.08l-57.7 57.69c-.03.04-.05.05-.07.06a.12.12 0 01-.07 0c-.03 0-.05-.02-.09-.06L512 569.93l-287.7 287.7c-.04.04-.06.05-.09.06a.12.12 0 01-.07 0c-.02 0-.04-.02-.08-.06l-57.69-57.7c-.04-.03-.05-.05-.06-.07a.12.12 0 010-.07c0-.03.02-.05.06-.09L454.07 512l-287.7-287.7c-.04-.04-.05-.06-.06-.09a.12.12 0 010-.07c0-.02.02-.04.06-.08l57.7-57.69c.03-.04.05-.05.07-.06a.12.12 0 01.07 0c.03 0 .05.02.09.06L512 454.07l287.7-287.7c.04-.04.06-.05.09-.06a.12.12 0 01.07 0z"
/>
</svg>
</span>
</button>
<div
class="ant-drawer-title"
>
Loading Drawer
</div>
</div>
</div>
<div
class="ant-drawer-body"
>
<div
class="ant-skeleton ant-skeleton-active ant-drawer-body-skeleton"
>
<div
class="ant-skeleton-content"
>
<ul
class="ant-skeleton-paragraph"
>
<li />
<li />
<li />
<li />
<li
style="width: 61%;"
/>
</ul>
</div>
</div>
</div>
</div>
</div>

View File

@ -29,10 +29,10 @@ const App: React.FC = () => {
Open
</Button>
<Drawer
closable
destroyOnClose
title="Basic Drawer"
title="Loading Drawer"
placement="right"
closable={false}
open={open}
loading={loading}
onClose={() => setOpen(false)}

View File

@ -17,6 +17,10 @@ A Drawer is a panel that is typically overlaid on top of a page and slides in fr
- Processing subtasks. When subtasks are too heavy for a Popover and we still want to keep the subtasks in the context of the main task, Drawer comes very handy.
- When the same Form is needed in multiple places.
> Notes for developers
>
> Since the `5.17.0`, we provided the `loading` prop by the Spin. However, since the `5.18.0` version, we have fixed this design error and replaced the Spin with the Skeleton, and also modified the type of `loading` prop, which can only accept `boolean` type.
## Examples
<!-- prettier-ignore -->
@ -69,7 +73,7 @@ v5 use `rootClassName` & `rootStyle` to config wrapper style instead of `classNa
| styles | Semantic structure style | [Record<SemanticDOM, CSSProperties>](#semantic-dom) | - | 5.10.0 |
| size | preset size of drawer, default `378px` and large `736px` | 'default' \| 'large' | 'default' | 4.17.0 |
| title | The title for Drawer | ReactNode | - | |
| loading | Show spinning indicator | boolean \| `Omit<SpinProp, 'fullScreen' \| 'tip'>` | false | 5.17.0 |
| loading | Show the Skeleton | boolean | false | 5.17.0 |
| open | Whether the Drawer dialog is visible or not | boolean | false | |
| width | Width of the Drawer dialog | string \| number | 378 | |
| zIndex | The `z-index` of the Drawer | number | 1000 | |

View File

@ -17,6 +17,10 @@ demo:
- 当需要一个附加的面板来控制父窗体内容,这个面板在需要时呼出。比如,控制界面展示样式,往界面中添加内容。
- 当需要在当前任务流中插入临时任务,创建或预览附加内容。比如展示协议条款,创建子对象。
> 开发者注意事项:
>
> 自 `5.17.0` 版本,我们提供了 `loading` 属性,内置 Spin 组件作为加载状态,但是自 `5.18.0` 版本开始,我们修复了设计失误,将内置的 Spin 组件替换成了 Skeleton 组件,同时收窄了 `loading` api 的类型范围,只能接收 boolean 类型。
## 代码演示
<!-- prettier-ignore -->
@ -68,7 +72,7 @@ v5 使用 `rootClassName` 与 `rootStyle` 来配置最外层元素样式。原 v
| style | 设计 Drawer 容器样式,如果你只需要设置内容部分请使用 `bodyStyle` | CSSProperties | - | |
| styles | 语义化结构 style | [Record<SemanticDOM, CSSProperties>](#semantic-dom) | - | 5.10.0 |
| title | 标题 | ReactNode | - | |
| loading | 显示旋转指示器 | boolean \| `Omit<SpinProp, 'fullScreen' \| 'tip'>` | false | 5.17.0 |
| loading | 显示骨架屏 | boolean | false | 5.17.0 |
| open | Drawer 是否可见 | boolean | - |
| width | 宽度 | string \| number | 378 | |
| zIndex | 设置 Drawer 的 `z-index` | number | 1000 | |

View File

@ -147,13 +147,6 @@ const genDrawerStyle: GenerateStyle<DrawerToken> = (token) => {
overflow: 'auto',
background: colorBgElevated,
pointerEvents: 'auto',
[`${componentCls}-content-spin`]: {
width: '100%',
height: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
},
// Header
@ -230,6 +223,13 @@ const genDrawerStyle: GenerateStyle<DrawerToken> = (token) => {
minHeight: 0,
padding: paddingLG,
overflow: 'auto',
[`${componentCls}-body-skeleton`]: {
width: '100%',
height: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
},
// Footer