[디자인 시스템은 어떻게 만들었나요?(2)] Radix Primitives와 Panda CSS로 유연하고 견고한 컴포넌트 만들기
Radix Primitives와 Panda CSS로 접근성과 유연성을 갖춘 YDS 컴포넌트를 재구축했다.
YDS v2 컴포넌트 라이브러리는 Radix Primitives와 Panda CSS를 중심으로 다시 설계했다. 목표는 사내 디자인 시스템에 맞는 세밀한 제어를 유지하면서도, 웹 접근성과 확장성, 유지보수성을 함께 확보하는 것이었다.
기성 UI 라이브러리는 빠르게 시작할 수 있지만, 고유한 디자인 시스템이 있을수록 기본 스타일을 덮어쓰는 비용이 커진다. 반대로 직접 구현하면 접근성, 키보드 내비게이션, 포커스 관리, 브라우저 호환성까지 모두 책임져야 하므로 운영 부담이 크다. 요기요 FE는 이 딜레마를 풀기 위해 로직과 접근성은 Radix에 위임하고, 스타일과 제품 요구사항은 내부 디자인 시스템이 주도하는 방향을 택했다.
핵심 설계는 Radix의 Open Component Architecture를 활용해 각 파트에 필요한 props, event listener, ref를 유연하게 주입할 수 있게 만든 것이다.
Tabs.Root / List / Trigger / Content구조로 컴포넌트를 래핑- 내부 로직용
listRef와 외부forwardRef를 composeRefs로 병합 - 활성 탭 위치를 계산해 Indicator를 정확히 배치
- Radix가 자동으로 주입하는
data-state="active"같은 data attributes를 스타일 분기 기준으로 활용
예시로 든 Tab 컴포넌트에서는 Trigger의 활성 상태, hover, focus-visible, disabled 상태를 Panda CSS의 slot recipe 안에서 선언적으로 처리했다. JavaScript에서 클래스를 토글하지 않고도 상태 기반 스타일링이 가능해졌고, 활성 탭의 굵기 표현이나 disabled 상태 같은 세부 UX도 일관되게 관리할 수 있었다.
스타일 시스템은 styled-components에서 Panda CSS로 전환했다. 런타임 CSS generation이 만드는 성능 오버헤드를 줄이고, React 18 이후의 RSC 흐름과 맞추기 위한 선택이었다. 2025년 3월 styled-components가 Maintenance 모드로 전환된 점도 전환의 배경이 됐다.
대안으로 Sass/CSS Modules와 Tailwind CSS도 검토했지만, 컴포넌트 로직과 스타일의 결합, 문자열 기반 스타일링의 유지보수 리스크, 팀의 마이그레이션 비용을 함께 고려해 zero-runtime CSS-in-TS 계열을 택했다. 그중에서도 Panda CSS는 문서화가 잘 되어 있고 styled 패턴을 제공해 러닝커브를 낮출 수 있었다.
토큰 라이브러리 역시 단순한 CSS 파일 배포가 아니라, 소비 환경별 특성에 맞게 데이터를 변환해 제공하는 방향으로 설계했다. 결국 핵심은 디자인 시스템의 일관성을 지키면서도, 구현은 더 유연하고 단단하게 만드는 데 있었다.
이 요약은 원문 이해를 돕기 위한 큐레이션입니다. 저작권은 원저작자에게 있으며, 정확한 내용과 맥락은 원문을 확인하세요.
요약 오류, 출처 표기 문제, 삭제 요청은 문의 · 건의로 알려주세요.
