피드로 돌아가기
Why I separated `variant` from `intent` in my component API
Dev.toDev.to
Frontend

Variant 폭발 방지, Intent 분리로 설계한 확장 가능한 Component API

Why I separated `variant` from `intent` in my component API

Sinisa Kusic2026년 4월 6일7intermediate

Context

단일 variant prop에 시각적 무게와 의미론적 상태를 모두 포함하는 구조. 조합 증가에 따라 prop 값이 기하급수적으로 늘어나는 현상 발생. 타입 시스템을 통한 자동 완성 및 발견 가능성이 현저히 떨어지는 모델링 한계.

Technical Solution

  • 시각적 강조도를 결정하는 variant와 의미론적 상태를 정의하는 intent로 prop을 완전히 분리하는 설계
  • variant는 primary, secondary, outline, ghost, link와 같이 시각적 무게감만 제어하는 방식
  • intent는 default, danger, success, warning과 같이 동작의 의미만 전달하는 구조
  • CVA(Class Variance Authority)의 compoundVariants를 활용하여 두 축의 교차 지점 스타일을 명시적으로 정의
  • 모든 조합(5 variants x 4 intents = 20개)을 사전 정의하여 런타임 예외를 방지하고 일관된 API 표면 제공
  • TypeScript 인터페이스를 통해 컴파일 단계에서 유효한 prop 조합만 허용하는 강한 타입 제약 적용

Key Takeaway

컴포넌트 API의 복잡도는 구현 도구가 아닌 도메인 모델링의 문제임. 서로 독립적인 두 가지 관심사(Orthogonal Concerns)를 단일 속성에 통합하지 않고 분리함으로써 예측 가능하고 확장 가능한 인터페이스를 구축할 수 있음.


컴포넌트의 스타일 조합이 10개 이상으로 늘어날 때, 시각적 스타일과 의미론적 상태를 분리한 2-Prop 모델 도입을 검토할 것

원문 읽기