로딩 스피너 만들기

소개



이것은 UI Kit with React, TypeScript, Storybook and Tailwind의 일부입니다. 혼란스러운 점이 있으면 시리즈의 이전 항목을 확인했는지 확인하세요.

이 시리즈에서는 기본 로딩 스피너를 구현하고 Storybook 과 통합하는 것을 목표로 합니다.


로딩 스피너



로딩 스피너에 필요한 것을 만드는 것으로 시작해 봅시다. 내 로딩 스피너가 측면에서 들어오고 나가는 세 개의 막대로 구성되기를 원합니다. 또한 로딩 스피너와 함께 사용할 텍스트를 지정할 수 있기를 원합니다.

프로젝트에서 두 개의 파일을 만듭니다.
  • src/components/LoadingSpinner/LoadingSpinner.tsx
  • src/components/LoadingSpinner/LoadingSpinner.module.css

  • 먼저 LoadingSpinner 에 필요한 구조를 만듭니다.

    // LoadingSpinner.tsx
    
    import cx from "classnames";
    import styles from "./LoadingSpinner.module.css";
    
    export type LoadingSpinnerProps = {
      isLoading: boolean;
      color?: string;
      text?: string;
    };
    
    const LoadingSpinner = ({
      isLoading,
      color = "bg-black",
      text = "",
    }: LoadingSpinnerProps) => {
      if (!isLoading) return null;
      return (
        <div className={styles.wrapper}>
          <div className={cx(styles.div1, color)}></div>
          <div className={cx(styles.div2, color)}></div>
          <div className={cx(styles.div3, color)}></div>
          <span>{text}</span>
        </div>
      );
    };
    
    export default LoadingSpinner;
    


    이 단계에서 이 구성 요소는 많은 작업을 수행하지 않거나 원하는 대로 보이지 않지만 이것이 내 구성 요소에 필요한 모든 것이어야 합니다.

    상단에서 classnames 이라는 라이브러리를 가져오는 것을 볼 수 있습니다. 저는 모든 React 앱에서 이 라이브러리를 사용하는 것을 좋아합니다. classNames 문자열을 쉽게 조작하여 혼자서 하기 힘든 방식으로 결합할 수 있습니다. 관심이 있는 경우 여기에서 classnames에 대해 자세히 읽을 수 있습니다. https://github.com/JedWatson/classnames . 제 경우에는 두 문자열(styles에서 가져온 문자열과 소품에서 color 문자열을 가져온 문자열)을 간단히 결합합니다.


    CSS 추가



    여기서 목표로 하는 것을 달성하기 위해 css이 많이 필요하지 않습니다.

    /* LoadingSpinner.module.css */
    
    .wrapper {
      width: fit-content;
      min-width: 24px;
    }
    
    .wrapper div {
      margin: 3px auto;
      height: 0.33em;
    }
    
    .div1 {
      animation: pulse 1.2s cubic-bezier(0, 0.5, 0.5, 1) infinite;
      margin-bottom: 2px;
    }
    
    .div2 {
      animation: pulse 1.2s cubic-bezier(0, 0.5, 0.5, 1) infinite;
      animation-delay: -0.2s;
      margin-bottom: 2px;
    }
    
    .div3 {
      animation: pulse 1.2s cubic-bezier(0, 0.5, 0.5, 1) infinite;
      animation-delay: -0.4s;
    }
    
    @keyframes pulse {
      0% {
        width: 0.4em;
      }
      50% {
        width: 1.4em;
      }
      100% {
        width: 0.4em;
      }
    }
    



    결과



    지금 이 구성 요소를 사용하면 다음과 같이 보이지만 애니메이션이 적용됩니다.




    구성 요소를 Storybook과 통합:



    다음 내용으로 src/stories/LoadingSpinner/LoadingSpinner.stories.tsx이라는 파일을 만듭니다.

    import { ComponentMeta, Story } from "@storybook/react";
    import LoadingSpinner, {
      LoadingSpinnerProps,
    } from "../../components/LoadingSpinner/LoadingSpinner";
    
    export default {
      argTypes: {
        color: {
          options: ["bg-red-200", "bg-indigo-700", "bg-black"],
          control: { type: "select" },
        },
      },
      title: "Loading Spinner",
      component: LoadingSpinner,
    } as ComponentMeta<typeof LoadingSpinner>;
    
    const Template: Story<LoadingSpinnerProps> = (args) => (
      <LoadingSpinner {...args} />
    );
    
    export const Basic = Template.bind({});
    Basic.args = {
      isLoading: true,
    };
    
    export const WithText = Template.bind({});
    WithText.args = {
      isLoading: true,
      text: "Loading...",
    };
    


    이렇게 하면 Storybook에서 구성 요소와 해당 컨트롤을 렌더링하는 데 필요한 모든 것이 생성됩니다.

    우리는 Storybook 소품이 color 컨트롤로 제어 가능해야 한다고 select에 알려줍니다. 여기서 옵션은 ["bg-red-200", "bg-indigo-700", "bg-black"]의 값 중 하나일 수 있습니다. 또한 Storybook에 서로 다른 두 가지 변형, 즉 BasicWithText을 표시하고 싶다고 말하며, 이렇게 하면 구성 요소의 미리 빌드된 다양한 사용 사례를 표시할 수 있습니다.


    러닝 스토리북



    이것이 실제로 어떻게 보이는지 보려면 Storybook을 실행하여 yarn storybook을 시작해야 합니다.
    Storybook을 실행하고 http://localhost:6006을 방문하면 실제로 로드 스피너를 사이드바에서 사용할 수 있음을 알 수 있습니다. 또한 아래 이미지와 같이 속성을 변경하여 구성 요소를 실시간으로 테스트할 수 있습니다.




    문제 해결



    실행할 수 없거나 다른 문제가 있는 경우 내 저장소에서 확인하고 작동하는지 확인하십시오.

    https://github.com/simon-nystrom/newcurrent-react-ui/tree/loading-spinner


    시리즈의 다음 항목을 기대해 주세요 😊. 다음에 보고 싶은 구성 요소는 무엇입니까?

    좋은 웹페이지 즐겨찾기