스핀

스핀 (Spin)

페이지나 컴포넌트가 비동기 데이터를 기다리거나 렌더링되는 동안 로딩 상태를 보여주는 컴포넌트입니다. 사용자의 불안감을 완화해 줘요.

출처: 문서

본문

언제 사용하나요 (When To Use)

페이지의 일부가 비동기 데이터를 기다리거나 렌더링 과정 중일 때, 적절한 로딩 애니메이션은 사용자의 불안감을 효과적으로 완화해 줍니다.

예제 (Examples)

기본 사용법 (Basic Usage)

간단한 로딩 상태입니다.

import React from 'react';
import { Spin } from 'antd';

const App: React.FC = () => <Spin />;

export default App;

크기 (Size)

텍스트 로딩에는 작은 Spin, 카드 레벨 블록 로딩에는 기본 크기의 Spin, 페이지 로딩에는 큰 Spin을 사용합니다.

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;

임베디드 모드 (Embedded mode)

Spin 안에 콘텐츠를 넣으면 로딩 상태로 설정됩니다.

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;

설명 커스터마이즈 (Customized description)

설명 텍스트를 커스터마이즈합니다.

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;

지연 (Delay)

로딩 상태에 대한 지연을 지정합니다. spinning이 지연 중에 끝나면 로딩 상태가 나타나지 않습니다.

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;

커스텀 로딩 인디케이터 (Custom spinning indicator)

커스텀 로딩 인디케이터를 사용합니다.

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;

진행률 (Progress)

진행률을 표시합니다. percent="auto"로 설정하면 불확정(indeterminate) 진행률이 표시됩니다.

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;

커스텀 시맨틱 DOM 스타일링 (Custom semantic dom styling)

classNames와 styles에 객체 또는 함수를 넘겨서 Spin의 시맨틱 DOM 스타일을 커스터마이즈할 수 있습니다.

import React from 'react';
import { Flex, Spin } from 'antd';
import type { GetProp, 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 }): GetProp<SpinProps, 'styles', 'Return'> => {
  if (props.size === 'small') {
    return {
      indicator: {
        color: '#722ed1',
      },
    };
  }
  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)

fullscreen 모드는 페이지 로더를 만들 때 아주 적합합니다. 어두워진 오버레이와 함께 중앙에 스피너를 표시합니다.

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;

API

Common props ref:Common props

Property Description Type Default Version Global Config
classNames Customize class for each semantic structure inside the component. Supports object or function. Record<SemanticDOM, string> | (info: { props }) => Record<SemanticDOM, string> - 6.0.0
delay Specifies a delay in milliseconds for loading state (prevent flush) number (milliseconds) - ×
description Customize description content ReactNode - 6.3.0 ×
fullscreen Display a backdrop with the Spin component boolean false 5.11.0 ×
indicator React node of the spinning indicator ReactNode - 5.20.0
percent The progress percentage, when set to auto, it will be an indeterminate progress number | 'auto' - 5.18.0 ×
size The size of Spin, options: small, medium and large string medium ×
spinning Whether Spin is visible boolean true ×
styles Customize inline style for each semantic structure inside the component. Supports object or function. Record<SemanticDOM, CSSProperties> | (info: { props }) => Record<SemanticDOM, CSSProperties> - 6.0.0
tip Customize description content when Spin has children. Deprecated, use description instead ReactNode - ×
wrapperClassName The className of wrapper when Spin has children. Deprecated, use classNames.root instead string - ×

정적 메서드 (Static Method)

  • Spin.setDefaultIndicator(indicator: ReactNode)

    기본 스핀 요소를 전역적으로 정의할 수 있습니다.

시맨틱 DOM (Semantic DOM)

https://ant.design/components/spin/semantic.md

디자인 토큰 (Design Token)

컴포넌트 토큰 (Component Token - Spin)

Token Name Description Type Default Value
contentHeight Height of content area string | number 400
dotSize Loading icon size number 20
dotSizeLG Large loading icon size number 32
dotSizeSM Small loading icon size number 14

글로벌 토큰 (Global Token)

Token Name Description Type Default Value
colorBgContainer Container background color, e.g: default button, input box, etc. Be sure not to confuse this with colorBgElevated. string
colorBgMask The background color of the mask, used to cover the content below the mask, Modal, Drawer, Image and other components use this token string
colorFillSecondary The second level of fill color can outline the shape of the element more clearly, such as Rate, Skeleton, etc. It can also be used as the Hover state of the third level of fill color, such as Table, etc. string
colorPrimary Brand color is one of the most direct visual elements to reflect the characteristics and communication of the product. After you have selected the brand color, we will automatically generate a complete color palette and assign it effective design semantics. string
colorText Default text color which comply with W3C standards, and this color is also the darkest neutral color. string
colorTextDescription Control the font color of text description. string
colorTextLightSolid Control the highlight color of text with background color, such as the text in Primary Button components. string
colorWhite Pure white color don't changed by theme string
fontFamily The font family of Ant Design prioritizes the default interface font of the system, and provides a set of alternative font libraries that are suitable for screen display to maintain the readability and readability of the font under different platforms and browsers, reflecting the friendly, stable and professional characteristics. string
fontSize The most widely used font size in the design system, from which the text gradient will be derived. number
lineHeight Line height of text. number
marginXXS Control the margin of an element, with the smallest size. number
motionDurationMid Motion speed, medium speed. Used for medium element animation interaction. string
motionDurationSlow Motion speed, slow speed. Used for large element animation interaction. string
paddingSM Control the small padding of the element. number
zIndexPopupBase Base zIndex of component like FloatButton, Affix which can be cover by large popup number

더 알아보기 (Learn more)