본문 바로가기

FrontEnd

컴포넌트 합성 : 레이아웃 기반 합성 컴포넌트

반응형

원문 : https://www.smashingmagazine.com/2022/01/composition-based-design-system-figma/

 

Composition-Based Design System In Figma — Smashing Magazine

Figma has advanced enough where it now supports some powerful concepts that can help with the flexibility and maintainability of a design system. In this article, Sasha explains why she finds the Systems Designer position so rewarding — and it’s not on

www.smashingmagazine.com

팀원들의 생산성 중 상당 부분이 다음과 같은 끝없는 대화에서 낭비됩니다.
  • 이건 다른 컴포넌트인가요?
  • 이건 variant(변형)인가요?
  • 설정 옵션은 어떻게 해야 하죠?

이러한 타입의 대화는 매우 반복적이며 결정 후에도 항상 애매하며 의문을 남십니다.

 

무엇을 위해 컴포넌트를 최적화하나요? 일관성, 확장성, 창의성 또는 유지보수?
최적화 목표는 여러가지이며, 하나에 집중하면 다른 것들이 희생되는 경우가 많습니다.

 

아래와 같은 리스트 아이템 컴포넌트가 있다고 가정합니다.

  • 해당 리스트 컴포넌트는 몇 번 재사용될까요?
  • 몇 개의 변형이 존재해야 할까요?

Four list items: all same, but different.

위의 Title-Subtitle 리스트 아이템 컴포넌트의 경우, 어떤 것이 변형을 의미하나요?
  • 이미지(쉐브론;>)
  • 끝에 쉐브론 대신 info 아이콘?
  • 선행 이미지?
  • 스위치?

해당 컴포넌트들은 동시에 state(선택됨, 눌림, 비활성화 등) 변형을 공유합니다.
해당 디자인은 두 가지 관점에서 바라볼 수 있습니다.

  • 개발자 관점 (컴포넌트, 코드)
  • 디자인 관점 (레이아웃 - 속성, 변형, 제약 조건)

디자인 시스템을 위한 합성(Composition), 컨텐츠 합성 및 컨테이너

이 리스트 아이템 컴포넌트를 살펴보겠습니다.
We always have a background that (in our case) could change depending on its state: primary, secondary, accent (plus its custom interaction and animation).

해당 컴포넌트의 다양한 모습을 나타내는 방법은 다음과 같습니다

Variation(변형)

디자인 시스템에서 변형은 동일한 기본 스타일을 공유하지만

색상이나 크기와 같은 일부 측면에서 다른 컴포넌트 또는 디자인 요소를 의미합니다. (size, color, etc.)

먼저 인터페이스에 존재하는 모든 리스트 아이템을 정의하고 변형을 식별합니다.

먼저 인터페이스에 존재하는 모든 리스트 아이템을 정의하고 변형을 식별합니다.

다음 각 리스트 아이템마다  정의된 모든 상태(보조, accent 등)를 변형으로 추가합니다.
이렇게 하면 상태당 각 원래 컴포넌트/변형이 두 배가 되며, 리스트 항목이 가질 수 있는 모든 상태를 설명할 수 있습니다.

각 아이템 + 상태 조합으로 인해 늘어난 변형

이것은 분명 흔히 볼 수 있는 문제 해결 방식입니다.
배경 및 기타 요소가 불필요하게 반복되는 곳에서 유지 관리해야 하는 변형의 수가 점차 늘어나고 있습니다.

 

앞으로 몇가지를 더 변경해보죠

  • 다른 색상/모서리 반경을 갖는 보조 배경(회색)
  • 제목의 글꼴 스타일
  • 제목과 부제 사이의 간격
  • 이미지 크기

이미 32개가 존재하는 리스트 아이템 변형이 기하급수적으로 늘어날 것입니다.

우리는 다른 방법이 필요합니다. 합성(composition)입니다.


Composition

컨테이너 합성부터 시작하겠습니다.
🔴가 컨테이너를 의미한다고 가정합시다.
 
컨테이너에 배경 스타일 및 패딩(모서리 반경, 그림자 등도 포함할 수 있음)을 정의하고
다른 컴포넌트와 교체할 수 있는 일반 콘텐츠 자리 차지자 🔷를 중첩합니다.
컨테이너와 컨텐츠
  • 🔴는 일반적인 컨텐츠를 위한 컨테이너입니다.
  • 🔷는 일반적인 컨텐츠가 위치할 수 있는 자리 차지자(placeholder)입니다.
