- 웹 브라우저에 기본 내장된 라디오 버튼이 단순한 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 요소라도 기본 기능을 재활용하는 설계가 유지보수성과 성능 모두에 유리함