Skip to content

Atomic Design Storybook

ypd01018 edited this page Dec 21, 2020 · 2 revisions

Atomic Design을 도입하게 된 이유

슬랙을 구현하면서 프로필 이미지나 메시지, 입력창 등 일관된 디자인의 컴포넌트들이 많다고 생각했습니다. 또한 재사용 가능한 컴포넌트를 만들면 불필요한 코드 중복을 줄이고, 개발 생산성을 높일 수 있다고 판단했기 때문에 Atomic Design을 도입하기로 했습니다.

Atomic Design이란?

Atomic Design이란 원자가 결합해서 분자가 되는 것처럼 단계를 나눠 작은 컴포넌트를 만들고, 그것들을 결합해 조금 더 큰 단위의 뷰를 만드는 방법론이며, 5개의 구분된 단계가 있습니다.

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/a94cd976-7d0e-4a63-8268-24d9c1adaee7/Untitled.png

출처: https://brunch.co.kr/@ultra0034/63

| Atoms(원자)

원자는 물질의 기본 구성 요소로, label, input, button과 같은 HTML tag입니다.

| Molecules(분자)

분자는 원자들이 함께 결합한 것이며, 화합물의 가장 작은 기본단위입니다. 분자들은 그 자체의 특성이 있습니다.

| Organisms(유기체)

유기체는 비교적 복잡하며 인터페이스에서 구분된 영역을 형성하는 서로 결합되어 있는 분자 그룹입니다.

| Templates

템플릿은 주로 페이지를 구성하기 위해 서로 묶인 유기체 그룹으로 구성되며, 디자인 확인 및 레이아웃 동작을 볼 수 있습니다.

| Pages

페이지는 템플릿의 특정 인스턴스로, 사용자가 보는 디자인을 정확하고 구체적으로 구현합니다.

Storybook

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/f71b46f2-a5d9-43ee-8a3e-27d213730de9/Storybook.png

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/7f3c8a4a-8852-4d8c-b801-9597e469f341/Untitled.png

Atomic Design / Storybook 도입 과정

| FE 디렉터리 구조

리액트를 사용해서 단일 페이지 애플리케이션(SPA)을 구현하는데, Atomic Design을 적용해 계층 구조를 기반으로 컴포넌트를 작성하기 위해서 atoms - molecules - organisms - templates - pages 로 FE 디렉터리 구조를 잡았습니다.

client
├── env
├── public
│   └── imgs
└── src
    ├── common
    │   ├── constants
    │   ├── socket
    │   │   ├── emits
    │   │   └── types
    │   ├── store
    │   │   ├── actions
    │   │   ├── reducers
    │   │   ├── sagas
    │   │   └── types
    │   ├── theme
    │   └── utils
    ├── components
    │   ├── atoms
    │   ├── molecules
    │   ├── organisms
    │   └── templates
    ├── pages
    └── shared

| Atomic Design의 각 단계를 나누는 기준에 대한 고민

처음에는 Atomic Design을 도입했을 때 어떤 기준을 가지고 각 단계를 나눠서 구현해야 할지 고민했었습니다.

페이지별로 필요한 컴포넌트들을 나누는 게 좋겠다고 판단을 해서 채팅방 페이지, 채널 리스트 페이지 등 화면 단위로 요구사항을 먼저 나누고, 그 안에서 채널 검색창과 채널 리스트 등 보이는 큼지막한 단위로 Organisms를 정했습니다.

정해진 Organisms를 구성하고 있는 컴포넌트들을 잘게 나눠서 Atoms들을 먼저 구현하고, Atoms들이 모여서 Molecules가 되고, Molecules가 모여서 Organisms가 되도록 기준을 잡았습니다.

| ex) ActiveProfileImg 컴포넌트가 만들어지는 과정

ActiveProfileImg 컴포넌트는 Side Bar의 DM 목록과 화면 우측 상단 로그인된 사용자의 상태를 나타내는 부분에 사용되는 컴포넌트입니다.

먼저 `atoms`에 가장 간단한 ActiveLight 컴포넌트와 ProfileImg 컴포넌트 구현했습니다.
/* client\src\components\atoms\ProfileImg\ProfileImg.tsx */