리스트아이템에는 체크 표시, 탐색 셰브론, 스위치 또는 버튼과 같은 몇 가지 컨텍스트 강화 요소가 있습니다.
정의된 모든 배경과 모든 일반 콘텐츠에 적용될 수 있으므로
해당 요소를 위해 다른 컨테이너를 구성해야 합니다.
  • 컨테이너는 요소와 해당 위치를 패딩과 함께 정의합니다.
  • 콘텐츠를 위한 자리 차지자는 같이 컨테이너 내부에 중첩하여 존재합니다.
배경색이 아직 없는 것에 주목하세요. 이 배경색은 컨테이너에서 옵니다
  • 🔶는 컨텍스트의 의미를 강화하는 요소를 포함한 컨테이너 입니다.
    • 🔶는 🔷를 포함한 컨테이너라고 생각할 수 있습니다.
    • 해당 요소가 있는 컨테이너는 또 다른 컨테이너 입니다.
    • 해당 요소를 포함한 컨테이너의 상태는 🔴에서 가져옵니다.
      • 🔴안에 🔶가 들어가는 형태

다음으로 인터페이스에 배경이 없는(텍스트와 이미지만 존재하는)
리스트 아이템 콘텐츠 ⚫️(예: 멀티 라인 리스트 아이템)를 정의해 보겠습니다.

이것은 더 적은 변형으로 여러 컴포넌트로 쉽게 분할될 수 있으며 우리의 접근 방식에서 아무것도 변경되지 않습니다.
  • ⚫️는 자리 차지자 위치(🔷, 🔶)에 들어갈 수 있는 인스턴스 입니다.
이제 필요한 리스템 아이템을 조립하려면 처음부터 생각해야 합니다(Z축 방향으로).
  • 컨테이너 🔴를 가져와 필요한 상태를 선택합니다.
  • 자리 표시자 🔷 내부를 목록 항목 콘텐츠 ⚫️ 정의한 항목으로 교체
  • 혹은 리스트 아이템에 향상 요소(예: 스위치, 버튼 등)가 있는 경우
    • 자리 차지자 🔷를 요소 컨테이너 🔶로 바꿉니다.
    • 🔶 내부의 🔷를 목록 항목 콘텐츠 ⚫️ 로 바꿉니다.

Using Composition To Align Design And Development Approaches from Smashing Magazine on Vimeo.

합성은 디자인 설계 및 컴포넌트 개발 방식을 얼라인 할 뿐 만 아니라,
디자인 및 코드에서 일관성과 유지관리를 고려하여 컴포넌트를 구축하는 가장 최적화 된 방식입니다.
아래 예제에서 Swift UI 코드와 디자인 문서가 얼마나 유사한지 볼 수 있습니다.
컨테이너 기반 합성

합성 컴포넌트의 장점

  1. 일관성 
  2. 에러에 강한 디자인
  3. 유연함
  4. 변형 슬림화
  5. 팀워크

1. 일관성

모든 배경 패턴을 재사용할 수 있도록 한 곳에 배치함으로써,
배경 상태가 기능(feature)과 팀 전체에서 단일 정보 소스로 일관되게 표시되도록 합니다.
이러한 상태가 실제로 정의되지 않으면 화면 전체에서 이러한 상태에 대해 시각적으로 다른 디자인을 얻게 됩니다.
팀에 디자이너가 많을수록 불일치가 더 많이 발생합니다.

2. 에러에 강한 디자인

우리는 디자이너가 상태를 오용하거나, 패딩을 잘못 사용하거나, 이미 존재하는 것을 다시 만들 가능성을 없앱니다.
인스턴스를 분리하지 않는 한…

인스턴스를 분리하지 않으실꺼죠?

3. 유연함

특정 콘텐츠만 호스팅하도록 리스트 아이템 컨텐츠를 제한할 필요가 없습니다. 어떤 내용이든 넣을 수 있습니다.
리스트 아이템에 사용한 콘텐츠를 카드 컨테이너에 완벽하게 매끄럽게 넣는 방법을 살펴보겠습니다.
일반적으로 일관성은 유연성을 희생시키면서 달성되지만 이 경우에는 그렇지 않습니다.

4. 변형 슬림화

더 이상 모든 리스트 아이템 컴포넌트에 리스트 아이템 상태를 포함할 필요가 없습니다.
스위치, 버튼, 아이콘 등과 같이 리스트아이템이 호스팅 할 수 있는 요소를
리스트 아이템과 동일한 위치에서 정의하고 컨테이너로 재사용했습니다.
컴포넌트의 유지 보수성 및 확장성에 + 입니다.
  •  🔴 안에 🔷 혹은 🔷+ 🔶컨테이너
    • 🔷안에 ⚫️

