이번 해커톤은 Vapor 디자인 시스템을 사용하여 진행하게 되었습니다!
🔗Vapor UI
이에 앞서, 꼭 알아야 할 요소들을 Docs 기반으로 가볍게 정리해봤습니다.
이 정도만 알아도 어떻게 사용하면 될지 감이 올 것 같습니다.
꼭 알아야 하는 10가지
1. 설치 & 전역 스타일
- 패키지: @vapor-ui/core + 아이콘이면 @vapor-ui/icons까지 설치.
- 전역에 Vapor CSS를 반드시 import. (Next/App Router는 app/layout.tsx, Vite는 src/main.tsx)
// 전역(예: app/layout.tsx 또는 main.tsx)
import '@vapor-ui/core/styles.css';
2. Tailwind CSS와의 통합 (v4)
- Vapor는 Tailwind v4와 잘 붙도록 문서가 준비돼 있음.
- global.css에서 레이어 순서와 import를 아래처럼 맞추면 끝.
- 핵심: Tailwind 유틸리티(tw-utilities)가 항상 우선순위 최상위 → 필요시 Tailwind 클래스로 Vapor 기본 스타일을 덮어쓰기 쉬움. 또한 Tailwind의 preflight는 기본적으로 비권장(충돌 방지). 꼭 써야 하면 레이어 순서 조정.
/* global.css */
@layer tw-theme, theme, reset, components, utilities, tw-utilities;
@import 'tailwindcss/theme.css' layer(tw-theme);
@import 'tailwindcss/utilities.css' layer(tw-utilities);
@import '@vapor-ui/core/styles.css';
@import '@vapor-ui/core/tailwind.css';
3. Vapor 전용 유틸리티 클래스(토큰 기반)
- @vapor-ui/core/tailwind.css를 넣으면 v- 접두사 유틸리티 사용 가능.
- 예시: bg-v-primary, text-v-danger, p-v-200, rounded-v-300 등. 토큰 네임스페이스(color, spacing, radius, font-weight 등)와 Tailwind 기본 유틸리티를 조합해서 사용. (Vapor UI)
4. 디자인 토큰(색/크기/타이포)
- Color: gray 컬러, 상태 색(primary/secondary/success/warning/danger 등)과 시맨틱 컬러 제공.
- Size: 간격/크기 스케일을 일관되게.
- Typography: 폰트 패밀리, 사이즈, 굵기, line-height 등 시스템화.
- ⭐토큰 페이지를 참고해 임의 값 대신 토큰 우선 사용. 유지보수성↑.
5. 레이아웃 프리미티브 먼저 쓰기
- Box / Flex / Grid / HStack / VStack이 기본 빌딩 블록.
- 예) 레이아웃은 Box, 1차 배치는 Flex(또는 H/VStack), 격자는 Grid로—가능한 한 컴포넌트 속성 + 토큰/유틸리티로 해결.
import { Box, HStack, Grid } from '@vapor-ui/core';
export default function Section() {
return (
<Box padding="$400" backgroundColor="gray-100" borderRadius="$300">
<HStack gap="4">
<div className="p-4 rounded bg-v-primary text-white">A</div>
<div className="p-4 rounded bg-v-secondary text-white">B</div>
</HStack>
<Grid columns="1fr 2fr" gap="$300" className="mt-4">
<div className="bg-v-normal-lighter p-v-200 rounded-v-200">Left</div>
<div className="bg-v-normal p-v-200 rounded-v-200">Right</div>
</Grid>
</Box>
);
}
6. 컴포넌트 패턴(Compound + render prop) — asChild 아님!
Vapor의 다수 컴포넌트는 .Root / .Trigger / .Content ... 식의 컴파운드 패턴을 사용.
- 버튼을 트리거로 감쌀 때 asChild가 아니라 render prop을 씀.
import { Button, Dialog } from '@vapor-ui/core';
export default function Demo() {
return (
<Dialog.Root>
<Dialog.Trigger render={<Button>열기</Button>} />
<Dialog.Content>
<Dialog.Header>
<Dialog.Title>알림</Dialog.Title>
<Dialog.Close aria-label="Close" />
</Dialog.Header>
<Dialog.Body>
<Dialog.Description>본문…</Dialog.Description>
</Dialog.Body>
<Dialog.Footer>
<Dialog.Close render={<Button variant="ghost">취소</Button>} />
<Button color="primary">확인</Button>
</Dialog.Footer>
</Dialog.Content>
</Dialog.Root>
);
}
7. 상태/사이즈/변형 Props의 공통성
- 예: Button은 color(primary|secondary|success|warning|danger|contrast), variant(예: outline, ghost), size 등을 공통 인터페이스처럼 제공. 팀 내에서 허용 색상/사이즈 테이블을 공유해 일관성 유지.
8. 아이콘 사용법
- @vapor-ui/icons에서 바로 import. (Docs의 Icons 페이지에서 클릭하면 import 예시 복사 가능)
- IconButton 같이 텍스트 없는 액션엔 접근성 고려(aria-label 필수).
import { IconButton } from '@vapor-ui/core';
import { HeartIcon } from '@vapor-ui/icons';
<IconButton aria-label="좋아요" render={<HeartIcon />} />;
9. 접근성(A11y) 기본 장착
- Vapor 컴포넌트는 ARIA/키보드 내비게이션을 기본 지원. 하지만 문맥에 맞는 aria-label/Title/Description을 넣는 건 개발자 몫. 다이얼로그엔 Title/Description을 꼭 포함. (Vapor UI)
10. 변경 이력 확인하며 버전 고정
- 컴포넌트 prop/토큰 네이밍이 가끔 바뀌니 Releases를 주기적으로 체크하고 패치 시 팀에 공지. CI에서 @vapor-ui/* 버전 범위를 명시해 예기치 않은 브레이킹 방지. (Vapor UI)
빠른 스타터 체크리스트
- @vapor-ui/core(+ @vapor-ui/icons) 설치 & 전역 styles.css import 완료
- Tailwind v4면 global.css에 레이어/임포트 정확히 배치, @vapor-ui/core/tailwind.css 포함
- 새 화면은 Box/Flex/Grid/HStack/VStack 조합으로 시작
- 색/간격/모서리/폰트는 토큰 기반 유틸리티(v- 접두) 우선 사용
- 모달·툴팁·메뉴 등은 Compound + render prop 패턴으로 구성 (asChild X)
- 아이콘은 @vapor-ui/icons에서 import, 텍스트 없는 컨트롤엔 aria-label 필수
자주 쓰는 컴포넌트 미니 레시피
- 버튼 색/변형 예시
<Button color="primary">확인</Button>
<Button color="secondary" variant="outline">취소</Button>
<Button color="danger" size="sm">삭제</Button>
- 툴팁(트리거는 render 사용)
import { Button, Tooltip } from '@vapor-ui/core';
<Tooltip.Root>
<Tooltip.Trigger render={<Button>툴팁 보기</Button>} />
<Tooltip.Content>유용한 정보</Tooltip.Content>
</Tooltip.Root>;
- 메뉴(드롭다운)
import { Button, Menu } from '@vapor-ui/core';
<Menu.Root>
<Menu.Trigger render={<Button>메뉴 열기</Button>} />
<Menu.Content>
<Menu.Item>새 파일</Menu.Item>
<Menu.Item>복사</Menu.Item>
<Menu.Separator />
<Menu.Item color="danger">삭제</Menu.Item>
</Menu.Content>
</Menu.Root>;
팀의 코딩 규칙 정해보기
- 토큰 우선: 색/간격/반경/폰트는 임의 값 대신 Vapor 토큰(bg-v-*, p-v-*, rounded-v-*) 사용.
- 컴파운드 + render: 서드파티 패턴(asChild 등) 혼용 금지. Vapor 문서 패턴만.
- 레이아웃 계층: Box(섹션) → Flex/HStack/VStack(정렬) → Grid(격자) 순으로 설계.
- A11y: 텍스트 없는 컨트롤에 aria-label 필수, Dialog에 Title/Description 포함.
- 릴리즈 트래킹: 릴리즈 노트 확인 후 버전 범위 적절히 업데이트.
'웹 개발 일기' 카테고리의 다른 글
| 디자인 시스템 사용해보기(1): Vapor (by goorm) (0) | 2025.09.20 |
|---|