import React from 'react';
import styled from 'styled-components';
import Logo from '@imgs/logo.png';
import { color } from '@theme/index';

interface ProfileImgProps {
  size?: 'small' | 'medium' | 'large';
  isHover?: boolean;
  src?: string;
}

// 생략

const ProfileImg: React.FC<ProfileImgProps> = ({ size = 'medium', isHover = false, src = Logo, ...props }) => {
  return (
    <ProfileImgContainter size={size} isHover={isHover} {...props}>
      <Img size={size} isHover={isHover} src={src}></Img>
    </ProfileImgContainter>
  );
};

export { ProfileImg, ProfileImgProps };

구현한 컴포넌트의 디자인을 Storybook을 통해 쉽게 확인하기 위해 ActiveLight.stories와 ProfileImg.stories 작성했으며, 이를 통해 각 컴포넌트의 디자인을 수정하면서 효율적으로 개발을 했습니다.

/* client\src\components\atoms\ProfileImg\ProfileImg.stories.tsx */

import React from 'react';
import { Story, Meta } from '@storybook/react/types-6-0';
import { ProfileImg, ProfileImgProps } from './ProfileImg';

export default {
  title: 'atom/ProfileImg',
  component: ProfileImg
} as Meta;

const Template: Story<ProfileImgProps> = (args) => <ProfileImg {...args} />;

export const LargeProfileImg = Template.bind({});
LargeProfileImg.args = {
  size: 'large'
};

export const MediumProfileImg = Template.bind({});
MediumProfileImg.args = {
  size: 'medium'
};

export const SmallProfileImg = Template.bind({});
SmallProfileImg.args = {
  size: 'small'
};

구현된 ActiveLight 컴포넌트와 ProfileImg 컴포넌트를 활용해서 molecules에 ActiveProfileImg 컴포넌트를 구현했습니다. 마찬가지로 ActiveProfileImg.stories을 작성해 Storybook을 통해 디자인 수정 및 테스트를 진행했습니다.

느낀 점

처음에는 Atomic Design의 각 단계를 어떤 기준으로 나눠야 할지 고민이 많았는데, 직접 가장 작은 컴포넌트부터 제작하고, 제작된 컴포넌트들을 합쳐서 더 큰 뷰를 구성하는 과정에서 블록을 조립해나가듯 합쳐가는 과정이 재미있게 느껴졌습니다.

또한, 모달창이나 버튼과 같이 공통으로 사용되는 컴포넌트들을 만들어 재사용함으로써 코드 중복을 줄이고 생산성을 높일 수 있었으며, Storybook 또한 Atoms나 Molecules 같은 작은 단위의 컴포넌트들을 제작할 때 많은 도움이 되었습니다.

마치며

Atomic Design을 도입하면서 화면 전체에서부터 아래로 내려가며 디자인을 설계하던 기존 방식과는 다르게 작은 컴포넌트부터 제작함으로써 훨씬 체계적으로 페이지를 구현할 수 있었습니다. 또한 React가 컴포넌트를 기반으로 하다 보니 Atomic Design과 잘 어울린다고 생각했습니다.

한편으로 Atomic Design의 각 단계를 어떤 기준으로 나눠야 할지 고민하면서 꼭 5단계가 아니더라도 프로젝트의 규모나 필요에 따라서 단계를 줄여서 사용해볼 수 있을 것 같다는 생각이 들었습니다. 실제로 기업에서도 Atomic Design을 부분적으로 도입해 프로젝트에 맞게 전략적으로 단계를 나누는 경우가 있다고 들었습니다.

Atomic Design의 장점을 최대한으로 가져가기 위해 어떻게 하면 재사용 가능한 컴포넌트를 만들 수 있을지, 단계는 어떻게 나눠야 할지 고민할 수 있었던 좋은 시간이었으며, 앞으로 Atomic Design을 적용해야 할 일이 있다면 이번 프로젝트를 하면서 느꼈던 고민이 많은 도움이 되리라 생각됩니다.

Clone this wiki locally