Shadcn 라디오 버튼의 과도한 복잡성

2 weeks ago 11

  • 웹 브라우저에 기본 내장된 라디오 버튼이 단순한 HTML 요소임에도, Shadcn UI 라이브러리에서는 이를 여러 계층의 React 컴포넌트로 재구성함
  • Shadcn의 <RadioGroup>과 <RadioGroupItem>은 Radix UI의 컴포넌트를 다시 감싸며, lucide-react 아이콘수십 개의 Tailwind 클래스를 사용
  • Radix는 접근성과 커스터마이징을 위해 ARIA 속성을 활용하지만, 실제로는 기본 <input type="radio"> 대신 버튼 요소를 재활용함
  • 단순한 CSS로도 동일한 스타일링이 가능함에도, 이 구조는 수백 줄의 코드와 여러 종속성을 추가해 불필요한 복잡성을 초래
  • 기본 HTML 요소를 재사용하지 않음으로써 성능 저하와 유지보수 부담이 커지고, 웹 개발의 단순함이 훼손됨

Shadcn 라디오 버튼 구조 분석

  • Shadcn은 <RadioGroup>과 <RadioGroupItem> 두 컴포넌트를 통해 라디오 버튼을 구현
    • 각 컴포넌트는 @radix-ui/react-radio-group에서 가져온 프리미티브를 감싸며, lucide-react의 CircleIcon을 사용
    • 45줄 이상의 코드와 3개의 외부 import가 포함되어 있으며, 30개 이상의 Tailwind 클래스로 스타일 지정
  • 단순한 원형 표시를 위해 SVG 아이콘 라이브러리를 불러오는 구조
    • CSS의 border-radius나 <circle> 요소로 대체 가능한 기능임

Radix UI의 역할

  • Shadcn이 사용하는 Radix는 접근성과 커스터마이징 중심의 저수준 UI 컴포넌트 라이브러리
    • Radix의 라디오 그룹 구현은 약 215줄의 React 코드와 7개의 파일을 import
  • Radix는 <button> 요소에 ARIA 속성을 추가해 라디오 버튼처럼 동작하도록 구성
    • 그러나 W3C의 ARIA 사용 제1원칙은 “가능한 경우 기본 HTML 요소를 사용할 것”으로 명시
    • Radix는 이 원칙을 따르지 않고, <input> 대신 버튼을 재활용함
  • <form> 내부에서만 숨겨진 <input type="radio">를 추가하는 구조로, 일관성이 떨어짐

CSS로 가능한 단순한 대안

  • 기본 HTML 라디오 버튼은 appearance: none, ::before, :checked, border-radius 등으로 손쉽게 스타일링 가능
    • 예시 코드에서는 의존성, 자바스크립트, ARIA 속성 없이 완전한 커스터마이징 구현
    • 동일한 효과를 Tailwind로도 구현 가능
  • “라디오 버튼 스타일링은 어렵다”는 인식은 과거의 문제이며, 현재는 순수 CSS만으로 충분한 제어 가능

복잡성의 누적 문제

  • Shadcn과 Radix를 함께 사용하면 두 개의 라이브러리와 수백 줄의 코드를 이해해야 함
    • 단순한 라디오 버튼 하나를 위해 수 KB의 자바스크립트가 추가 로드됨
    • 사용자는 버튼 토글을 위해 JS 파싱과 실행을 기다려야 함
  • 이러한 구조는 인지 부하 증가, 버그 가능성 확대, 웹 성능 저하로 이어짐

단순함으로의 회귀

  • 브라우저는 이미 라디오 버튼을 기본 제공하며, <input type="radio" name="beverage" value="coffee" /> 한 줄로 충분
  • 불필요한 추상화와 중첩된 라이브러리 사용은 웹 개발의 본래 단순성과 효율성을 해침
  • 작은 UI 요소라도 기본 기능을 재활용하는 설계가 유지보수성과 성능 모두에 유리함

Read Entire Article