티스토리 뷰

Problem

  • 디자인 시스템 구축을 위한 UI 프로젝트의 개발을 진행.
  • 최초 개발 시 컴포넌트별 색상의 변경이 있을 것이라는 고려는 없는 상태로 개발 진행하여 version1에서 지원해야 할 컴포넌트들이 개발됨.
  • light 테마만 지원하는 프로젝트가 개발됨

Use case

  • 신규 개발 프로젝트에서 디자인 컴포넌트를 제공하기 위해 개발 하던 도중 고객사의 요청이 다크 테마를 지원해야 된다고 하여 디자인이 변경됨
  • 따라서 기존에 개발된 컴포넌트의 색상때문에 이용할 수 없는 상황이 발생함.
  • 이용할 수 있도록 컴포넌트의 테마를 주입하는 기능이 필요함.

Condition

  • Dark 테마를 지원해야 함.
  • 고객사에서 요청하는 프로젝트의 Dark테마 Color set과 추후 사내 플랫폼에서 사용할 Dark테마의 Color set이 다름
  • 단순히 정적인 light 테마, Dark 테마를 지원하는 것이 아닌 custom 테마를 생성하여 주입할 수 있는 기능이 필요함.

Develop Considerations

  • React를 사용한 컴포넌트
  • sass module을 사용하여 개발이 된 상태이며, styled-component 또는 emotionjs로 마이그레이션 할 시간적 여유가 없는 상황(정확히는 마이그레이션 할때 필요한 시간을 예측하기가 어려웠다.)
  • 각 컴포넌트 별 사용하는 색상이 정해져 있는 상태이며, 특정 컴포넌트만 그 색상을 바꿀 수 있어야 한다.

위의 고려사항에 따라 Context API를 이용한 방법

  • 테마 상태를 관리하는 전역 상태 관리 시스템이 필요함
    • React contextAPI를 이용
  • 컴포넌트 별 사용할 색상 타입을 정의한다.
  • UI 프로젝트에서 제공하는 Provider를 다른 프로젝트에 지원
    • Provider에 UI 프로젝트에 주입 될 color set을 생성한다.
  • Provider에는 현재 선택된 theme와 theme의 color set을 파싱하여 scss에 넘겨준다.
    document.documentElement.style.setProperty('--color', '#ffffff');
  • scss는 var 를 이용하여 색상을 받고 컴포넌트에 뿌려준다.
  • UI 프로젝트에서 테마를 변경할 수 있는 hooks를 제공한다. - useTheme

발생된 문제점

  • 최초 실행 시 깜빡임 현상이 있다.
    • useEffect에서 파싱 및 생성을 하여 scss에 주입하므로 최초에는 색상이 없는 상태
  • default로 설정된 기본 테마가 아닌 커스텀 테마로 설정
    • 위와 동일한 문제로 커스텀 테마로 띄울 경우 기본 테마로 설정된 색상이 보여진 후 커스텀 테마로 넘어갈 것이며 깜빡임 문제가 있다.

고려한 해결 방법

해결 방법1

  • Provider에서 완전히 계산이 완료 되기 전까지 display: none; 으로 설정한다.
  • 테마에 대한 계산 완료 후 display: block; 으로 변경하여 화면에 띄운다.
  • 문제점
    • 최초 렌더링 시 테마를 계산한 후 화면에 출력하므로 계산할 테마 색상이 많아질수록 느려진다.
    • transition이 걸려져 있는 경우 여전히 깜빡임 현상이 발생한다.

해결 방법2

  • emotionjs를 도입한다.
  • emotionjs를 도입하여 색상 부분만 emotionjs로 스타일을 주입한다.
  • 문제점
    • 위에서 작성했듯 작업 소요시간이 예측이 되지 않는다.

해결 방법3

  • 우선 순위가 낮은 css 변수를 지원하며 css에서 직접 색상을 주입할 수 있도록한다.
  • 각 컴포넌트는 기본 제공 되는 css 변수를 사용하여 색상을 표현한다.
  • Provider가 필요 없어지고 테마의 계산이 필요 없어진다.
  • UI 프로젝트에서 제공하는 CSS를 사용하는 곳에서 우선순위가 높은 공간에서 색상을 재정의 한다.
  • 단점
    • 컴포넌트 사용 시 러닝 커브가 추가적으로 발생한다.
    • css 변수를 제공할 문서가 따로 필요하다.

Solution

  • 위의 해결 방법 중 3번을 선택했다.
  • sass module만을 쓰는 형태로, 렌더링 시 깜빡거림에 대한 이슈가 없다.
  • 컴포넌트에서 사용하는 css에 css 변수를 명시하고 사용한다.
$background-color: var(--bg-color, #ffffff);
.component {
  background-color: $background-color;
}
  • 위의 코드와 같이 사용한다면 프로젝트에서 --bg-color를 선언한 후 색상을 외부에서 자유롭게 변경할 수 있다.
:root {
  --background: #000000;
}

body {
  --background: #ffffff;
}
  • 위와 같이 우선순위를 조절할 수 있다.
  • 또한 컴포넌트 상위에 변수를 덮어씌워 특정 컴포넌트만 색상을 변경할 수 있다.

이와 같이 CSS에서 커스텀 테마를 적용할 수 있을 뿐만 아니라 특정 컴포넌트만 색상을 다르게 적용할 수 있는 등의 자유도 또한 부여할 수 있게 되었다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함