Segmented
Segmented는 단일 선택을 위한 pill형 컨트롤입니다. 필터나 뷰 전환에 적합합니다.
Playground
<Segmented defaultValue="play">
<Segmented.Item value="prev">Prev</Segmented.Item>
<Segmented.Item value="play">Play</Segmented.Item>
<Segmented.Item value="next">Next</Segmented.Item>
</Segmented>Variants
defaultPill StyleoutlineBordered StyleunderlineTab StyleghostMinimal StyleSizes
Text Only
smmddefaultlg| Size | 높이 | 가로 패딩 | 폰트 | 미리보기 |
|---|---|---|---|---|
sm | 32px | 14px | 12px | |
md | 36px | 14px | 13px | |
default | 40px | 16px | 13px | |
lg | 48px | 24px | 14px |
Icon Only (정사각형)
smmddefaultlg| Size | 컨테이너 높이 | 아이템 크기 | 아이콘 | 미리보기 |
|---|---|---|---|---|
sm | 32px | 24px × 24px | 14px | |
md | 36px | 28px × 28px | 16px | |
default | 40px | 32px × 32px | 16px | |
lg | 48px | 40px × 40px | 16px |
Icon + Text
smmddefaultlg| Size | 높이 | 가로 패딩 | Gap | 아이콘 | 폰트 | 미리보기 |
|---|---|---|---|---|---|---|
sm | 32px | 12px | 8px | 14px | 12px | |
md | 36px | 14px | 8px | 16px | 13px | |
default | 40px | 16px | 8px | 16px | 13px | |
lg | 48px | 24px | 8px | 16px | 14px |
Features
Use Cases
Notion, Linear, 태스크 관리 앱
Stripe, Google Analytics, 대시보드
Figma, Notion, 프로젝트 관리 도구
SaaS 요금 페이지, 구독 서비스
// Status Filter — Notion, Linear style
<Segmented defaultValue="all">
<Segmented.Item value="all">전체</Segmented.Item>
<Segmented.Item value="active">활성</Segmented.Item>
<Segmented.Item value="completed">완료</Segmented.Item>
</Segmented>
// Date Range Filter — Stripe, Analytics style
<Segmented defaultValue="30d">
<Segmented.Item value="7d">7일</Segmented.Item>
<Segmented.Item value="30d">30일</Segmented.Item>
<Segmented.Item value="90d">90일</Segmented.Item>
</Segmented>
// View Switch — Figma, Notion style
<Segmented defaultValue="table">
<Segmented.Item value="table">테이블</Segmented.Item>
<Segmented.Item value="board">보드</Segmented.Item>
<Segmented.Item value="calendar">캘린더</Segmented.Item>
</Segmented>
// Billing Cycle — SaaS pricing style
<Segmented defaultValue="yearly">
<Segmented.Item value="monthly">월간</Segmented.Item>
<Segmented.Item value="yearly">연간</Segmented.Item>
</Segmented>States
Default
선택된 아이템이 하이라이트로 표시됩니다.
Disabled
모든 아이템이 비활성화된 상태입니다.
부분 Disabled
특정 아이템만 비활성화됩니다.
다수 아이템
2~5개 아이템에 최적입니다.
API
Component Structure
Segmented— Radix RadioGroup.ItemProps세그먼트 아이템Props
Segmented
valueundefinedstring제어 모드에서 선택된 값
defaultValueundefinedstring비제어 모드에서 초기 선택값
onValueChangeundefined(value: string) => void선택 변경 시 콜백
variant"default""default" | "outline" | "underline" | "ghost"스타일 변형 (default: iOS 스타일, outline: 테두리, underline: Stripe 스타일, ghost: Notion 스타일)
size"default""sm" | "md" | "default" | "lg"세그먼트 크기 (32/36/40/48px)
radius"default""none" | "sm" | "base" | "default" | "lg" | "xl" | "2xl" | "3xl" | "full"모서리 둥글기 (6px)
fontWeight"normal""normal" | "semibold"모든 아이템에 적용되는 폰트 굵기
disabledfalseboolean모든 아이템 비활성화
| Name | Type | Default | Description |
|---|---|---|---|
value | string | undefined | 제어 모드에서 선택된 값 |
defaultValue | string | undefined | 비제어 모드에서 초기 선택값 |
onValueChange | (value: string) => void | undefined | 선택 변경 시 콜백 |
variant | "default" | "outline" | "underline" | "ghost" | "default" | 스타일 변형 (default: iOS 스타일, outline: 테두리, underline: Stripe 스타일, ghost: Notion 스타일) |
size | "sm" | "md" | "default" | "lg" | "default" | 세그먼트 크기 (32/36/40/48px) |
radius | "none" | "sm" | "base" | "default" | "lg" | "xl" | "2xl" | "3xl" | "full" | "default" | 모서리 둥글기 (6px) |
fontWeight | "normal" | "semibold" | "normal" | 모든 아이템에 적용되는 폰트 굵기 |
disabled | boolean | false | 모든 아이템 비활성화 |
Segmented.Item
value—string아이템의 고유값
disabledfalseboolean개별 비활성화
sizeinherit"sm" | "md" | "default" | "lg"개별 크기 재정의
radiusinherit"none" | "sm" | ... | "full"개별 모서리 재정의
contentType"text""text" | "icon-text" | "icon"콘텐츠 유형 (icon: 정사각형, icon-text: 간격 포함, text: 기본)
| Name | Type | Default | Description |
|---|---|---|---|
value | string | — | 아이템의 고유값 |
disabled | boolean | false | 개별 비활성화 |
size | "sm" | "md" | "default" | "lg" | inherit | 개별 크기 재정의 |
radius | "none" | "sm" | ... | "full" | inherit | 개별 모서리 재정의 |
contentType | "text" | "icon-text" | "icon" | "text" | 콘텐츠 유형 (icon: 정사각형, icon-text: 간격 포함, text: 기본) |
Customization
모든 아이템은 디자인 시스템 스페이싱 규칙에 따른 기본값을 사용합니다. 그룹의 className으로 전체 아이템을 일괄 커스터마이즈할 수 있습니다.
가로 패딩 변경
className="[&>button]:px-10"Icon Only 너비 변경
className="[&>button]:aspect-auto [&>button]:px-5"Tip:기본값은 일관성을 유지하도록 설계되어 있습니다. 필요한 경우에만 커스터마이즈하세요.
Anatomy
Best Practices
권장
- ✓2~5개 선택지에 사용
- ✓같은 콘텐츠 영역 내 뷰 전환에 사용
- ✓라벨은 짧고 간결하게 (1~2단어)
- ✓필터나 정렬 전환에 최적
지양
- ✗6개 이상의 옵션에는 사용하지 않기
- ✗페이지 내비게이션에는 사용하지 않기 (→ Tabs)
- ✗다중 선택이 필요한 경우 사용하지 않기 (→ ToggleGroup)
- ✗긴 라벨 텍스트 사용하지 않기
Accessibility
키보드 조작
ARIA 속성
role="radiogroup"자동 부여role="radio"각 아이템에 부여aria-checked자동 업데이트- 포커스 인디케이터
Segmented vs Tabs
비슷한 외관이지만 용도와 구조가 다릅니다. 적절한 컴포넌트를 선택하세요.
용도
Segmented: 값 선택 (필터, 전환)
Tabs: 콘텐츠 내비게이션
구조
Segmented: 단독 컴포넌트
Tabs: TabList + TabPanel 조합
결과
Segmented: 같은 영역 내 데이터 변경
Tabs: 패널 전환
배치
Segmented: 콘텐츠 내 어디서나
Tabs: 페이지/섹션 상단
Radix Primitive
Segmented: RadioGroup
Tabs: @radix-ui/react-tabs
| 특징 | Segmented | Tabs |
|---|---|---|
| 용도 | 값 선택 (필터, 전환) | 콘텐츠 내비게이션 |
| 구조 | 단독 컴포넌트 | TabList + TabPanel 조합 |
| 결과 | 같은 영역 내 데이터 변경 | 패널 전환 |
| 배치 | 콘텐츠 내 어디서나 | 페이지/섹션 상단 |
| Radix Primitive | RadioGroup | @radix-ui/react-tabs |
같은 콘텐츠 영역 내에서 뷰를 변경할 때는 Segmented, 다른 콘텐츠 패널을 전환할 때는 Tabs를 사용하세요.