사용자 경험의 일관성과
생산성 향상에 기여한 디자인 시스템

빠른 제품 검증을 가능하게 도와준 디자인 시스템

빠른 제품 검증을 가능하게

도와준 디자인 시스템

June 2021

사용자 경험의 일관성과
생산성 향상에 기여한
디자인 시스템

왜 디자인 시스템을 구축 하였나요?

왜 디자인 시스템을
구축 하였나요?

디자인의 본질은 사용자의 '문제를 해결하는 것'이라고 생각합니다. 다시 말해 디자인은 그 자체가 '목적'이라기 보다는 '수단'으로서 사용자 입장에서 문제를 발견하고 해결하는 '도구'입니다.


때문에 '도구'인 '디자인 시스템'은 마치 과학 실험처럼 사용자의 문제를 해결하기 위해 세웠던 가설을 '빠르게' 검증하도록 도와주는 '촉매제' 역할을 한다고 생각합니다.


'마이뮤직시트'의 '디자인 시스템'은 서비스 경험의 일관성을 해치지 않으면서도 사용자 문제 해결에 필요한 다양한 가설을 빠르게 검증할 수 있도록 그 생산성을 높이고자 설계되었습니다.

디자인의 본질은 사용자의 '문제를 해결하는 것'이라고 생각합니다. 다시 말해 디자인은 그 자체가 '목적'이라기 보다는 '수단'으로서 사용자 입장에서 문제를 발견하고 해결하는 '도구'입니다.


때문에 '도구'인 '디자인 시스템'은 마치 과학 실험처럼 사용자의 문제를 해결하기 위해 세웠던 가설을 '빠르게' 검증하도록 도와주는 '촉매제' 역할을 한다고 생각합니다.


'마이뮤직시트'의 '디자인 시스템'은 서비스 경험의 일관성을 해치지 않으면서도 사용자 문제 해결에 필요한 다양한 가설을 빠르게 검증할 수 있도록 그 생산성을 높이고자 설계되었습니다.

'디자인 시스템'은 과학 실험의 '촉매제'처럼 서비스의 일관성을 해치지 않으면서도 사용자 문제 해결에 필요한 가설을 '빠르게' 검증할 수 있도록 도와줍니다.

'디자인 시스템'은 과학 실험의 '촉매제'처럼 서비스의 일관성을 해치지 않으면서도 사용자 문제 해결에 필요한 가설을 '빠르게' 검증할 수 있도록 도와줍니다.

디자인 시스템을 어떻게 구축 하였나요?

디자인 시스템을
어떻게 구축 하였나요?

서비스 개선을 멈추지 않으면서도 구축할 수 있는 디자인 시스템 워크플로우

서비스 개선을 멈추지 않으면서도 구축할 수 있는 디자인 시스템 워크플로우

제품 팀의 생산성 향상으로 가설을 빠르게 검증하는 것도 중요했지만 지금 마주하고 있는 사용자에게 가치를 전달하는 것이 더욱더 중요했습니다.


'마이뮤직시트'의 제품 팀은 총 다섯 명으로 한 명의 프로덕트 리드 겸 디자이너인 저와 세 명의 프론트엔드 엔지니어 그리고 두 명의 백엔드 엔지니어로 구성되어 있었습니다. 그 때문에 당장의 사용자 문제를 해결하는 것을 멈추지 않으면서도 한정된 개발 자원으로 디자인 시스템을 구축해야 했습니다. 개발자와 디자이너 간의 커뮤니케이션 시간이 구축에 있어서 제일 큰 비용이라고 판단하였기에 이를 효과적으로 줄일 수 있는 '도구'를 찾고자 하였습니다.

디자이너와 개발자가 모두가 컴포넌트의 제약을 빠르게 이해하며 소통할 수 있는 도구

디자이너와 개발자가 모두가 컴포넌트의 제약을 빠르게 이해하며 소통할 수 있는 도구

구축 시 컴포넌트별로 스펙을 확정 짓는 단계에서 많은 시간이 소요 되었지만, 이 단계의 시간 비용은 오히려 바람직하다고 생각했습니다. 초기에 컴포넌트의 명확한 책임과 역할을 이야기하며 작업자들 간의 공감대를 형성하는 것이 궁극적으로는 미래의 소통 비용을 절감할 수 있었기 때문입니다.


