Skip to content

Commit

Permalink
feat(spin): Adds fullscreen property to <Spin /> component (ant-d…
Browse files Browse the repository at this point in the history
…esign#44986)

* feat: start the implementation of the fullscreen prop in Spin

* docs: change main spin demo

* docs: enhance demo

* test: update snapshot

* fix: address pr comments

* fix: use logical property on fullscreen class

* fix: address pr review

* feat: Added background color token

* fix: remove onClick and change demo

* feat: change spin to white when fullcreen

also use the bgmask as background, removing the bgColor token

* fix: unused import

* test: update snapshot

* Update components/spin/style/index.tsx

Signed-off-by: lijianan <574980606@qq.com>

* fix: use white color from token

* fix: not needed interpolation and version

* fix: address pr review

* fix: tip prop was not working

* test: cover tip & fullscreen case

* fix: addrress pr coments

---------

Signed-off-by: lijianan <574980606@qq.com>
Co-authored-by: lijianan <574980606@qq.com>
Co-authored-by: MadCcc <1075746765@qq.com>
  • Loading branch information
3 people authored Oct 19, 2023
1 parent 2e8e67f commit cc223a1
Show file tree
Hide file tree
Showing 9 changed files with 118 additions and 17 deletions.
13 changes: 13 additions & 0 deletions components/spin/__tests__/__snapshots__/demo-extend.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,19 @@ exports[`renders components/spin/demo/delayAndDebounce.tsx extend context correc

exports[`renders components/spin/demo/delayAndDebounce.tsx extend context correctly 2`] = `[]`;

exports[`renders components/spin/demo/fullscreen.tsx extend context correctly 1`] = `
<button
class="ant-btn ant-btn-default"
type="button"
>
<span>
Show fullscreen for 2s
</span>
</button>
`;

exports[`renders components/spin/demo/fullscreen.tsx extend context correctly 2`] = `[]`;

exports[`renders components/spin/demo/inside.tsx extend context correctly 1`] = `
<div
class="example"
Expand Down
11 changes: 11 additions & 0 deletions components/spin/__tests__/__snapshots__/demo.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,17 @@ exports[`renders components/spin/demo/delayAndDebounce.tsx correctly 1`] = `
</div>
`;

exports[`renders components/spin/demo/fullscreen.tsx correctly 1`] = `
<button
class="ant-btn ant-btn-default"
type="button"
>
<span>
Show fullscreen for 2s
</span>
</button>
`;

exports[`renders components/spin/demo/inside.tsx correctly 1`] = `
<div
class="example"
Expand Down
12 changes: 11 additions & 1 deletion components/spin/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { render } from '@testing-library/react';
import React from 'react';
import { render } from '@testing-library/react';

import Spin from '..';
import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
Expand All @@ -19,6 +20,15 @@ describe('Spin', () => {
expect(container.querySelector<HTMLElement>('.ant-spin')?.style.background).toBe('red');
});

it('should not apply nested styles when full screen', () => {
const { container } = render(
<Spin fullscreen>
<div>content</div>
</Spin>,
);
expect(container.querySelector<HTMLElement>('ant-spin-nested-loading')).toBeNull();
});

it("should render custom indicator when it's set", () => {
const customIndicator = <div className="custom-indicator" />;
const { asFragment } = render(<Spin indicator={customIndicator} />);
Expand Down
7 changes: 7 additions & 0 deletions components/spin/demo/fullscreen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
## zh-CN

`fullscreen` 属性非常适合创建流畅的页面加载器。它添加了半透明覆盖层,并在其中心放置了一个旋转加载符号。

## en-US

The `fullscreen` mode is perfect for creating page loaders. It adds a dimmed overlay with a centered spinner.
23 changes: 23 additions & 0 deletions components/spin/demo/fullscreen.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React, { useState } from 'react';
import { Button, Spin } from 'antd';

const App: React.FC = () => {
const [show, setShow] = useState(false);

const showLoader = () => {
setShow(true);

setTimeout(() => {
setShow(false);
}, 2000);
};

return (
<>
<Button onClick={showLoader}>Show fullscreen for 2s</Button>
{show && <Spin fullscreen size="large" />}
</>
);
};

export default App;
10 changes: 6 additions & 4 deletions components/spin/index.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,28 @@ When part of the page is waiting for asynchronous data or during a rendering pro
## Examples

<!-- prettier-ignore -->
<code src="./demo/basic.tsx">basic Usage</code>
<code src="./demo/basic.tsx">Basic Usage</code>
<code src="./demo/size.tsx">Size</code>
<code src="./demo/inside.tsx">Inside a container</code>
<code src="./demo/nested.tsx">Embedded mode</code>
<code src="./demo/tip.tsx">Customized description</code>
<code src="./demo/delayAndDebounce.tsx">delay</code>
<code src="./demo/delayAndDebounce.tsx">Delay</code>
<code src="./demo/custom-indicator.tsx">Custom spinning indicator</code>
<code src="./demo/fullscreen.tsx">Fullscreen</code>

## API

Common props ref:[Common props](/docs/react/common-props)

| Property | Description | Type | Default |
| --- | --- | --- | --- |
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| delay | Specifies a delay in milliseconds for loading state (prevent flush) | number (milliseconds) | - |
| indicator | React node of the spinning indicator | ReactNode | - |
| size | The size of Spin, options: `small`, `default` and `large` | string | `default` |
| spinning | Whether Spin is visible | boolean | true |
| tip | Customize description content when Spin has children | ReactNode | - |
| wrapperClassName | The className of wrapper when Spin has children | string | - |
| fullscreen | Display a backdrop with the `Spin` component | boolean | false | 5.11.0 |

### Static Method

Expand Down
12 changes: 10 additions & 2 deletions components/spin/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export interface SpinProps {
wrapperClassName?: string;
indicator?: SpinIndicator;
children?: React.ReactNode;
fullscreen?: boolean;
}

export interface SpinClassProps extends SpinProps {
Expand Down Expand Up @@ -87,6 +88,7 @@ const Spin: React.FC<SpinClassProps> = (props) => {
style,
children,
hashId,
fullscreen,
...restProps
} = props;

Expand All @@ -108,7 +110,10 @@ const Spin: React.FC<SpinClassProps> = (props) => {
setSpinning(false);
}, [delay, customSpinning]);

const isNestedPattern = React.useMemo<boolean>(() => typeof children !== 'undefined', [children]);
const isNestedPattern = React.useMemo<boolean>(
() => typeof children !== 'undefined' && !fullscreen,
[children, fullscreen],
);

if (process.env.NODE_ENV !== 'production') {
const warning = devUseWarning('Spin');
Expand All @@ -126,6 +131,7 @@ const Spin: React.FC<SpinClassProps> = (props) => {
[`${prefixCls}-lg`]: size === 'large',
[`${prefixCls}-spinning`]: spinning,
[`${prefixCls}-show-text`]: !!tip,
[`${prefixCls}-fullscreen`]: fullscreen,
[`${prefixCls}-rtl`]: direction === 'rtl',
},
className,
Expand All @@ -151,7 +157,9 @@ const Spin: React.FC<SpinClassProps> = (props) => {
aria-busy={spinning}
>
{renderIndicator(prefixCls, props)}
{tip && isNestedPattern ? <div className={`${prefixCls}-text`}>{tip}</div> : null}
{tip && (isNestedPattern || fullscreen) ? (
<div className={`${prefixCls}-text`}>{tip}</div>
) : null}
</div>
);

Expand Down
18 changes: 10 additions & 8 deletions components/spin/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,21 @@ demo:
<code src="./demo/tip.tsx">自定义描述文案</code>
<code src="./demo/delayAndDebounce.tsx">延迟</code>
<code src="./demo/custom-indicator.tsx">自定义指示符</code>
<code src="./demo/fullscreen.tsx">全屏</code>

## API

通用属性参考:[通用属性](/docs/react/common-props)

| 参数 | 说明 | 类型 | 默认值 |
| ---------------- | -------------------------------------------- | ------------- | --------- |
| delay | 延迟显示加载效果的时间(防止闪烁) | number (毫秒) | - |
| indicator | 加载指示符 | ReactNode | - |
| size | 组件大小,可选值为 `small` `default` `large` | string | `default` |
| spinning | 是否为加载中状态 | boolean | true |
| tip | 当作为包裹元素时,可以自定义描述文案 | ReactNode | - |
| wrapperClassName | 包装器的类属性 | string | - |
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| delay | 延迟显示加载效果的时间(防止闪烁) | number (毫秒) | - |
| indicator | 加载指示符 | ReactNode | - |
| size | 组件大小,可选值为 `small` `default` `large` | string | `default` |
| spinning | 是否为加载中状态 | boolean | true |
| tip | 当作为包裹元素时,可以自定义描述文案 | ReactNode | - |
| wrapperClassName | 包装器的类属性 | string | - |
| fullscreen | 显示带有 `Spin` 组件的背景 | boolean | false | 5.11.0 |

### 静态方法

Expand Down
29 changes: 27 additions & 2 deletions components/spin/style/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { CSSObject } from '@ant-design/cssinjs';
import { Keyframes } from '@ant-design/cssinjs';

import { resetComponent } from '../../style';
import type { FullToken, GenerateStyle } from '../../theme/internal';
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
Expand Down Expand Up @@ -39,6 +40,8 @@ const antRotate = new Keyframes('antRotate', {
to: { transform: 'rotate(405deg)' },
});

const dotPadding = (token: SpinToken) => (token.dotSize - token.fontSize) / 2 + 2;

const genSpinStyle: GenerateStyle<SpinToken> = (token: SpinToken): CSSObject => ({
[`${token.componentCls}`]: {
...resetComponent(token),
Expand All @@ -57,6 +60,30 @@ const genSpinStyle: GenerateStyle<SpinToken> = (token: SpinToken): CSSObject =>
opacity: 1,
},

[`${token.componentCls}-text`]: {
fontSize: token.fontSize,
paddingTop: dotPadding(token),
},

'&-fullscreen': {
position: 'fixed',
width: '100vw',
height: '100vh',
backgroundColor: token.colorBgMask,
zIndex: token.zIndexPopupBase,
inset: 0,
display: 'flex',
alignItems: 'center',
flexDirection: 'column',
justifyContent: 'center',
[`${token.componentCls}-dot ${token.componentCls}-dot-item`]: {
backgroundColor: token.colorWhite,
},
[`${token.componentCls}-text`]: {
color: token.colorTextLightSolid,
},
},

'&-nested-loading': {
position: 'relative',
[`> div > ${token.componentCls}`]: {
Expand All @@ -80,9 +107,7 @@ const genSpinStyle: GenerateStyle<SpinToken> = (token: SpinToken): CSSObject =>
position: 'absolute',
top: '50%',
width: '100%',
paddingTop: (token.dotSize - token.fontSize) / 2 + 2,
textShadow: `0 1px 2px ${token.colorBgContainer}`, // FIXME: shadow
fontSize: token.fontSize,
},

[`&${token.componentCls}-show-text ${token.componentCls}-dot`]: {
Expand Down

0 comments on commit cc223a1

Please sign in to comment.