-
Notifications
You must be signed in to change notification settings - Fork 6
Atomic Design Storybook
Atomic Design을 도입하게 된 이유
슬랙을 구현하면서 프로필 이미지나 메시지, 입력창 등 일관된 디자인의 컴포넌트들이 많다고 생각했습니다. 또한 재사용 가능한 컴포넌트를 만들면 불필요한 코드 중복을 줄이고, 개발 생산성을 높일 수 있다고 판단했기 때문에 Atomic Design을 도입하기로 했습니다.
Atomic Design이란?
Atomic Design이란 원자가 결합해서 분자가 되는 것처럼 단계를 나눠 작은 컴포넌트를 만들고, 그것들을 결합해 조금 더 큰 단위의 뷰를 만드는 방법론이며, 5개의 구분된 단계가 있습니다.
출처: https://brunch.co.kr/@ultra0034/63
| Atoms(원자)
원자는 물질의 기본 구성 요소로, label, input, button과 같은 HTML tag입니다.
| Molecules(분자)
분자는 원자들이 함께 결합한 것이며, 화합물의 가장 작은 기본단위입니다. 분자들은 그 자체의 특성이 있습니다.
| Organisms(유기체)
유기체는 비교적 복잡하며 인터페이스에서 구분된 영역을 형성하는 서로 결합되어 있는 분자 그룹입니다.
| Templates
템플릿은 주로 페이지를 구성하기 위해 서로 묶인 유기체 그룹으로 구성되며, 디자인 확인 및 레이아웃 동작을 볼 수 있습니다.
| Pages
페이지는 템플릿의 특정 인스턴스로, 사용자가 보는 디자인을 정확하고 구체적으로 구현합니다.
Storybook
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을 적용해야 할 일이 있다면 이번 프로젝트를 하면서 느꼈던 고민이 많은 도움이 되리라 생각됩니다.