Tabs
Tabs는 관련된 콘텐츠를 탭 형태로 구성하여 사용자가 쉽게 전환할 수 있도록 하는 컴포넌트입니다. 키보드 내비게이션, 접근성, 다양한 스타일 변형을 지원합니다.import { Tabs } from '@vapor-ui/core';
import { AiSmartieIcon, AssignmentIcon, ListIcon } from '@vapor-ui/icons';
export default function DefaultTabs() {
return (
<Tabs.Root defaultValue="overview" className="max-w-[200px] w-full mx-auto">
<Tabs.List>
<Tabs.Button value="overview">개요</Tabs.Button>
<Tabs.Button value="features">기능</Tabs.Button>
<Tabs.Button value="examples">예시</Tabs.Button>
</Tabs.List>
<Tabs.Panel value="overview" className="h-[100px] flex items-center justify-center">
<AssignmentIcon size="32px" />
</Tabs.Panel>
<Tabs.Panel value="features" className="h-[100px] flex items-center justify-center">
<AiSmartieIcon size="32px" />
</Tabs.Panel>
<Tabs.Panel value="examples" className="h-[100px] flex items-center justify-center">
<ListIcon size="32px" />
</Tabs.Panel>
</Tabs.Root>
);
}Property
Size
Tabs의 크기를 지정합니다. sm, md, lg, xl 네 가지 크기를 제공합니다.
import { Tabs, VStack } from '@vapor-ui/core';
export default function TabsSize() {
return (
<VStack gap="$400">
<Tabs.Root defaultValue="tab1" size="sm">
<h4 className="text-sm font-medium mb-2">Small</h4>
<Tabs.List>
<Tabs.Button value="tab1">Tab 1</Tabs.Button>
<Tabs.Button value="tab2">Tab 2</Tabs.Button>
<Tabs.Button value="tab3">Tab 3</Tabs.Button>
</Tabs.List>
</Tabs.Root>
<Tabs.Root defaultValue="tab1" size="md">
<h4 className="text-sm font-medium mb-2">Medium</h4>
<Tabs.List>
<Tabs.Button value="tab1">Tab 1</Tabs.Button>
<Tabs.Button value="tab2">Tab 2</Tabs.Button>
<Tabs.Button value="tab3">Tab 3</Tabs.Button>
</Tabs.List>
</Tabs.Root>
<Tabs.Root defaultValue="tab1" size="lg">
<h4 className="text-sm font-medium mb-2">Large</h4>
<Tabs.List>
<Tabs.Button value="tab1">Tab 1</Tabs.Button>
<Tabs.Button value="tab2">Tab 2</Tabs.Button>
<Tabs.Button value="tab3">Tab 3</Tabs.Button>
</Tabs.List>
</Tabs.Root>
<Tabs.Root defaultValue="tab1" size="xl">
<h4 className="text-sm font-medium mb-2">Extra Large</h4>
<Tabs.List>
<Tabs.Button value="tab1">Tab 1</Tabs.Button>
<Tabs.Button value="tab2">Tab 2</Tabs.Button>
<Tabs.Button value="tab3">Tab 3</Tabs.Button>
</Tabs.List>
</Tabs.Root>
</VStack>
);
}Variant
Tabs의 스타일 변형을 설정합니다. line과 fill 두 가지 스타일을 제공합니다.
import { Tabs, VStack } from '@vapor-ui/core';
export default function TabsVariant() {
return (
<VStack gap="$400">
<Tabs.Root defaultValue="home" variant="line">
<h4 className="text-sm font-medium mb-4">Line 변형</h4>
<Tabs.List className={'max-w-[400px] w-full mx-auto'}>
<Tabs.Button value="home">홈</Tabs.Button>
<Tabs.Button value="about">소개</Tabs.Button>
<Tabs.Button value="services">서비스</Tabs.Button>
</Tabs.List>
</Tabs.Root>
<Tabs.Root defaultValue="home" variant="fill">
<h4 className="text-sm font-medium mb-4">fill 변형</h4>
<Tabs.List>
<Tabs.Button value="home">홈</Tabs.Button>
<Tabs.Button value="about">소개</Tabs.Button>
<Tabs.Button value="services">서비스</Tabs.Button>
</Tabs.List>
</Tabs.Root>
</VStack>
);
}Orientation
수평(horizontal)과 수직(vertical) 방향을 설정합니다.
import { Grid, Tabs } from '@vapor-ui/core';
export default function TabsOrientation() {
return (
<Grid.Root gap="$500" templateColumns="1fr 1fr">
<Grid.Item>
<h4 className="text-sm font-medium mb-4">수평 (Horizontal)</h4>
<Tabs.Root defaultValue={1} orientation="horizontal">
<Tabs.List>
<Tabs.Button value={1}>Tab 1</Tabs.Button>
<Tabs.Button value={2}>Tab 2</Tabs.Button>
<Tabs.Button value={3}>Tab 3</Tabs.Button>
</Tabs.List>
</Tabs.Root>
</Grid.Item>
<Grid.Item>
<h4 className="text-sm font-medium mb-4 flex justify-center">수직 (Vertical)</h4>
<Tabs.Root defaultValue={1} orientation="vertical" className="flex justify-center">
<Tabs.List>
<Tabs.Button value={1}>Tab 1</Tabs.Button>
<Tabs.Button value={2}>Tab 2</Tabs.Button>
<Tabs.Button value={3}>Tab 3</Tabs.Button>
</Tabs.List>
</Tabs.Root>
</Grid.Item>
</Grid.Root>
);
}Controlled State
Tabs의 활성 상태를 외부에서 제어합니다.
'use client';
import { useState } from 'react';
import { Button, Tabs, VStack } from '@vapor-ui/core';
export default function TabsControlled() {
const [activeTab, setActiveTab] = useState('profile');
return (
<VStack gap="$200">
<Tabs.Root value={activeTab} onValueChange={setActiveTab}>
<Tabs.List>
<Tabs.Button value="profile">프로필</Tabs.Button>
<Tabs.Button value="account">계정</Tabs.Button>
<Tabs.Button value="security">보안</Tabs.Button>
<Tabs.Button value="notifications">알림</Tabs.Button>
</Tabs.List>
</Tabs.Root>
<div className="text-sm text-gray-600">
현재 선택된 탭: <code className="bg-gray-100 px-1 rounded">{activeTab}</code>
</div>
<div className="flex gap-2">
<Button onClick={() => setActiveTab('account')} className="">
계정 탭으로 이동
</Button>
<Button
colorPalette="success"
onClick={() => setActiveTab('security')}
className=""
>
보안 탭으로 이동
</Button>
</div>
</VStack>
);
}States
개별 탭 또는 전체 탭 그룹을 비활성화할 수 있습니다.
import { Tabs, VStack } from '@vapor-ui/core';
export default function TabsStates() {
return (
<VStack gap="$400">
<Tabs.Root defaultValue="enabled">
<h4 className="text-sm font-medium mb-4">개별 탭 비활성화</h4>
<Tabs.List>
<Tabs.Button value="enabled">활성화 탭</Tabs.Button>
<Tabs.Button value="disabled" disabled>
비활성화 탭
</Tabs.Button>
<Tabs.Button value="normal">일반 탭</Tabs.Button>
</Tabs.List>
</Tabs.Root>
<Tabs.Root defaultValue="enabled" disabled>
<h4 className="text-sm font-medium mb-4">전체 탭 그룹 비활성화</h4>
<Tabs.List>
<Tabs.Button value="enabled">활성화 탭</Tabs.Button>
<Tabs.Button value="disabled">비활성화 탭</Tabs.Button>
<Tabs.Button value="normal">일반 탭</Tabs.Button>
</Tabs.List>
</Tabs.Root>
</VStack>
);
}Examples
Keyboard Navigation
activateOnFocus와 loop props를 사용하여 키보드 내비게이션 동작을 세밀하게 제어할 수 있습니다.
import { Tabs, VStack } from '@vapor-ui/core';
export default function TabsKeyboard() {
return (
<VStack gap="$400">
<Tabs.Root defaultValue="tab1" activateOnFocus={true}>
<h4 className="text-sm font-medium mb-4">
포커스 시 활성화 <code>(activateOnFocus: true)</code>
</h4>
<Tabs.List>
<Tabs.Button value="tab1">탭 1</Tabs.Button>
<Tabs.Button value="tab2">탭 2</Tabs.Button>
<Tabs.Button value="tab3">탭 3</Tabs.Button>
</Tabs.List>
</Tabs.Root>
<Tabs.Root defaultValue="tab1" activateOnFocus={false}>
<h4 className="text-sm font-medium mb-4">
엔터/스페이스로 활성화 <code>(activateOnFocus: false)</code>
</h4>
<Tabs.List>
<Tabs.Button value="tab1">탭 1</Tabs.Button>
<Tabs.Button value="tab2">탭 2</Tabs.Button>
<Tabs.Button value="tab3">탭 3</Tabs.Button>
</Tabs.List>
</Tabs.Root>
<Tabs.Root defaultValue="tab1" loop={true} activateOnFocus={false}>
<h4 className="text-sm font-medium mb-4">
비순환 내비게이션 <code>(loop: false)</code>
</h4>
<Tabs.List loop={false}>
<Tabs.Button value="tab1">탭 1</Tabs.Button>
<Tabs.Button value="tab2">탭 2</Tabs.Button>
<Tabs.Button value="tab3">탭 3</Tabs.Button>
</Tabs.List>
</Tabs.Root>
</VStack>
);
}Without Panel
Tabs.Panel 없이 외부 상태로 콘텐츠를 관리할 수 있습니다.
'use client';
import { useState } from 'react';
import { Tabs, Text, VStack } from '@vapor-ui/core';
const CONTENT_MAP = {
home: { title: '홈', description: '홈 페이지 콘텐츠입니다.' },
about: { title: '소개', description: '회사 소개 콘텐츠입니다.' },
services: { title: '서비스', description: '서비스 안내 콘텐츠입니다.' },
} as const;
export default function TabsWithoutPanel() {
const [activeTab, setActiveTab] = useState<keyof typeof CONTENT_MAP>('home');
return (
<VStack gap="$300">
<Tabs.Root
value={activeTab}
onValueChange={(value) => setActiveTab(value as keyof typeof CONTENT_MAP)}
>
<Tabs.List>
<Tabs.Button value="home">홈</Tabs.Button>
<Tabs.Button value="about">소개</Tabs.Button>
<Tabs.Button value="services">서비스</Tabs.Button>
</Tabs.List>
</Tabs.Root>
<VStack padding="$400" border="1px solid" borderColor="$gray-200" borderRadius="$300">
<Text typography="heading4">{CONTENT_MAP[activeTab].title}</Text>
<Text typography="body2">{CONTENT_MAP[activeTab].description}</Text>
</VStack>
</VStack>
);
}Custom Indicator
Tabs.List는 기본적으로 Tabs.IndicatorPrimitive를 포함합니다. Indicator를 커스터마이징하려면 indicatorElement prop을 사용하세요.
import { Button, Tabs } from '@vapor-ui/core';
export default function TabsCustomIndicator() {
return (
<Tabs.Root defaultValue="home">
<Tabs.List
indicatorElement={
<Tabs.IndicatorPrimitive
className="bg-gradient-to-r from-red-600 to-orange-400"
style={{ height: '4px', borderRadius: '2px' }}
/>
}
>
<Button width="5rem">hi</Button>
<Tabs.Button value="home" width="5rem">
홈
</Tabs.Button>
<Tabs.Button value="about" width="5rem">
소개
</Tabs.Button>
<Tabs.Button value="services" width="5rem">
서비스
</Tabs.Button>
</Tabs.List>
</Tabs.Root>
);
}Props Table
Tabs.Root
Loading component documentation...
Tabs.List
Loading component documentation...
Tabs.ListPrimitive
Loading component documentation...
Tabs.IndicatorPrimitive
Loading component documentation...
Tabs.Button
Loading component documentation...
Tabs.Panel
Loading component documentation...