HomeFeedAbout

디자인 시스템 만들기 - 컴포넌트 만들기

김성현 1개월 전
React디자인 시스템컴포넌트

이틀 간 컴포넌트들을 새로 만들었습니다.

얼마 전에 만든 백오피스 UI 라이브러리를 막상 사용해보니 너무 불편했어요. 수정 사항이 생기면 하루에도 수십번씩 빌드, 업데이트를 해야 했거든요. 마침 새로운 웹앱 프론트엔드를 처음부터 개발해야 하는 상황이라, 이틀 간 컴포넌트 공장장이 되었습니다. 고민하면서 느꼈던 자잘한 팁을 공유해보려고 해요.

디자인 토큰 수집하기

먼저, 스타일링의 기반이 되는 색상 토큰을 정리했어요. 저희 회사엔 아직 디자이너분이 안 계셔서 어떻게 할 지 고민하던 중, 원티드 팀에서 공개한 디자인 시스템을 알게 됐어요. 배운 것 중 하나가 색상 토큰을 Atomic과 Semantic 계층으로 나누는 방식이었어요. Atomic은 해시태그#FFFFFF 같이 헥사값으로 구성된 팔레트 자체를 의미하고, 실제 컴포넌트에서는 primary.strong처럼 의미가 부여된 Semantic 토큰을 참조해요. 이때 primary.strong은 해시태그#1E90FF 가 아니라 palette.blue[50]같은 Atomic 토큰을 참조해요. 이렇게 추상화하면 브랜드 컬러가 바뀌더라도 손쉽게 전체 색상을 변경할 수 있어요.

컴포넌트 레시피 만들기

평소 즐겨 사용하는 Vanilla-Extract (CSS)의 recipe 패키지를 알게 됐어요. 같은 Tag 컴포넌트이지만 조금씩 UI가 다를 때 basic, recommand 등으로 나눠 recipe에 정의해두면 컴포넌트가 훨씬 간결해져요. 버튼도 recipe 기반으로 만들고나서, BadgeButton, BottomCTA처럼 한 번 더 추상화 해줬어요. 이정도면 거의 CDD(CSS Driven Development)가 아닌가 하는 생각이 들었습니다 ㅋㅋ

굳이 복잡하게 만들지 않기

성능 향상을 위해 최대한 CSS와 코드를 줄이는 걸 목표로 했어요. 웬만한 건 그냥 만들고 사진의 ContentCard처럼 다양하게 조합이 가능한 경우에만 컴포넌트 컴파운드 패턴을 사용해서 구현했어요.

interface ContentCardHeaderProps {
  leadingIcon?: React.ReactNode;
  title: string;
  description?: string;
}

export const ContentCardWrapper = ({
  children,
}: {
  children: React.ReactNode;
}) => {
  return <div className={container}>{children}</div>;
};

export const ContentCardHeader = ({
  leadingIcon,
  title,
  description,
}: ContentCardHeaderProps) => {
  return (
    <div className={headerSection}>
      <div className={headerTitleSection}>
        {leadingIcon}
        <p>{title}</p>
      </div>
      {description && <p className={headerDescription}>{description}</p>}
    </div>
  );
};

export const ContentCardBody = ({
  children,
}: {
  children: React.ReactNode;
}) => {
  return <div className={bodySection}>{children}</div>;
};

export const ContentCard = {
  Wrapper: ContentCardWrapper,
  Header: ContentCardHeader,
  Body: ContentCardBody,
};

충분히 테스트하고 배포하기

무작정 npm에 배포해버리니까 관리가 너무 힘들었기 때문에, 이제 shared에 놓고 충분히 테스트하고 나중에 배포해보려고 해요.

(컴포넌트 디자인은 서울대 삶향상기술 연구실에서 컨설팅해주신 화면 기획서를 바탕으로 구현했습니다)

다음 할 일: UI 테스트 적용하기

오늘 TeoConf에 참여해서 너무 재밌는 시간을 보냈습니다. 뒷풀이 때 위시캣 프론트엔드 FE 리드분과 얘기를 나누면서 컴포넌트 테스트를 어떻게 하시는지 궁금했어요. 기본적으로 TDD로 개발을 하기 때문에 UI에도 테스트 코드를 작성한다고 하시더라구요.
프론트엔드에서 TDD가 가능하다는 것을 보여드립니다. (라이브 코딩) 영상을 추천해주셔서, 당분간은 컴포넌트들을 더 만들면서 테스트를 함께 적용할 예정이에요.