## Spin 组件示例
### 基本用法
一个简单的 loading 状态。

```tsx
import React from 'react';
import { Spin } from 'antd';
const App: React.FC = () => <Spin />;
export default App;
```
### 各种大小
小的用于文本加载，默认用于卡片容器级加载，大的用于**页面级**加载。

```tsx
import React from 'react';
import { Flex, Spin } from 'antd';
const App: React.FC = () => (
  <Flex align="center" gap="medium">
    <Spin size="small" />
    <Spin />
    <Spin size="large" />
  </Flex>
);
export default App;
```
### 卡片加载中
可以直接把内容内嵌到 `Spin` 中，将现有容器变为加载状态。

```tsx
import React from 'react';
import { Alert, Flex, Spin, Switch } from 'antd';
const App: React.FC = () => {
  const [loading, setLoading] = React.useState<boolean>(false);
  return (
    <Flex gap="medium" vertical>
      <Spin spinning={loading}>
        <Alert
          type="info"
          title="Alert message title"
          description="Further details about the context of this alert."
        />
      </Spin>
      <p>
        Loading state：
        <Switch checked={loading} onChange={setLoading} />
      </p>
    </Flex>
  );
};
export default App;
```
### 自定义描述文案
自定义描述文案。

```tsx
import React from 'react';
import { Alert, Flex, Spin } from 'antd';
const contentStyle: React.CSSProperties = {
  padding: 50,
  background: 'rgba(0, 0, 0, 0.05)',
  borderRadius: 4,
};
const content = <div style={contentStyle} />;
const App: React.FC = () => (
  <Flex gap="medium" vertical>
    <Flex gap="medium">
      <Spin description="Loading" size="small">
        {content}
      </Spin>
      <Spin description="Loading">{content}</Spin>
      <Spin description="Loading" size="large">
        {content}
      </Spin>
    </Flex>
    <Spin description="Loading...">
      <Alert
        title="Alert message title"
        description="Further details about the context of this alert."
        type="info"
      />
    </Spin>
  </Flex>
);
export default App;
```
### 延迟
延迟显示 loading 效果。当 spinning 状态在 `delay` 时间内结束，则不显示 loading 状态。

```tsx
import React from 'react';
import { Alert, Flex, Spin, Switch } from 'antd';
const App: React.FC = () => {
  const [loading, setLoading] = React.useState<boolean>(false);
  return (
    <Flex gap="medium" vertical>
      <Spin spinning={loading} delay={500}>
        <Alert
          type="info"
          title="Alert message title"
          description="Further details about the context of this alert."
        />
      </Spin>
      <p>
        Loading state：
        <Switch checked={loading} onChange={setLoading} />
      </p>
    </Flex>
  );
};
export default App;
```
### 自定义指示符
使用自定义指示符。

```tsx
import React from 'react';
import { LoadingOutlined } from '@ant-design/icons';
import { Flex, Spin } from 'antd';
const App: React.FC = () => (
  <Flex align="center" gap="medium">
    <Spin indicator={<LoadingOutlined spin />} size="small" />
    <Spin indicator={<LoadingOutlined spin />} />
    <Spin indicator={<LoadingOutlined spin />} size="large" />
    <Spin indicator={<LoadingOutlined style={{ fontSize: 48 }} spin />} />
  </Flex>
);
export default App;
```
### 进度
展示进度，当设置 `percent="auto"` 时会预估一个永远不会停止的进度条。

```tsx
import React from 'react';
import { Flex, Spin, Switch } from 'antd';
const App: React.FC = () => {
  const [auto, setAuto] = React.useState(false);
  const [percent, setPercent] = React.useState(-50);
  const timerRef = React.useRef<ReturnType<typeof setTimeout>>(null);
  React.useEffect(() => {
    timerRef.current = setTimeout(() => {
      setPercent((v) => {
        const nextPercent = v + 5;
        return nextPercent > 150 ? -50 : nextPercent;
      });
    }, 100);
    return () => {
      if (timerRef.current) {
        clearTimeout(timerRef.current);
        timerRef.current = null;
      }
    };
  }, [percent]);
  const mergedPercent = auto ? 'auto' : percent;
  return (
    <Flex align="center" gap="medium">
      <Switch
        checkedChildren="Auto"
        unCheckedChildren="Auto"
        checked={auto}
        onChange={() => {
          setAuto(!auto);
          setPercent(-50);
        }}
      />
      <Spin percent={mergedPercent} size="small" />
      <Spin percent={mergedPercent} />
      <Spin percent={mergedPercent} size="large" />
    </Flex>
  );
};
export default App;
```
### 自定义语义结构的样式和类
通过 `classNames` 和 `styles` 传入对象/函数可以自定义 Spin 的[语义化结构](#semantic-dom)样式。

```tsx
import React from 'react';
import { Flex, Spin } from 'antd';
import type { SpinProps } from 'antd';
import { createStaticStyles } from 'antd-style';
const classNames = createStaticStyles(({ css }) => ({
  root: css`
    padding: 8px;
  `,
}));
const stylesObject: SpinProps['styles'] = {
  indicator: {
    color: '#00d4ff',
  },
};
const stylesFn: SpinProps['styles'] = ({ props }) => {
  if (props.size === 'small') {
    return {
      indicator: {
        color: '#722ed1',
      },
    } satisfies SpinProps['styles'];
  }
  return {};
};
const App: React.FC = () => {
  const sharedProps: SpinProps = {
    spinning: true,
    percent: 0,
    classNames: { root: classNames.root },
  };
  return (
    <Flex align="center" gap="medium">
      <Spin {...sharedProps} styles={stylesObject} />
      <Spin {...sharedProps} styles={stylesFn} size="small" />
    </Flex>
  );
};
export default App;
```
### 全屏
`fullscreen` 属性非常适合创建流畅的页面加载器。它添加了半透明覆盖层，并在其中心放置了一个旋转加载符号。

```tsx
import React from 'react';
import { Button, Spin } from 'antd';
const App: React.FC = () => {
  const [spinning, setSpinning] = React.useState(false);
  const [percent, setPercent] = React.useState(0);
  const showLoader = () => {
    setSpinning(true);
    let ptg = -10;
    const interval = setInterval(() => {
      ptg += 5;
      setPercent(ptg);
      if (ptg > 120) {
        clearInterval(interval);
        setSpinning(false);
        setPercent(0);
      }
    }, 100);
  };
  return (
    <>
      <Button onClick={showLoader}>Show fullscreen</Button>
      <Spin spinning={spinning} percent={percent} fullscreen />
    </>
  );
};
export default App;
```
