Tab
탭 형태로 콘텐츠를 전환할 수 있는 Tab 컴포넌트입니다. Root, List, Trigger, Content로 구성된 Compound 패턴으로 유연한 커스터마이징이 가능합니다. underline과 pill 두 가지 스타일을 제공하며, horizontal/vertical 방향 전환을 지원하고, automatic/manual 두 가지 활성화 모드를 선택할 수 있습니다. 많은 탭이 있을 때 드래그 스크롤 및 자동 센터링 기능을 제공하며, 화살표 키 네비게이션과 비활성 탭 건너뛰기를 지원합니다. ARIA 속성을 통한 완벽한 접근성 지원, asChild 패턴을 통한 커스텀 렌더링, forceMount를 통한 성능 최적화, CSS 변수를 통한 색상 커스터마이징을 제공합니다.
미리보기
이메일 주소, 프로필 정보, 계정 삭제 등 계정과 관련된 설정을 관리할 수 있습니다.
사용법
TSX
1"use client";
2
3import { Tab } from "motile-ui";
4
5export default function PreviewExample() {
6 return (
7 <Tab defaultValue="account">
8 <Tab.List>
9 <Tab.Trigger value="account">계정</Tab.Trigger>
10 <Tab.Trigger value="password">비밀번호</Tab.Trigger>
11 <Tab.Trigger value="notifications">알림</Tab.Trigger>
12 </Tab.List>
13
14 <Tab.Content value="account">
15 <p>
16 이메일 주소, 프로필 정보, 계정 삭제 등 계정과 관련된 설정을 관리할 수
17 있습니다.
18 </p>
19 </Tab.Content>
20
21 <Tab.Content value="password">
22 <p>안전한 비밀번호로 정기적으로 변경하여 계정 보안을 강화하세요.</p>
23 </Tab.Content>
24
25 <Tab.Content value="notifications">
26 <p>
27 이메일 알림, 푸시 알림 등 원하는 알림 방식을 선택할 수 있습니다.
28 </p>
29 </Tab.Content>
30 </Tab>
31 );
32}API 레퍼런스
Tab
탭의 상태와 설정을 관리하는 최상위 컴포넌트
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
value | string | - | 현재 활성화된 탭 값 (제어 모드) |
defaultValue | string | - | 초기 활성화 탭 값 (비제어 모드) |
onValueChange | (value: string) => void | - | 탭이 변경될 때 실행되는 함수 |
activationMode | "automatic" | "manual" | "automatic" | 탭 활성화 모드 (automatic: 포커스 시 자동 활성화, manual: Enter/Space로 활성화) |
orientation | "horizontal" | "vertical" | "horizontal" | 탭 방향 (horizontal: 수평, vertical: 수직) |
variant | "underline" | "pill" | "underline" | 탭 스타일 (underline: 밑줄, pill: 둥근 배경) |
disabled | boolean | false | 모든 탭 비활성화 여부 |
color | string | - | 커스텀 색상 (활성 탭 및 인디케이터 색상) |
asChild | boolean | false | 래퍼 없이 자식 요소만 렌더링 |
Tab.List
탭 트리거들을 담는 컨테이너
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
asChild | boolean | false | 래퍼 없이 자식 요소만 렌더링 |
기본 <code>div</code> HTML 속성을 모두 사용할 수 있습니다.
Tab.Trigger
클릭하여 탭을 전환하는 버튼
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
value | string | - | 탭 트리거의 고유 값 |
disabled | boolean | false | 개별 탭 트리거 비활성화 여부 |
asChild | boolean | false | 래퍼 없이 자식 요소만 렌더링 |
기본 <code>button</code> HTML 속성을 모두 사용할 수 있습니다.
Tab.Content
선택된 탭에 표시될 콘텐츠
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
value | string | - | 표시할 콘텐츠의 탭 값 |
forceMount | boolean | false | 비활성 상태에서도 DOM에 유지 (숨김 처리) |
asChild | boolean | false | 래퍼 없이 자식 요소만 렌더링 |
기본 <code>div</code> HTML 속성을 모두 사용할 수 있습니다.
예제
Pill 스타일
사용자의 기본 프로필 정보를 관리합니다.
TSX
1"use client";
2
3import { Tab } from "motile-ui";
4
5export default function DefaultExample() {
6 return (
7 <Tab defaultValue="profile" variant="pill">
8 <Tab.List>
9 <Tab.Trigger value="profile">프로필</Tab.Trigger>
10 <Tab.Trigger value="settings">설정</Tab.Trigger>
11 <Tab.Trigger value="notifications">알림</Tab.Trigger>
12 </Tab.List>
13
14 <Tab.Content value="profile">
15 사용자의 기본 프로필 정보를 관리합니다.
16 </Tab.Content>
17
18 <Tab.Content value="settings">
19 앱의 다양한 설정을 변경할 수 있습니다.
20 </Tab.Content>
21
22 <Tab.Content value="notifications">
23 알림 설정을 관리하고 알림 내역을 확인합니다.
24 </Tab.Content>
25 </Tab>
26 );
27}세로 방향 (Vertical)
사용자의 기본 프로필 정보를 관리합니다.
TSX
1"use client";
2
3import { Tab } from "motile-ui";
4
5export default function ControlledExample() {
6 return (
7 <Tab defaultValue="profile" orientation="vertical">
8 <Tab.List>
9 <Tab.Trigger value="profile">프로필</Tab.Trigger>
10 <Tab.Trigger value="settings">설정</Tab.Trigger>
11 <Tab.Trigger value="notifications">알림</Tab.Trigger>
12 </Tab.List>
13
14 <Tab.Content value="profile">
15 <div style={{ padding: "16px", color: "#666" }}>
16 사용자의 기본 프로필 정보를 관리합니다.
17 </div>
18 </Tab.Content>
19
20 <Tab.Content value="settings">
21 <div style={{ padding: "16px", color: "#666" }}>
22 앱의 다양한 설정을 변경할 수 있습니다.
23 </div>
24 </Tab.Content>
25
26 <Tab.Content value="notifications">
27 <div style={{ padding: "16px", color: "#666" }}>
28 알림 설정을 관리하고 알림 내역을 확인합니다.
29 </div>
30 </Tab.Content>
31 </Tab>
32 );
33}비활성화
최신 업데이트와 추천 콘텐츠를 확인합니다.
TSX
1"use client";
2
3import { Tab } from "motile-ui";
4
5export default function DisabledExample() {
6 return (
7 <Tab defaultValue="home" variant="pill">
8 <Tab.List>
9 <Tab.Trigger value="home">홈</Tab.Trigger>
10 <Tab.Trigger value="settings" disabled>
11 설정
12 </Tab.Trigger>
13 <Tab.Trigger value="profile">
14 프로필
15 </Tab.Trigger>
16 </Tab.List>
17
18 <Tab.Content value="home">
19 <div style={{ padding: "16px", color: "#666" }}>
20 최신 업데이트와 추천 콘텐츠를 확인합니다.
21 </div>
22 </Tab.Content>
23
24 <Tab.Content value="settings">
25 <div style={{ padding: "16px", color: "#666" }}>
26 이 기능은 현재 사용할 수 없습니다.
27 </div>
28 </Tab.Content>
29
30 <Tab.Content value="profile">
31 <div style={{ padding: "16px", color: "#666" }}>
32 사용자의 프로필 정보를 관리합니다.
33 </div>
34 </Tab.Content>
35 </Tab>
36 );
37}Manual Activation
💡 키보드 화살표로 이동 후 Enter 또는 Space를 눌러 탭을 활성화하세요.
코드를 작성하고 편집합니다.
TSX
1"use client";
2
3import { Tab } from "motile-ui";
4
5export default function ManualActivationExample() {
6 return (
7 <div>
8 <div
9 style={{
10 marginBottom: "16px",
11 padding: "12px",
12 background: "#f0f9ff",
13 borderRadius: "8px",
14 fontSize: "14px",
15 color: "#0369a1",
16 }}
17 >
18 💡 키보드 화살표로 이동 후 Enter 또는 Space를 눌러 탭을 활성화하세요.
19 </div>
20
21 <Tab defaultValue="code" activationMode="manual">
22 <Tab.List>
23 <Tab.Trigger value="code">코드</Tab.Trigger>
24 <Tab.Trigger value="preview">미리보기</Tab.Trigger>
25 <Tab.Trigger value="console">콘솔</Tab.Trigger>
26 </Tab.List>
27
28 <Tab.Content value="code">
29 <div style={{ padding: "16px", color: "#666" }}>
30 코드를 작성하고 편집합니다.
31 </div>
32 </Tab.Content>
33
34 <Tab.Content value="preview">
35 <div style={{ padding: "16px", color: "#666" }}>
36 작성한 코드의 실행 결과를 확인합니다.
37 </div>
38 </Tab.Content>
39
40 <Tab.Content value="console">
41 <div style={{ padding: "16px", color: "#666" }}>
42 로그와 오류 메시지를 확인합니다.
43 </div>
44 </Tab.Content>
45 </Tab>
46 </div>
47 );
48}많은 탭 스크롤
디지털 관련 상품을 둘러보세요.
TSX
1"use client";
2
3import { Tab } from "motile-ui";
4
5export default function ScrollExample() {
6 const categories = [
7 { value: "all", label: "전체" },
8 { value: "electronics", label: "전자제품" },
9 { value: "fashion", label: "패션" },
10 { value: "books", label: "도서" },
11 { value: "food", label: "식품" },
12 { value: "furniture", label: "가구" },
13 { value: "toys", label: "완구" },
14 { value: "sports", label: "스포츠" },
15 { value: "beauty", label: "뷰티" },
16 { value: "pet", label: "반려동물" },
17 { value: "digital", label: "디지털" },
18 { value: "home", label: "홈데코" },
19 { value: "kitchen", label: "주방용품" },
20 { value: "health", label: "건강" },
21 { value: "auto", label: "자동차" },
22 { value: "music", label: "음악" },
23 { value: "game", label: "게임" },
24 { value: "office", label: "문구" },
25 ];
26
27 return (
28 <Tab defaultValue="digital" variant="pill">
29 <Tab.List>
30 {categories.map((cat) => (
31 <Tab.Trigger key={cat.value} value={cat.value}>
32 {cat.label}
33 </Tab.Trigger>
34 ))}
35 </Tab.List>
36
37 {categories.map((cat) => (
38 <Tab.Content key={cat.value} value={cat.value}>
39 <div style={{ padding: "16px", color: "#666" }}>
40 {cat.label} 관련 상품을 둘러보세요.
41 </div>
42 </Tab.Content>
43 ))}
44 </Tab>
45 );
46}