하지만 컴포넌트 스펙 확정 이후 디자인 과정에서 컴포넌트를 관리하고 전달하는 방식은 미래의 소통 비용에 큰 영향을 미쳤습니다. 이는 디자이너와 개발자가 서로 다른 '언어'를 사용하기 때문이었습니다. 그렇기에 컴포넌트 스펙 확정 짓고, 디자인 도구에서 이를 전달할때 사용할 '공용어'가 필요했습니다.


이러한 필요에 따라 디자인 시스템 구축 및 전달 도구로 '프레이머'를 채택하였습니다. 프레이머에서는 컴포넌트 UI 디자인 단계에서부터 prop과 variant 그리고 adornment를 '코드 베이스'로 정의할 수 있습니다. 또한 Nested Coponents 디자인할 때도 하위 컴포넌트에서 사용할 prop들을 object로 관리할 수 있어 개발자에게 더욱 명확한 스펙 전달이 가능했습니다.

addPropertyControls(MPInput, {

pseudoClass: {

type: ControlType.Enum,

displaySegmentedControl: true,

defaultValue: "normal",

options: ["normal", "hover", "focus"],

},

status: {

type: ControlType.Enum,

displaySegmentedControl: true,

defaultValue: "normal",

options: ["normal", "error", "disabled"],

},

size: {

type: ControlType.Enum,

displaySegmentedControl: true,

defaultValue: "l",

options: ["m", "l"],

},

required: {

type: ControlType.Boolean,

defaultValue: false,

},

customHeight: {

type: ControlType.Boolean,

defaultValue: false,

},

_height: {

type: ControlType.Number,

title: "ㄴ Height",

defaultValue: 40,

hidden(props) {

return props.customHeight === false

},

},

label: {

type: ControlType.String,

placeholder: "Label",

defaultValue: "Label",

},

placeholder: {

type: ControlType.String,

placeholder: "Placeholder",

defaultValue: "내용을 입력해주세요",

},

value: {

type: ControlType.String,

placeholder: "Value",

},

helperText: {

type: ControlType.String,

placeholder: "Helper Text",

},

prefix: {

type: ControlType.String,

placeholder: "prefix",

},

suffix: {

type: ControlType.String,

placeholder: "suffix",

},

...inheritProps("Icon_L", "leftIcon2", mpIconProps, ["iconName"]),

...inheritProps("Icon_R", "rightIcon2", mpIconProps, ["iconName"]),

customBG: {

type: ControlType.Boolean,

defaultValue: false,

},

backgroundColor: {

type: ControlType.Color,

title: "ㄴ Background",

defaultValue: colors.White,

hidden(props) {

return props.customBG === false

},

},

customRadius: {

type: ControlType.Boolean,

defaultValue: false,

},

...fusedNumber({

variableName: "radius",

defaultValue: 5,

type: "corner",

hidden(props) {

return props.customRadius === false

},

}),

shadow: {

type: ControlType.Boolean,

defaultValue: false,

},

shadowLiteral: {

title: "ㄴ Literal",

type: ControlType.String,

defaultValue: "0px 0px 1px rgba(0,0,0,0.2)",

hidden(props) {

return props.shadow === false

},

},

})

위 이미지처럼 각 컴포넌트의 Property Controls에 prop의 type과 option을 정의하면 초기 컴포넌트 구축 단계에서부터 개발자와 디자이너가 생각의 차이 없이 스펙을 확정할 수 있습니다.


개발자 컨펌을 거쳐 컴포넌트의 디자인 스펙이 확정되면 프로덕션 개발에 착수하게 됩니다. 개발 과정에서 예측하지 못했던 이슈가 발생하더래도 손쉽게 코드를 보며 스펙을 조율할 수 있습니다.

위 이미지처럼 각 컴포넌트의 Property Controls에 prop의 type과 option을 정의하면 초기 컴포넌트 구축 단계에서부터 개발자와 디자이너가 생각의 차이 없이 스펙을 확정할 수 있습니다.