변형 기반 접근 방식이 유지보수하기 정말 어렵다는 것을 더 깊이 이해하셨을 겁니다.

5. 팀워크

코드와 동일한 설계 방식으로 컴포넌트를 디자인하면,

디자인 사양과 코드 간의 차이가 줄어들어 의사소통이 쉬워집니다.

또한 유사한 합성 구조를 공유하는 많은 컴포넌트에 사용할 수 있습니다.

  • 카드: 활성, 강조 표시, 비활성화와 같은 배경 재사용
  • 커스텀 바텀 시트: 컨테이너를 재사용하고 내용물을 내부에 넣습니다.


해야할 때와 하지 말아야 할 때

합성 구조가 일관된 재사용 및 유지 보수성에 최적이라는건 이미 아셨겠지만, 남용은 금물입니다.
다음은 컴포지션을 사용할 수 있는 경우에 대한 일반적인 규칙입니다.

컴포지션은 (합리적으로) 컴포넌트(X/Y/Z 축)를 "일반 콘텐츠"와 "강화 요소"의 두 부분으로 나눌 수 있을 때 사용합니다.
  • "일반 콘텐츠;Generic content"는 모든 UI 콘텐츠를 호스팅하는 컴포넌트의 슬라이스(영역)입니다.
  • "강화 요소;Enhancing elements"는 컴포넌트에 일관적인 UI 요소(예: 스위치, 쉐브론, 배경) 및 상호 작용 동작(애니메이션)을 의미합니다.

이 규칙은 사람마다 슬라이스를 다르게 볼 수 있기 때문에 해석의 여지가 많이 있으나,
목표를 달성할 수 있는 여러 가지 방법이 있는 이 접근 방식의 유연성과 강력함을 보여주기 때문에 괜찮습니다.

꽤 많은 논리(아이콘 색상, IBAN 형식)가 포함되어 있기 때문에 일반 콘텐츠를 재사용하고 싶습니다. 라디오 그룹 및 선택 목록 컴포넌트는 일반적인 컨텐츠를 포함하고 싶습니다.

합성이 필요없는 경우는 서로가 강하게 연관되어 있을 경우입니다.

예를 들어 아래 인풋은 입력 상태와 배경색이 매우 강하게 연관되어 있습니다.

여기서 배경은 재사용 가능해 보이지만 실제로는 입력 상태에 반응합니다. 이는 텍스트 필드와 배경 사이에 결합을 생성하여 서로 분리할 수 없음을 의미합니다.


합성의 힘 다스리기

디자인 시스템에서 합성 가능한 구조를 채택하기로 결정한 경우 컴포넌트를 Figma의 계층 구조로 분할하는 것이 좋습니다.

 

  1. 컨테이너 배경  🔴
    • 이들은 Z축에서 합성되며 다음만 정의합니다.
      • 스타일링: 배경색, 모서리 반경, 그림자 등.
      • 일반 레이아웃: 패딩, 콘텐츠의 위치.
  2. 강화 요소 컨테이너 🔶
    • 쉐브론, 스위치, 버튼, 아이콘 등과 같은 추가 요소를 포함할 수 있는 컨테이너
  3. 콘텐츠  🔷
    • 실제 일반 콘텐츠의 구현(인스턴스)인 컴포넌트입니다. 컴포지션 트리의 마지막 노드입니다.

이제 우리는 무엇이든 합성할 수 있는 능력을 갖게 되었습니다.

하지만 이론적으로 아래와 같이 의미없는 조합을 구현하는 것도 가능합니다.

(can't가 아니라 shouldn't!)

현실적으로는 의미없는 구현

위의 체크 표시와 스위치를 결합하는 이상한 예처럼 두 요소를 모두 중첩하지 못하게 하고 싶습니다.
즉, 합성 가능한 컴포넌트의 사용 가능한 조합 케이스를 제한하기로 결정할 수 있습니다.
강화 컨테이너를 컨테이너 배경과 결합하여 새 컨테이너 배경 컴포넌트 🔴를 만듭니다.
 
네비게이션 리스트 아이템의 컨테이너 배경(2가지 변형, 기본 및 누름)을
강화 컨테이너(쉐브론)와 결합하여 새로운 컨테이너를 생성합니다.
네비게이션 컴포넌트는 단 두 개의 모양밖에 없음
 
이렇게 하면 네비게이션 컴포넌트의 가능한 모든 변형을 정의할 수 있습니다.
(🔶 가 🔴와 통합됨)
 
즉, 이제 selected 상태나, Switch와 같은 아이템을 네비게이션 리스트 아이템으로 사용할 수 없지만,
컨텐츠 영역은 일반성을 유지합니다.
반응형