누구나 로고
온라인 강의기업·단체교육읽는 강의트렌드 인사이트무료 강의공지사항문의하기채용 사이트
모든 강의를 무료로 볼 수 있어요. 회원가입 없이도 학습 가능합니다.
로그인무료 회원가입
강좌리액트 입문 — 컴포넌트로 만드는 웹28강

28강 / 전체 28강

배포하기

4분 읽기 조회 0

컴포넌트 라이브러리(shadcn/ui, Radix UI) 활용법과 스타일 시스템 구축, 접근성(a11y) 원칙, 그리고 디자인 시스템 없이도 일관된 UI를 만드는 방법을 배웁니다.

🎨 왜 컴포넌트 라이브러리를 쓰는가

버튼, 모달, 드롭다운, 날짜 선택기 등 복잡한 UI 컴포넌트를 처음부터 직접 만들면 많은 시간이 걸립니다. 특히 키보드 탐색, 스크린 리더 지원, 포커스 트랩 같은 접근성 기능까지 직접 구현하는 것은 매우 어렵습니다. 컴포넌트 라이브러리를 활용하면 이 문제를 해결합니다.

📦 shadcn/ui — 현재 가장 인기있는 선택

shadcn/ui는 기존 컴포넌트 라이브러리와 다릅니다. 코드를 당신의 프로젝트에 직접 복사합니다. npm 패키지가 아닙니다. 그래서 완전히 커스터마이징 가능합니다.

# 초기 설정 (Vite 프로젝트)
npx shadcn@latest init

# 필요한 컴포넌트 추가
npx shadcn@latest add button
npx shadcn@latest add dialog
npx shadcn@latest add input

설치하면 src/components/ui/에 컴포넌트 코드가 생깁니다. 직접 수정해서 쓸 수 있습니다.

import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from '@/components/ui/dialog'

function App() {
  return (
    <Dialog>
      <DialogTrigger asChild>
        <Button variant="outline">모달 열기</Button>
      </DialogTrigger>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>설정</DialogTitle>
        </DialogHeader>
        <div className="space-y-4 py-4">
          <div>
            <label className="text-sm font-medium">이름</label>
            <Input placeholder="이름을 입력하세요" className="mt-1" />
          </div>
          <Button className="w-full">저장</Button>
        </div>
      </DialogContent>
    </Dialog>
  )
}

♿ 접근성(a11y) 기본 원칙

좋은 UI는 마우스 없이도 키보드만으로 사용할 수 있어야 합니다. shadcn/ui는 Radix UI 위에 구축되어 접근성이 이미 내장되어 있습니다. 직접 컴포넌트를 만들 때 지켜야 할 기본 규칙:

// ❌ 접근성 없는 버튼 — 키보드 사용 불가, 스크린 리더 설명 없음
<div onClick={handleDelete} className="cursor-pointer text-red-500">
  삭제
</div>

// ✅ 시맨틱 요소 사용
<button
  onClick={handleDelete}
  aria-label="게시글 삭제"  // 아이콘만 있을 때 레이블 제공
  className="text-red-500 hover:text-red-700"
>
  <Trash2 className="h-4 w-4" />
</button>

// ✅ 이미지 alt 텍스트
<img src="/avatar.jpg" alt="김민준 프로필 사진" />  // 의미 있는 설명
<img src="/decoration.png" alt="" />               // 장식용은 빈 문자열
원칙실천 방법
시맨틱 HTMLbutton은 <button>, 링크는 <a>, 입력은 <input>
키보드 접근모든 인터랙션이 Tab, Enter, Space, Esc로 동작해야 함
포커스 표시outline을 지우지 마세요 (접근성 필수)
색 대비텍스트와 배경 대비 4.5:1 이상 (WCAG AA)
ARIA 레이블아이콘 버튼에 aria-label 추가

🎭 cn() 유틸리티 — Tailwind 클래스 병합

조건부 클래스와 기본 클래스를 깔끔하게 병합합니다:

// lib/utils.ts (shadcn/ui가 자동 생성)
import { clsx, type ClassValue } from 'clsx'
import { twMerge } from 'tailwind-merge'

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs))
}

// 사용
function Badge({ variant = 'default' }: { variant?: 'default' | 'success' | 'danger' }) {
  return (
    <span
      className={cn(
        'inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium',
        {
          'bg-gray-100 text-gray-700': variant === 'default',
          'bg-green-100 text-green-700': variant === 'success',
          'bg-red-100 text-red-700': variant === 'danger',
        }
      )}
    >
      {/* ... */}
    </span>
  )
}

✅ 정리

  • shadcn/ui: 코드를 프로젝트에 복사해 사용 — 완전 커스터마이징 가능.
  • Radix UI 기반으로 키보드, 스크린 리더, 포커스 관리가 내장되어 있습니다.
  • 직접 컴포넌트 만들 때: 시맨틱 HTML + aria 속성 + 키보드 동작을 반드시 챙기세요.
  • cn()으로 조건부 Tailwind 클래스를 깔끔하게 병합합니다.

관련 주제

  • shadcn/ui
  • Radix UI
  • 컴포넌트 라이브러리
  • 접근성
  • 키보드 탐색
  • 스크린 리더
  • 커스터마이징
  • 개발·프로그래밍
  • 개발·프로그래밍 강의
  • 리액트 입문 — 컴포넌트로 만드는 웹
  • 무료강의
  • 무료 온라인 강의
  • NUGUNA
  • 누구나
이전 27강환경변수와 빌드

댓글

0/1000

불러오는 중...

목차

  1. 1.리액트란 무엇인가
  2. 2.개발 환경 만들기 — Vite
  3. 3.JSX 기초
  4. 4.컴포넌트 만들기
  5. 5.Props로 데이터 전달
  6. 6.State와 useState
  7. 7.이벤트 처리
  8. 8.조건부 렌더링
  9. 9.리스트 렌더링과 key
  10. 10.폼 다루기
  11. 11.useEffect 기초
  12. 12.데이터 가져오기(fetch)
  13. 13.상태 끌어올리기
  14. 14.컴포넌트 합성과 재사용
  15. 15.useRef와 DOM 접근
  16. 16.커스텀 훅 만들기
  17. 17.Context API
  18. 18.useReducer
  19. 19.리스트 앱 실전 ①
  20. 20.리스트 앱 실전 ②
  21. 21.라우팅 — React Router
  22. 22.스타일링 방법들
  23. 23.리스트·상세 페이지 연결
  24. 24.비동기 상태 관리 패턴
  25. 25.성능 기초 — memo
  26. 26.에러 처리와 경계
  27. 27.환경변수와 빌드
  28. 28.배포하기

고객지원

  • 공지사항
  • 자주 묻는 질문
  • 문의하기
  • 커뮤니티

이용안내

  • 이용약관
  • 개인정보처리방침
  • 환불정책

서비스

  • 회사소개
  • 회원가입
  • 신규 강의
  • 무료 강의
누구나 로고
이용약관개인정보처리방침환불정책

상호명: NUGUNA  |  대표자: 정우진  |  사업자등록번호: 392-32-01817  |  통신판매업신고: 제 2026-서울양천-0564 호

주소: 서울특별시 양천구 목동서로 100  |  이메일: nugunapass@gmail.com  |  전화: 010-6395-3043

© 2026 NUGUNA. All rights reserved.

KB예금주인증관리자
홈강의읽는 강의문의하기MY