[DDD-Presen] 공통 컴포넌트 실패에 대한 임시방안

조민호·2024년 7월 2일
1

[DDD-Presen] 공통 컴포넌트의 개념과 우리팀에서 의도한 방향
에서 실제 우리 프로젝트에 도입해볼 공통 컴포넌트 시스템에 대한 컨셉을 알아봤었다.

하지만 앞서 설명했듯이 동아리 활동 후반기쯤에 프로젝트의 디자인 시스템을 제외하기로 했기 때문에
아쉽게도 해당 시스템은 사용할 수가 없었다.

이는 개발팀 쪽에서도 상당한 변수였다. 몇 주동안 만들어가던 기존 시스템을 전혀 사용하지 못하게 된 것이기 때문이다.


어떻게든 기존에 만들어 두었던 내용들을 재사용하기 위해 다음과 같은 선택을 했다.

  1. 기존의 방식인 props만 조합해서 사용하는 것을 포기한다.
    대신, 스타일이 공통되는 요소들에 일괄 적용하는 클래스명을 따로 만들어서 사용한다.

  2. 위의 클래스명의 스타일에, 기존의 공통 컴포넌트 시스템에서 만들었던 크기나 색상에 대한 각각의 값들을 css변수로 추출해서 사용하는 것이다.

    ( 이 프로젝트는 .module.scss 형태로 스타일을 하고 있었으므로 scss 믹스인으로 변수를 쉽게 만들 수 있었다. )

최대한 기존 시스템의 내용(props 조합을 위해 만들어 두었던 모든 사이즈, 색상 등의 값들)을 그대로 가져가면서,
사용할때 독립적인 props조합이 아닌, (어쩔 수 없이)스타일이 공통된 요소들을 묶어서 일괄 적용하는 방식으로 가는 것이다.

사실 이 방법은 공통 컴포넌트 - 초기 기획 에서 대놓고 "이상적인 방법은 아니다" 라고 말한 방법이었다.


하지만 이상적이지 않을 뿐 잘못된 방법은 아니었을 뿐더러, ( 아무런 시스템 없이 css를 쌩으로 적용하는것 보다야 나은건 맞으니까. )
프로젝트 마감 기한이 코앞으로 다가온 현재 상황에 맞는 가장 합리적인 선택으로써 어쩔 수 없었다.


우리 팀에서 실제로 사용한 사례이다.

1. 공통된 스타일 값들에 대해 변수화를 진행한다.

    /** Color - gray */
    $gray-10: #1e1e1e;
    $gray-9: #393939;
    $gray-8: #4b4b4b;
    $gray-7: #5e5e5e;
    $gray-6: #727272;
    $gray-5: #868686;
    $gray-4: #9b9b9b;
    $gray-3: #b0b0b0;
    $gray-2: #c6c6c6;
    $gray-1: #dddd;
    $gray-0: #f3f3f3;
    
    /** Color - purple */
    $purple-9: #0000e6;
    $purple-8: #2507eb;
    $purple-7: #4312f0;
    $purple-6: #5a1df8;
    $purple-5: #6822ff; // primary
    $purple-4: #854cff;
    $purple-3: #9f70ff;
    $purple-2: #bc9bff;
    $purple-1: #d7c4fe;
    $purple-0: #f0e7ff;
    
    /** Color - red */
    $red-7: #de3428;
    $red-5: #ff4a2e;
    $red-3: #ef7771;
    
    /** Color - black, white */
    $white: #ffff;
    $black: $gray-10;
    
    /** Color - value */
    $primary: $purple-5;
    $secondary: $gray-6;
    $error: $red-5;
    
    /** Font - Headline */
    $h1: 32px;
    $h2: 24px;
    $h3: 18px;
    $h4: 16px;
    $h5: 14px;
    
    /** Font - Body */
    $font-1: 18px;
    $font-2: 16px;
    $font-3: 14px;
    $font-4: 12px;

2. 공통 컴포넌트에 적용할 믹스인들을 생성한다

    // ### 웹 버튼 기본 사이즈
    @mixin button_size_web_basic {
      width: 227px;
      height: 56px;
      font-size: px-to-rem($h2);
    
      // 내부 글씨 중앙 정렬
      display: flex;
      justify-content: center;
      align-items: center;
      padding-top: 12px;
      padding-bottom: 12px;
      border-radius: 12px;
      cursor: pointer;
    }
    
    // ### 웹 버튼 small 사이즈
    @mixin button_size_web_small {
       ...
    }
    
    // ### 웹 버튼 large 사이즈
    @mixin button_size_web_large {
       ...
    }
    
    // ### 버튼 default 테마
    @mixin button_theme_default {
      background-color: $gray-9;
      color: $white;
      border: none;
      &:hover {
        background-color: $primary;
        cursor: pointer;
      }
      &:active {
        background-color: $gray-9;
        cursor: pointer;
      }
      &:disabled {
        background-color: $gray-3;
        cursor: not-allowed;
      }
    }
    
    // ### 버튼 inverted 테마
    @mixin button_theme_inverted {
      ...
    }
    

3.믹스인을 조합해서 공통된 디자인에 적용할 클래스네임을 생성한다.

    .confirmButton {
      @include button_size_web_basic; // 사이즈
      @include button_theme_default; // 테마
    }
    
    .cancelButton { 
      @include button_size_web_small; // 사이즈
      @include button_theme_lined; // 테마
    }

4. 공통 컴포넌트인 <Button/> 을 생성한다.

<Button/> 컴포넌트 사용은 2가지의 방향성을 가진다

    import { ButtonHTMLAttributes } from 'react';
    
    export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
      // 공통컴포넌트에 사용될 버튼 문구
      _content: string;
    }
    
    const Button = ({ children, className, _content, ...rest }: ButtonProps) => {
      return children ? (
        // 기존 디자인 사용
        <button className={className} {...rest}>
          {_content}
        </button>
      ) : (
        // 예상치 못한 버튼 디자인에 대응
        <button className={className} {...rest}>
          {children}
        </button>
      );
    };
    
    export default Button;
    

1. 공통 컴포넌트로 지정한 버튼을 사용하는 경우

  • className

    공통 컴포넌트의 클래스명을 넘겨준다 ( .confirmButton , .cancelButton 등 )

  • _content

    버튼의 문구로 사용할 문자열을 넘겨준다

2. 공통 컴포넌트로 대응하지 못한 그 외의 버튼을 사용할 경우

  • children

    버튼의 내용으로 사용할 ReactNode를 넘겨준다.

    버튼 내부로 단순 문자열 형태의 문구를 사용할 수도 있고,

    다른 리액트 컴포넌트를 사용할 수도 있기 때문에,{children} 을 넘겨준다

  • className

    직접 디자인을 지정한 클래스명을 넘겨준다

profile
웰시코기발바닥

1개의 댓글

comment-user-thumbnail
2024년 7월 4일

좋은 정보 감사합니다!

답글 달기