와탭 블로그

전체보기

와탭 테마 기능 적용기 - React 환경에서 styled-components 이용하기

2020년 06월 15일

whatap_theme

작업을 하게된 배경

안녕하세요. 저는 와탭랩스에서 프론트엔드 개발을 하고있는 원성철이라고 합니다. 최근 프론트 UI에서는 늦은 시간대에 서비스를 이용하는 사용자나 개인의 취향에 더 맞춰줄 수 있도록 다크 테마를 제공해주는 경우가 많습니다. 저희 와탭에서도 더 많은 사용자분들을 만족시켜드릴 수 있도록 다크 테마와 더 나아가서 개인 커스텀 테마 기능까지 추가 개발했습니다.

SaaS 서비스를 운영하시는 다른 분들께 제 경험이 조금이라도 도움이 될 수 있기를 바라며, 테마 기능 적용기를 시작하겠습니다.

현재 환경 파악

우선 새로운 개발 환경을 만드는 것이 아니라 이미 운영중인 서비스에 기능을 추가해야 하기 때문에 현실적으로 적용 가능한 방법을 찾기 위해, 현재 서비스를 파악할 필요가 있습니다.

저희의 웹 서비스는 javascript의 라이브러리인 React.js를 메인으로 개발을 진행하고 있으며. 각 페이지는 react-router로 라우팅 하고 있으며 과거에 스타일링 모듈로는 scss, css를 이용했으나 현재는 styled-components를 통해서 스타일을 적용하고 있습니다.

styled-components example styled-components 사용 예제

styled-components는 특정 스타일이 적용된 컴포넌트를 만들어주는 모듈이며, 위와 같이 대부분의 부분이 모든 값들을 상수로 이용하고 있습니다.

거기다가 추가로 실제 로직 안에서 컬러값들을 이용하고 있는 경우들도 있습니다.

Code example 코드에서 사용 예제

서비스의 규모가 커지며 이런 코드들이 곳곳에 굉장히 많기때문에 테마를 단번에 적용시키기에는 무리가 있어보입니다.

필요한 것 정리

테마 기능을 만들기 이전에 현재 개발 환경을 대충 파악했으니 현실적으로 테마 기능을 만들기 위해서 어떤 것들이 필요한지 생각해봅니다.

  • 사용중인 컬러 분류, 오브젝트로 정의
    • 굉장히 많은 코드에 많은 컬러를 이용하고 있으니, 페이지에서 사용할 컬러를 분류해서 테마를 적용하기 위해서 중구난방으로 사용중인 컬러를 분류하고, 테마 적용과 일관된 디자인을 위해 컬러 값들을 정해진 키 값과 매핑한 오브젝트를 테마별로 동일한 형태로 만듭니다.
  • styled-components 에서 테마 컬러 사용
    • 거의 모든 dom을 styled-components를 통해 만들고 있기 때문에 styled-components를 사용할 때 위에서 정의한 컬러를 쓸 수 있어야 합니다. (개발 시에 계속 쓰일 것이기 때문에 최대한 쉽고 편하게 쓸 수 있어야 개발시의 스트레스를 줄이고 생산성을 높일 수 있습니다.)
  • 컬러값을 로직 내에서 직접 사용
    • styled-components 에서 뿐만 아니라 여러 모듈에 값을 넘길 때나 많은 로직에서 컬러값을 사용하고 있기 때문에 테마의 컬러값을 쉽게 받아서 사용할 수 있는 방법도 추가해야합니다.
  • 테마 변경, 커스텀 설정 화면 추가
    • 다른 테마로 변경할 수 있는 화면과 커스텀으로 컬러를 지정할 수 화면을 만들어줍니다.
  • 순차적 적용
    • 이미 운영중인 서비스이기 때문에 기존에 사용중인 코드가 굉장히 많은데, 한 번에 모두 바꾸려면 작업량도 굉장히 많고, 버그가 발생할 가능성도 있기 때문에 테마 기능을 부분 부분 적용시켜 나갈 수 있도록 해야합니다.

제작

우선 페이지에서 사용하고 있는 컬러값들에 이름을 붙여서 정리합니다.

arrange theme color 정리된 컬러값

저희 서비스에서 사용하고 있는 컬러들을 사용처별로 분류했으며, 컬러 외에도 box-shadow 같이 테마별로 달라질만한 값들을 함께 정리해서 JSON 오브젝트로 만들었습니다. (개인적으로 테마 작업에서 이 작업이 가장 어려운 작업이라 생각되며, 이부분은 디자이너님께서 힘써주셨습니다. 감사합니다.)

그리고 styled-components에서 해당 값을 사용하기 위해 styled-components의 ThemeProvider 를 이용해줬습니다. 쓰기 편하게 잘 만들어져 있어, 고민을 덜 수 있었습니다.
참고 링크: https://styled-components.com/docs/api#themeprovider

ThemeProvider

ThemeProvider의 theme 라는 프롭으로 값을 전달해주면, styled-components에서 돔을 만들 때 해당 값을 사용할 수 있습니다. 위에서 지정해준 컬러값을 전달해줬습니다.

Apply theme color 지정한 테마 컬러값 사용

styled-components 에서 돔을 만들며, props.theme를 통하여 지정했던 컬러들을 사용할 수 있는 것을 확인할 수 있습니다.

Result of applied color 결과

ThemeProvider에 넘겨준 값을 사용하는 방법은 알았으니, 이제 사용자가 지정한 테마에 따라서 ThemeProvider에 다른 값을 넘겨주기만 하면 styled-component에서의 테마 변경 기능이 완성됩니다.

