본문 바로가기

Issues/frontend

(디자인 시스템) Storybook 과 TailwindCSS 디자인 시스템 구축

 

최근 개발팀의 인원이 증가하고, 버전 관리가 복잡해짐에 따라 프론트엔드 개발에서 공통적인 요소를 사전에 정의하고 활용하는 필요성이 더욱 커졌습니다.

 

현재 프론트엔드 개발자는 총 5명, 백엔드 개발자는 3명으로 구성되어 있으며, 여러 버전을 동시에 개발해야 하는 상황에서 효율적인 협업과 일관성 유지가 중요한 과제로 대두되었습니다. 이러한 필요성을 해결하기 위해 디자인팀과의 협의를 통해 디자인 시스템을 도입하기로 결정했습니다.

 

처음에는 디자인 시스템에 디자인 토큰 개념까지 적용해 프로젝트에 사용하고자 했으나, 초기 도입 시점에서는 예상보다 큰 실익을 얻지 못한다고 판단했습니다. 대신 TailwindCSS를 기반으로 한 Storybook을 설정하여 가장 작은 단위의 요소를 공통으로 정의하고, 점진적으로 디자인 시스템의 범위를 확장해 나가기로 했습니다. 이를 통해 빠르게 일관된 UI를 구축하면서도 디자이너와 개발자 간의 협업 효율성을 극대화할 수 있게 되었습니다.

 

1. 기본 디자인 컴포넌트 설정

 

디자인팀과 개발팀은 Figma를 통해 제공된 기본 컴포넌트들을 기반으로 디자인 시스템을 정의했습니다. 빠르고 효율적인 시스템 구축과 프로젝트 적용을 목표로 하여, 최소한의 단위로 컴포넌트를 설정했으며, 초기 정의된 컴포넌트 목록은 다음과 같습니다:

 

Header, Base, Dot, Scale, Tab, Button, Input, InputDropdown, DatePicker, ToothNumber

 

이 컴포넌트들은 Storybook을 통해 다양한 상태와 변형(variants)을 체계적으로 관리하고, 팀 내에서 쉽게 공유할 수 있도록 하였습니다. Storybook은 각 컴포넌트를 독립적으로 테스트하고, 여러 스토리를 통해 다양한 상태와 스타일을 시각적으로 확인할 수 있는 환경을 제공합니다. 이를 통해 개발자들은 일관성 있는 디자인을 유지하면서도 재사용 가능한 컴포넌트를 효율적으로 관리하고 프로젝트에 적용할 수 있습니다.

 

이 접근 방식은 컴포넌트의 상태 변화와 변형을 시각적으로 확인하고, 개발과 디자인 간의 커뮤니케이션을 개선하여, 궁극적으로 일관성 있는 사용자 경험을 제공하는 데 기여합니다.

 

2. 컴포넌트 디자인 요소 추출

 

Button 컴포넌트는 대부분의 UI에서 중요한 역할을 담당하기 때문에, 이를 디자인 시스템의 첫 번째 구성 요소로 정의하였습니다.

디자인팀에서 정해준 Button 컴포넌트의 variant는 "primary"와 "secondary" 두 가지입니다.

 

Button 컴포넌트에서 추출한 주요 props는 다음과 같습니다.

 

(1) 버튼 크기 및 폰트 크기

designSize prop을 사용하여 버튼의 크기와 폰트 크기를 조절합니다. 버튼의 너비와 높이는 designSize에 따라 달라지며, 다양한 화면 크기에서도 일관된 버튼 스타일을 유지할 수 있도록 설계하였습니다. 지원하는 크기는 xssmmdlgxl2xl 입니다.

 

(2) 버튼 라벨

label prop을 사용하여 버튼의 텍스트를 정의합니다. 이는 버튼의 주요 내용을 전달하는 역할을 합니다.

 

(3) 위험 표시

danger prop은 boolean 값을 가지며, 버튼이 위험한 작업을 수행할 수 있음을 사용자에게 시각적으로 알리는 역할을 합니다. 예를 들어, 삭제와 같은 위험한 작업의 경우 danger를 true로 설정하여 버튼 스타일을 경고 색상으로 변경할 수 있습니다.

 

(4) 아이콘 정보

아이콘은 버튼에 시각적 요소를 추가하여 더 나은 사용자 경험을 제공합니다. iconInfo prop은 "src"와 "alt" 속성을 포함하여 아이콘의 경로와 대체 텍스트를 정의합니다.

 

(5) 아이콘 위치 설정

아이콘의 유무 및 위치는 사용자 경험에서 중요한 요소 중 하나입니다. 이를 위해 icon prop을 추가하여 아래와 같이 세 가지 경우를 지원합니다.

 

** 아이콘 없음: 기본 버튼 스타일.

** 아이콘 앞에 위치(leading): 버튼 텍스트 앞에 아이콘이 위치하는 경우.

** 아이콘 뒤에 위치(trailing): 버튼 텍스트 뒤에 아이콘이 위치하는 경우.

 

(6) 버튼 활성화 상태

버튼의 활성화/비활성화를 제어하기 위해 disabled prop을 추가하였습니다. 사용자가 특정 작업을 수행하지 못하도록 하기 위해 disabled 상태를 명확히 표시하며, 이로 인해 사용자는 버튼을 사용할 수 없는 경우를 직관적으로 알 수 있습니다.

 

2.1 Storybook을 통한 버튼 스토리 정의

Storybook을 사용하여 Button 컴포넌트의 다양한 변형을 정의하고, 이를 통해 팀원들이 개발 중에도 각 상태를 쉽게 테스트할 수 있도록 하였습니다. 스토리북은 해당 컴포넌트 안에 다양한 **다양한 스토리 변형(variants)**을 설정할 수 있다. 각각의 스토리는 컴포넌트의 다른 상태나 스타일을 보여주는데 사용한다.

 

export const Primary: Story = {
  args: {
    primary: true,
    label: "Button",
  },
};

export const Secondary: Story = {
  args: {
    label: "Button",
  },
};

 

 

라벨이나 danger 등은 DesignButton에서 상속을 받아 실제 서비스 컴포넌트에서 구현할 수 있다.