오늘은 플러터에서 디자인 시스템을 효율적으로 관리하는 방법을 소개하려고 합니다. 특히 프로젝트 내에서 범용적으로 사용되는 TextStyle과 Color에 초점을 맞추어 글을 작성하겠습니다.
디자인 시스템이란?
디자인 시스템은 프로덕트 개발의 일관성, 효율성, 확장성을 보장하기 위해 필요한 시각적 요소(스타일, 구성 요소, 패턴, 가이드라인) 등을 정의한 것입니다.
디자인 시스템을 정의하는 법은 따로 정해져 있지 않기에 좌측처럼 디자이너가 직접 작성하여 공유하는 경우도 있으며, 우측과 같이 디자인 툴() 내부 기능을 통하여 정의하기도 합니다.
디자인 시스템에서 정의된 Text(세부 속성 및 명칭 포함) | Figma 내부에서 정의된 색상 모음 |
이렇듯 자주 사용하는 TextStyle, Color 등을 프로젝트 초기 단계에서 정의해두면 아래와 같은 장점을 얻을 수 있습니다.
- 색상 값이 변경된 경우, 해당 색상을 참조하는 모든 부분을 수정하는 것이 아니라 정의 부분만 변경하면 된다.
- Color의 hex 값이나 TextStyle의 세부 속성들을 옮기는 과정에서 발생하는 시간을 단축하고 휴먼 에러를 방지할 수 있다.
👍 본 포스팅에서 소개하는 관리 방법이 정답이 아님을 먼저 말씀드리며
더 좋은 방법을 찾거나 의견을 주신다면 적극적으로 피드백을 반영하도록 하겠습니다 :)
플러터에서 Color 관리하기
abstract class AppColor {
AppColor._();
//Primary Color
static const primary900 = Color(0xff0e0224);
static const primary800 = Color(0xff210653);
static const primary700 = Color(0xff340983);
static const primary600 = Color(0xff480cb3);
static const primary500 = Color(0xff5b0fe3);
static const primary400 = Color(0xff7743f1);
static const primary300 = Color(0xff9763f5);
...
}
AppColor는 abstract를 사용하여 추상 클래스로 선언하였으며 생성자 앞에 언더스코어(_)를 붙임으로 private으로 설정해두었습니다. 이를 통하여 직접 인스턴스화 하는 것을 방지하고 AppColor 안에서 정의한 정적 필드만 제공하는 유틸리티 클래스의 역할을 수행하도록 하였습니다.
이러한 Color 관리를 통하여 UI 구현 과정에서 색상 코드를 직접 입력하지 않고 AppColor를 참조하는 것으로 오탈자로 발생할 수 있는 휴먼 에러를 방지하고 코드의 가독성을 높일 수 있습니다.
플러터에서 TextStyle 관리하기
class Typo {
Color color;
Color decorationColor;
TextDecoration decoration;
double letterSpacing;
TextDecorationStyle decorationStyle;
Typo(
{this.color = AppColor.black,
this.decoration = TextDecoration.none,
this.decorationColor = AppColor.black,
this.letterSpacing = LetterSpacing.defaultValue,
this.decorationStyle = TextDecorationStyle.solid});
/// Title/30_Bold
TextStyle get title1 => TextStyle(
fontWeight: FFontWeight.bold,
fontSize: 30,
height: 1.3,
color: color,
decoration: decoration,
decorationColor: decorationColor,
letterSpacing: letterSpacing,
);
TextStyle을 관리하기 위하여 Typo라는 클래스를 선언하였습니다. Typo는 프로젝트에서 자주 사용되는 TextStyle의 공통 요소를 변수로 가지고 있으며 디자인 시스템에서 정의한 TextStyle(Title1, Title2, Body1, Body2 등)을 메소드 형태로 반환합니다.
특히, 플러터에서는 중괄호 {} 를 사용하여 파라미터를 받는 방법, 'Named Parameter'를 지원합니다. 네임드 파라미터의 장점으로는 파라미터 순서에 상관 없이 원하는 파라미터에 직접 값을 할당할 수 있어서 코드 가독성이 높아지며 유연성도 증가합니다. 하지만 위 코드에서는 color, decoration, decorationColor 등 Typo가 많은 매개변수를 가지기 때문에 선택적으로 값을 전달하기 위하여 사용하였습니다.
실제 사용 예시
위 코드를 적용하면 실제로 얼마나 코드의 가독성이 좋아지고 줄 수가 줄어드는지 확인해보겠습니다.
Text(
'국가/지역 선택',
style: Typo().subtitle1,
),
Text(
'국가/지역 선택',
style: TextStyle(
color: Color(0xff000000),
fontWeight: FontWeight.w600,
fontSize: 19,
height: 1.3,
)
),
가장 기본적으로 사용되는 색상, 폰트 크기, 폰트 두께, 행간만을 다루어도 플러터의 코드는 상당히 길어지게 됩니다. 이처럼 별도의 클래스를 통하여 관리하게 되면 개발 과정에서 편의성과 가독성 향상을 기대할 수 있습니다.
추가로 문서 주석(Doc comment)를 사용하게 되면 디자인 툴로 Figma를 사용할 때 큰 도움이 될 수 있습니다. Typography 내부에서 주석으로 세부 사항(Body 중에서 Body1인지 Body2인지 등)을 안내하는 경우가 종종 있을 때, 재차 확인해야 하는 번거로움을 줄일 수 있습니다.
마치며...
자주 사용하는 스타일들을 재사용하고 확장할 수 있도록 관리하는 것은 다소 많은 시간이 소요되고 번거로울 수 있습니다. 하지만 프로젝트 초기 단계에서는 각 스타일의 세부적인 수치 변동이 잦을 수 있으며 새로운 스타일이 정의될 때, 기존 관리 방법을 그대로 사용하면 프로젝트 관리 및 협업을 효율적으로 진행할 수 있습니다.
개인적으로 플러터로 프로젝트의 스타일을 관리할 때, Named Parameter와 Doc Comment는 적극적으로 활용하면 큰 개발 시간 단축을 가져올 수 있을 것이란 생각이 들었습니다. 더 좋은 방법을 알게 된다면 해당 포스트에 추가로 작성하도록 하겠습니다. 긴 글 읽어주셔서 감사합니다 :)
'Dart + Flutter' 카테고리의 다른 글
[Flutter] 하단 Sticky UI 패턴을 적용하기 위한 스크린 템플릿 (0) | 2024.01.15 |
---|---|
[Flutter] Pop Gesture(Swipe Back Gesture)에 의한 뒤로 가기 막기 (2) | 2023.11.25 |
[Dart - 01] Dart는 무엇이고 왜 Flutter에서 사용할까? (0) | 2023.09.09 |