개발자 컨펌을 거쳐 컴포넌트의 디자인 스펙이 확정되면 프로덕션 개발에 착수하게 됩니다. 개발 과정에서 예측하지 못했던 이슈가 발생하더래도 손쉽게 코드를 보며 스펙을 조율할 수 있습니다.

결과적으로 위 이미지처럼 디자인 과정에서 합의된 컴포넌트의 Prop과 Variant만 사용하여 플로우를 전달 할 수 있게 되었습니다.

초기 컴포넌트 스펙 확정 이후 발생하는 유지 비용을 절감하는 워크플로우

초기 컴포넌트 스펙 확정 이후 발생하는 유지 비용을 절감하는 워크플로우

컴포넌트들은 사용자의 다양한 문제를 해결하면서 깎이고 발전하는 숙성의 과정을 거치게 됩니다. 만일 합의 된 컴포넌트의 제약을 탈피하여 디자인해야만 하는 경우 컴포넌트의 프레이머 코드 파일을 수정하면 Git과 slack의 매세지로 개발자에게 알릴 수 있도록 하였습니다.


이러한 워크플로우는 디자인 시스템 개선 과정에서 발생하는 유지 비용을 줄여주었습니다. 또한 실제 개발 환경의 컴포넌트 구현체와 디자인 툴의 컴포넌트 간의 간극을 놓치지 않고 메꾸는 데에도 도움이 되었습니다.

컴포넌트들은 사용자의 다양한 문제를 해결하면서 깎이고 발전하는 숙성의 과정을 거치게 됩니다. 만일 합의 된 컴포넌트의 제약을 탈피하여 디자인해야만 하는 경우 컴포넌트의 프레이머 코드 파일을 수정하면 Git과 slack의 매세지로 개발자에게 알릴 수 있도록 하였습니다.


이러한 워크플로우는 디자인 시스템 개선 과정에서 발생하는 유지 비용을 줄여주었습니다. 또한 실제 개발 환경의 컴포넌트 구현체와 디자인 툴의 컴포넌트 간의 간극을 놓치지 않고 메꾸는 데에도 도움이 되었습니다.

다섯 개의 번역 정보를 효율적으로 관리할 수 있도록 도와준 디자인 툴의 컴포넌트.

다섯 개의 번역 정보를 효율적으로 관리할 수 있도록 도와준 디자인 툴의 컴포넌트.

'마이뮤직시트'는 글로벌 서비스로 다섯 개의 번역 정보를 관리하고 있었습니다. 하지만 캡처 화면을 주고받으며 번역되었던 기존 방식은 플로우를 파악하기 어려워 오역을 빈번하게 발생시켰습니다. 또한 슬랙에서 관리 되던 번역 파일(json)은 메세지 특성상 쉽게 휘발되어 많은 관리 비용을 야기시켰습니다.


디자인 시안 상에서 번역자가 플로우를 확인하며 컴포넌트에 번역 정보를 적을 수 있도록 하여 복잡했던 번역 워크플로우를 디자인 툴로 개선하였습니다. 이를 통해 슬랙에서 번역 파일(json)을 주고받는 것이 아닌 디자인 시안에서 번역 파일(json)을 효율적으로 관리하며 의도에 맞는 번역을 할 수 있게 되었습니다.

현재 디자인 시스템은?

현재 디자인 시스템은?

초기 70%의 구축까지 3.5개월의 시간이 걸렸지만, 그 후 '디자인 시스템'을 만들고자 했던 목적에 맞게 제품팀의 생산성이 향상되면서 빠른 가설 검증할 수 있어 졌습니다.


그뿐만 아니라 제품팀의 주된 대화가 표현적인 UI 가 아닌 사용자 문제를 발견하고 해결하는 대화에 집중할 수 있게 되었습니다. MVP를 만드는 데도 '디자인 시스템'이 '촉매제' 기능을 하며 동일 시간 대비보다 다양한 가설 검증을 할 수 있게 되었습니다.

컴포넌트 목록 (2021년 6월 기준)

· Aside Button

· Badge

· Button

· Callout

· Check

· Dialog

· Divider

· File Upload Item

· Helper Text

· Icon Button

· Icon

· Input

· Menu Cell

· Pagination

· Progress

· Radio

· Slider

· Spacing

· Spinner

· Switch

· Tab Item

· Text

· Textarea

· Toast

· Tooltip