버튼 만들기

소개



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

이 시리즈에서는 기본 버튼 구성 요소를 구현하고 Storybook 와 통합하는 것을 목표로 합니다.


버튼



버튼 구성 요소에 필요한 것을 만드는 것으로 시작하겠습니다. 내 버튼이 세 가지 크기, 세 가지 변형을 지원하고 onClick 핸들러를 수락하고 버튼에 텍스트를 지정하기를 원합니다.

이 블로그 게시물에서 다음을 빌드합니다.



프로젝트에서 다음 파일을 만듭니다.
  • src/components/Button/Button.tsx

  • 먼저 내Button에서 지원하려는 유형을 생성합니다.

    // Button.tsx
    
    export enum ButtonVariant {
      PRIMARY = "primary",
      SECONDARY = "secondary",
      TERTIARY = "tertiary",
    }
    
    export enum ButtonSize {
      SMALL = "small",
      MEDIUM = "medium",
      LARGE = "large",
    }
    
    export type ButtonProps = {
      type?: "submit" | "reset" | "button";
      text: string;
      variant: ButtonVariant;
      size?: ButtonSize;
      onClick?: () => void;
    };
    


    이것은 좋은 토대를 마련하는데, 미리 유형을 가지고 있으면 Button 구성 요소를 더 쉽게 작성할 수 있습니다.

    이제 필요한 상용구를 작성하는 것으로 시작하여 구성 요소 자체에 대한 작업을 시작해야 합니다.

    // Button.tsx
    
    const Button = ({
      type = "submit",
      text,
      size = ButtonSize.MEDIUM,
      variant = ButtonVariant.PRIMARY,
      onClick,
    }: ButtonProps) => {
      return (
        <button onClick={onClick} type={type}>
          {text}
        </button>
      );
    };
    
    export default Button;
    


    이 단계에서 Button 구성 요소는 모든 변형 및 크기에서 다음과 같이 보입니다.



    이제 tailwind 를 사용하여 몇 가지 스타일을 추가해 보겠습니다.

    const shared =
      "rounded-sm text-white tracking-tighter transition-color duration-150";
    
    const small = "p-1 text-sm font-medium gap-2 border-1";
    const medium = "px-3 py-1.5 font-semibold border-2";
    const large = "px-4 py-2 text-lg font-semibold border-4";
    
    const primary =
      "bg-indigo-700 border-transparent text-white hover:bg-indigo-600";
    
    const secondary =
      "border border-indigo-700 text-indigo-700 hover:bg-indigo-200";
    
    const tertiary =
      "text-indigo-700 border-transparent bg-white hover:bg-indigo-600 hover:text-white";
    
    const getSizeClass = (size: ButtonSize) => {
      if (size === ButtonSize.SMALL) return small;
      if (size === ButtonSize.MEDIUM) return medium;
      if (size === ButtonSize.LARGE) return large;
    };
    
    const getVariantClass = (variant: ButtonVariant) => {
      if (variant === ButtonVariant.PRIMARY) return primary;
      if (variant === ButtonVariant.SECONDARY) return secondary;
      if (variant === ButtonVariant.TERTIARY) return tertiary;
    };
    


    그리고 classnames 가져오기를 통해 Button에서 클래스를 쉽게 결합할 수 있습니다.

    // Button.tsx
    
    import cx from "classnames";
    
    const Button = ({
      type = "submit",
      text,
      size = ButtonSize.MEDIUM,
      variant = ButtonVariant.PRIMARY,
      onClick,
    }: ButtonProps) => {
      return (
        <button
          onClick={onClick}
          className={cx(shared, getSizeClass(size), getVariantClass(variant))}
          type={type}
        >
          {text}
        </button>
      );
    };
    


    이것이 Button 구성 요소 😊에 필요한 전부입니다.


    스토리북에 버튼 추가하기


    Button 에 미리 정의된 다양한 속성과 함께 Storybook를 표시하려면 다음 파일을 만듭니다.
  • src/stories/Button/Button.stories.tsx

  • 그리고 다음 내용을 추가합니다.

    // Button.stories.tsx
    
    import { ComponentMeta, Story } from "@storybook/react";
    import Button, {
      ButtonProps,
      ButtonSize,
      ButtonVariant,
    } from "../../components/Button/Button";
    
    export default {
      title: "Button",
      component: Button,
    } as ComponentMeta<typeof Button>;
    
    const Template: Story<ButtonProps> = (args) => <Button {...args} />;
    
    export const SmallPrimary = Template.bind({});
    SmallPrimary.args = {
      text: "Submit",
      variant: ButtonVariant.PRIMARY,
      size: ButtonSize.SMALL,
    };
    
    export const MediumPrimary = Template.bind({});
    MediumPrimary.args = {
      text: "Submit",
      variant: ButtonVariant.PRIMARY,
      size: ButtonSize.MEDIUM,
      type: "button",
    };
    
    export const MediumSecondary = Template.bind({});
    MediumSecondary.args = {
      text: "Submit",
      variant: ButtonVariant.SECONDARY,
      size: ButtonSize.MEDIUM,
      type: "button",
    };
    
    export const LargeTertiary = Template.bind({});
    LargeTertiary.args = {
      text: "Submit",
      variant: ButtonVariant.TERTIARY,
      size: ButtonSize.LARGE,
      type: "button",
    };
    


    실행하면 다음 목록이 표시됩니다Storybook.



    이 게시물의 초기 스크린샷에 포함된 내용을 완료하려면 다음도 추가하세요.

    // Button.stories.tsx
    
    export const All = () => {
      return (
        <div className="flex gap-6 items-start flex-col" style={{ width: "500px" }}>
          <div className="flex gap-2 items-start justify-between w-full">
            <Button
              text={"Primary Small"}
              variant={ButtonVariant.PRIMARY}
              size={ButtonSize.SMALL}
            ></Button>
            <Button
              text={"Primary Medium"}
              variant={ButtonVariant.PRIMARY}
              size={ButtonSize.MEDIUM}
            ></Button>
            <Button
              text={"Primary Large"}
              variant={ButtonVariant.PRIMARY}
              size={ButtonSize.LARGE}
            ></Button>
          </div>
          <div className="flex gap-2 items-start justify-between w-full">
            <Button
              text={"Secondary Small"}
              variant={ButtonVariant.SECONDARY}
              size={ButtonSize.SMALL}
            ></Button>
            <Button
              text={"Secondary Medium"}
              variant={ButtonVariant.SECONDARY}
              size={ButtonSize.MEDIUM}
            ></Button>
            <Button
              text={"Secondary Large"}
              variant={ButtonVariant.SECONDARY}
              size={ButtonSize.LARGE}
            ></Button>
          </div>
          <div className="flex gap-2 items-start justify-between w-full">
            <Button
              text={"Tertiary Small"}
              variant={ButtonVariant.TERTIARY}
              size={ButtonSize.SMALL}
            ></Button>
            <Button
              text={"Tertiary Medium"}
              variant={ButtonVariant.TERTIARY}
              size={ButtonSize.MEDIUM}
            ></Button>
            <Button
              text={"Tertiary Large"}
              variant={ButtonVariant.TERTIARY}
              size={ButtonSize.LARGE}
            ></Button>
          </div>
        </div>
      );
    };
    



    문제 해결



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

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


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

    좋은 웹페이지 즐겨찾기