Atomic Pattern 도입기

아토믹 패턴의 도입과 성찰
강석우's avatar
Feb 01, 2024
Atomic Pattern 도입기

서론

코딩을 하다보면 "어 이건 스타일이 같은 코드인데 복붙을 해서 해야하네", "좀 더 편하게 스타일을 코딩할 수 없을까" 라는 생각이 들 때가 많다.
사실 마음의 양심을 살짝만 덜어낸다면 그냥 복붙을 하고 넘어갈 수도 있지만
효율성, 가독성이 더 높은 개발을 위해서 아토믹 패턴을 도입하게 되었다.

아토믹 패턴

아토믹 디자인은 인터페이스 디자인 시스템을 더 의도적이고 계층적으로 만들기 위해 함께 작동하는 다섯 가지 구별된 단계로 구성된 방법론이다.
아토믹 패턴은 아래와 같이 다섯 단계로 구성되어있다.

Atoms

우리의 인터페이스의 atom을 모든 사용자 인터페이스를 구성하는 기본적인 구성 요소로서의 역할로 한다. 이러한 원자에는 기본 HTML 요소가 포함되어 있으며, 이들은 더 이상 기능을 갖지 않게 되지 않는 한 더 이상 분해될 수 없는 것들이며, 이러한 HTML 요소에는 폼 레이블, 입력 필드, 버튼 등이 포함된다.

Molecules

인터페이스에서 molecule은 비교적 간단한 UI 요소의 그룹으로, 함께 기능하는 단위로 작동한다. 예를 들어, 폼 레이블, 검색 입력, 버튼이 함께 모여 검색 폼 분자를 생성할 수 있다.
간단한 구성요소를 만들어야 단일 책임 원칙을 준수할 수 있다.

Organisms

Organisms는 molecule, atom 및/또는 다른 organism의 그룹으로 구성된 비교적 복잡한 UI 구성 요이다. 이러한 organism은 인터페이스의 구별된 섹션을 형성한다.
헤더가 대표적인 organism의 예시이다.

Templates

템플릿은 컴포넌트를 레이아웃에 배치하고 디자인의 기본 컨텐츠 구조를 명시하는 페이지 수준의 객체이다.
템플릿의 중요한 특징은 페이지의 최종 콘텐츠가 아닌 페이지의 기본 콘텐츠 구조에 중점을 둔다는 것이다.

Pages

페이지는 실제 대표 콘텐츠가 들어간 템플릿의 구체적인 인스턴스로, UI가 실제 대표적인 콘텐츠와 함께 어떻게 보이는지를 보여준다.

자료 출처 : https://atomicdesign.bradfrost.com/chapter-2/


커스텀 아톰

스타일과 html 을 한번에 사용하기 위하여 styled component 를 통해
style의 확장이 가능한 atom들을 만들어보았다.

기존의 구조로 가게되면

<StTest>
    <textarea classname="testTextArea"/>
</StTest>

const StTest = styled.div`
  .testTextArea{
     width : 280px;
     height : 50px;
     font-size : 18px;
     font-family : "light"
   }
`;

위와 같이 모든 컴포넌트 또는 페이지들에 styled-component를 선언해주어야 한다.

하지만 커스텀 아토믹 패턴을 사용하면 아래와 같이 props 형태로 스타일의 인자들을 넘겨주어 스타일을 관리하게 된다.

<div>
  <TextArea 
    width={280}  
    height={50}
    fontSize={18}
    fontFamily='light'
  />
</div>

타입스크립트로 작성을 하게되면 TextArea의 속성은 다음과 같다.

import React, { forwardRef } from "react";
import { styled } from "styled-components";

interface TextProps {
  textRef?: React.RefObject<HTMLTextAreaElement>;
  width?: string;
  height?: number;
  placeholderText?: string;
  fontSize?: number;
  fontcolor?: string;
  placeholdercolor?: string;
  padding?: string;
  borderradius?: number;
  border?: string;
  type?: string;
  value?: string;
  onblur?: () => void;
  onchange?: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
}

const TextArea = forwardRef<HTMLInputElement, TextProps>((props) => {
  return (
    <StInput
      value={props.value}
      ref={props.textRef}
      width={props.width}
      height={props.height}
      fontSize={props.fontSize}
      placeholdercolor={props.placeholdercolor}
      placeholder={props.placeholderText}
      padding={props.padding}
      borderradius={props.borderradius}
      border={props.border}
      type={props.type}
      onChange={props.onchange}
      onBlur={props.onblur}
    />
  );
});

const StInput = styled.textarea<TextProps>`
  width: ${(props) => props.width};
  min-height: ${(props) => props.height}px;
  font-size: ${(props) => props.fontSize}px;
  font-family: "regular";
  padding: ${(props) => props.padding};
  outline: none;
  box-sizing: border-box;
  border-radius: ${(props) => props.borderradius}px;
  border: ${(props) => props.border};
  resize: none;
  &::placeholder {
    color: ${(props) => props.placeholdercolor};
    font-family: "light";
  }
`;

export default TextArea;

처음 커스텀아토믹 패턴을 사용하기 시작한다면
div, br, input, img 등 초기 세팅을 위해 작업하는 시간이 많이 들게 되지만 세팅을 잘 해놓고 사용하기 시작한다면 든든한 아군이 되어준다.

커스텀 아토믹의 장점

  • 라이브러리를 매번 선언해줄 필요가 없다.

  • 코드 가독성이 좋아진다.

  • 코드 작성 속도가 빨라진다.

  • 실수가 줄어든다.

  • 재사용성이 올라간다.

  • 확장성이 뛰어나다.

  • 불가피하게 html이 길어질 때 스타일을 보기 쉽다.

고려해야할 점

  • 내가 만든 요소를 어디까지 쓸수 있게 만들것인지 고려해야한다.

    • ex) width 의 경우 typescript 를 사용하면 number로 지정해줄수 있다.
      하지만 width는 string으로 "100%"를 사용하게 되는경우가 많은데 이러한 타입을 정해줄때 어디까지 허용해줄 것인가를 정해야한다.

  • 타입스크립트로 작성을 해야만 한다.

    • 사실 타입스크립트로 작성을 하지않아도 동작하지만 속성값의 정확한 명칭을 정확하게 직접 치는게 굉장히 어렵기 때문에 타입을 지정해주고 속성을 명시해주자.

  • 생각보다 자잘한 css까지 입력을 해주어야 한다.

    • 위와 같은 커스텀 아토믹 패턴은 정말 내가 정해준 css까지만 사용을 할 수 있기 때문에 만약 설정되어있지 않은 css가 많이 필요하다면 위의 atom을 사용하기 보다는 하나를 새로 만들어서 개별 컴포넌트로 사용하는것도 좋다.

  • 반응형에 대한 고민을 많이 해야한다.

    • div 요소는 생각보다 많은 css가 들어갈 수 있기 때문에 정말 많은 속성이 들어가게 된다. 게다가 적용이 될지 안될지도 모르는 반응형이 들어가게 된다면 속성이 66개까지 들어가는 atom도 있었다.

  • 코드 작성 속도, 재사용성, 확장성이 뛰어난건 알겠다. 하지만 정말 성능적으로 좋을까??

    • 커스텀 아톰을 작성하며 가장 고민했던건 '과연 정말 성능이 구려지지 않을까?' 였다.
      사실 근본적으로 본다면 아톰을 사용할때마다 사용하지 않는 스타일들이 적용되는 셈인데 성능에 영향이 없는지 나중에 테스트를 해봐야 할 것 같다.

Share article

석우의 개발블로그