우선 테마를 변경할 수 있는 ux부터 만들어주도록 하겠습니다. 테마는 모든 화면에서 쓸 수 있는 공통 기능이기 때문에, 헤더에 만들도록 하겠습니다.

header 상단 헤더에서 테마를 선택하는 드롭다운 메뉴

변경했을 때 키 값들은 다음에도 유지할 수 있도록 페이지의 쿠키 값으로 저장했으며, 순차적으로 테마 기능을 적용할 예정이기 때문에, 사용자가 기능 작동 여부를 인지할 수 있도록 테마 지원 여부를 표시했으며, 테마들을 선택할 수 있도록 추가해줬습니다. (빔 프로젝트를 이용했을 때 흐릿한 컬러들이 보이지 않는다는 피드백이 있어, 프레젠테이션 모드를 추가로 만들었습니다.)

Dark theme color 다크 테마 컬러 정의

이제 다크 테마의 컬러를 JSON 오브젝트로 정의하고 ThemeProvider에서 테마를 변경했을 때, 해당 오브젝트를 전달해주기만 하면 컬러가 달라지는 것을 확인할 수 있습니다.

Result Light / Dark 테마 적용 결과

다크 테마를 적용한 방식과 동일한 방법으로 다른 테마들도 추가할 수 있으며, JSON 오브젝트의 키 값을 사용자가 정의한 값으로 수정해서 저장할 수 있게 하면 커스텀 테마 기능도 만들 수 있습니다.

custom theme test 커스텀 테마 설정

테마 컬러값을 지정하는데 모든 선택옵션을 노출하면 커스텀 테마를 적용하는데에 어렵게 느껴질 수 있어, 테마 컬러에서 주요 Key항목만 선별해서 커스텀 테마 설정 화면을 만들었습니다.

먼저 Light와 Dark중에서 베이스가 될 테마를 선택하고 커스텀으로 컬러를 지정하면 해당 테마에 해당 컬러를 덮어씌우는 방식으로 제작했습니다.

apply custom theme 커스텀 테마 적용

default로 커스텀으로 지정한 색상의 키값을 base가 되는 테마에 덮어씌우게 했으며, 특정 색상이 수정되면 같이 수정돼야하는 값들이 있을 수 있어 (버튼의 색상을 수정하면 버튼을 호버했을 때의 색상도 바꿔주는 등) switch case문을 사용하여 그러한 처리를 넣을 수 있는 공간을 미리 비워뒀습니다.

여기까지 styled-components로 만든 돔에 테마를 적용시켰으며, 그 외의 부분에서도 테마의 색상을 이용할 수 있도록 Context를 추가했습니다.

ThemeContext ThemeContext

ThemeContext 라는 context를 만들었으며, 테마의 색상 값들과 기타 개발에 필요한 테마와 관련된 값들을 추가했습니다.

ThemeContext context에 저장된 값 사용
ThemeContext Result context에 저장된 값 사용 결과

context의 값을 정상적으로 불러온 것을 확인할 수 있습니다. (styled-components 에 ThemeConsumer를 통해 ThemeProvider에 넣은 값을 꺼낼 수 있었으나 styled-components v4 부터 지원하여 버전이 맞지 않아 사용하지 못했습니다.)

Theme supported 테마 지원 / 미지원 페이지 관리

그리고 ThemeProvider쪽에는 theme(지정한 테마), invokedTheme(실제 호출되고있는 테마), hasTheme(테마를 가지고 있는지 여부) 이 세가지 값을 통하여 테마 적용 여부를 관리하여 boolean 값인 hasTheme를 통해 hasTheme가 참이면 theme를, 거짓이면 기본 Light(white) 테마를 적용할 수 있도록 하여. 테마 작업이 되지 않은 페이지를 관리할 수 있도록 했습니다.

마무리

그동안 테마 기능을 넣어야지 넣어야지 하면서도, 다른 개발 일정에 밀려 작업을 못하다가 드디어 작업을 하게 되었습니다. 사실 작업만 생각하면 rgb나 hash값을 넣어서 사용하던 색상들에 이름을 붙여서 해당 이름으로 사용하게하는게 전부인 작업이었으나 과거에 테마 기능을 추가하려고 했던 흔적들이 발목을 잡아 시간이 걸리게 되었습니다. 그래도 기술 부채를 조금 청산한 거 같아 기분이 좋습니다 하하.

와탭의 서비스는 고객의 데이터를 시각화 하고있기때문에 많은 차트 종류와 색상이 사용됩니다. 모니터링하는 환경과 목적에 따라서 특정 항목이나 데이터를 더 강조하여 다른 컬러를 사용하고 싶어하시는 분들도 있고, 반대로 덜 강조하고싶은 항목과 데이터들의 컬러를 바꾸고 싶어하시는 분들도 있었습니다. 또한 다양한 디바이스 환경에서 가독성을 높이기위해 컬러들을 조절할 필요도 있었습니다. 이번 테마 기능을 통하여 많은 분들의 니즈를 조금이라도 충족시켰으면 좋겠고, 커스텀 테마같은 기능을 통해 색약을 가지고 계신 분들도 서비스를 원활하게 이용하셨으면 합니다.

앞으로도 더욱 많은 분들께 도움이 될 수 있도록 노력하는 와탭의 프론트 개발자가 되겠습니다. 마지막으로 실제 서비스에 적용된 화면 보여드리고 글 마치도록 하겠습니다.

light, dart, custome theme

다양한 환경에서도 데이터를 선명하게 볼 수 있는 와탭 테마기능을 사용해보세요.

와탭 무료로 시작하기
seoungchul_won
원성철(scwon@whatap.io )
Development TeamFront-End Developer
<  이전 글

다음 글  >

최신글