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.Trigger value="overview">개요</Tabs.Trigger>
                <Tabs.Trigger value="features">기능</Tabs.Trigger>
                <Tabs.Trigger value="examples">예시</Tabs.Trigger>
                <Tabs.Indicator />
            </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.Trigger value="tab1">Tab 1</Tabs.Trigger>
                    <Tabs.Trigger value="tab2">Tab 2</Tabs.Trigger>
                    <Tabs.Trigger value="tab3">Tab 3</Tabs.Trigger>
                    <Tabs.Indicator />
                </Tabs.List>
            </Tabs.Root>

            <Tabs.Root defaultValue="tab1" size="md">
                <h4 className="text-sm font-medium mb-2">Medium</h4>
                <Tabs.List>
                    <Tabs.Trigger value="tab1">Tab 1</Tabs.Trigger>
                    <Tabs.Trigger value="tab2">Tab 2</Tabs.Trigger>
                    <Tabs.Trigger value="tab3">Tab 3</Tabs.Trigger>
                    <Tabs.Indicator />
                </Tabs.List>
            </Tabs.Root>

            <Tabs.Root defaultValue="tab1" size="lg">
                <h4 className="text-sm font-medium mb-2">Large</h4>
                <Tabs.List>
                    <Tabs.Trigger value="tab1">Tab 1</Tabs.Trigger>
                    <Tabs.Trigger value="tab2">Tab 2</Tabs.Trigger>
                    <Tabs.Trigger value="tab3">Tab 3</Tabs.Trigger>
                    <Tabs.Indicator />
                </Tabs.List>
            </Tabs.Root>

            <Tabs.Root defaultValue="tab1" size="xl">
                <h4 className="text-sm font-medium mb-2">Extra Large</h4>
                <Tabs.List>
                    <Tabs.Trigger value="tab1">Tab 1</Tabs.Trigger>
                    <Tabs.Trigger value="tab2">Tab 2</Tabs.Trigger>
                    <Tabs.Trigger value="tab3">Tab 3</Tabs.Trigger>
                    <Tabs.Indicator />
                </Tabs.List>
            </Tabs.Root>
        </VStack>
    );
}

Variant

Tabs는 line과 plain 두 가지 스타일 변형을 제공합니다.

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.Trigger value="home"></Tabs.Trigger>
                    <Tabs.Trigger value="about">소개</Tabs.Trigger>
                    <Tabs.Trigger value="services">서비스</Tabs.Trigger>
                    <Tabs.Indicator />
                </Tabs.List>
            </Tabs.Root>

            <Tabs.Root defaultValue="home" variant="plain">
                <h4 className="text-sm font-medium mb-4">Plain 변형</h4>
                <Tabs.List>
                    <Tabs.Trigger value="home"></Tabs.Trigger>
                    <Tabs.Trigger value="about">소개</Tabs.Trigger>
                    <Tabs.Trigger value="services">서비스</Tabs.Trigger>
                    <Tabs.Indicator />
                </Tabs.List>
            </Tabs.Root>
        </VStack>
    );
}

Orientation

Tabs는 수평(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.Trigger value={1}>Tab 1</Tabs.Trigger>
                        <Tabs.Trigger value={2}>Tab 2</Tabs.Trigger>
                        <Tabs.Trigger value={3}>Tab 3</Tabs.Trigger>
                        <Tabs.Indicator />
                    </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.Trigger value={1}>Tab 1</Tabs.Trigger>
                        <Tabs.Trigger value={2}>Tab 2</Tabs.Trigger>
                        <Tabs.Trigger value={3}>Tab 3</Tabs.Trigger>
                        <Tabs.Indicator />
                    </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.Trigger value="profile">프로필</Tabs.Trigger>
                    <Tabs.Trigger value="account">계정</Tabs.Trigger>
                    <Tabs.Trigger value="security">보안</Tabs.Trigger>
                    <Tabs.Trigger value="notifications">알림</Tabs.Trigger>
                    <Tabs.Indicator />
                </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 color="success" onClick={() => setActiveTab('security')} className="">
                    보안 탭으로 이동
                </Button>
            </div>
        </VStack>
    );
}

States

Tabs의 다양한 상태(개별 탭 비활성화, 전체 탭 그룹 비활성화)를 설정할 수 있습니다.

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.Trigger value="enabled">활성화 탭</Tabs.Trigger>
                    <Tabs.Trigger value="disabled" disabled>
                        비활성화 탭
                    </Tabs.Trigger>
                    <Tabs.Trigger value="normal">일반 탭</Tabs.Trigger>
                    <Tabs.Indicator />
                </Tabs.List>
            </Tabs.Root>

            <Tabs.Root defaultValue="enabled" disabled>
                <h4 className="text-sm font-medium mb-4">전체 탭 그룹 비활성화</h4>
                <Tabs.List>
                    <Tabs.Trigger value="enabled">활성화 탭</Tabs.Trigger>
                    <Tabs.Trigger value="disabled">비활성화 탭</Tabs.Trigger>
                    <Tabs.Trigger value="normal">일반 탭</Tabs.Trigger>
                    <Tabs.Indicator />
                </Tabs.List>
            </Tabs.Root>
        </VStack>
    );
}

Examples


Keyboard Navigation

Tabs는 완전한 키보드 내비게이션을 지원합니다. 포커스 동작과 순환 내비게이션을 세밀하게 제어할 수 있습니다.

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.Trigger value="tab1">탭 1</Tabs.Trigger>
                    <Tabs.Trigger value="tab2">탭 2</Tabs.Trigger>
                    <Tabs.Trigger value="tab3">탭 3</Tabs.Trigger>
                    <Tabs.Indicator />
                </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.Trigger value="tab1">탭 1</Tabs.Trigger>
                    <Tabs.Trigger value="tab2">탭 2</Tabs.Trigger>
                    <Tabs.Trigger value="tab3">탭 3</Tabs.Trigger>
                    <Tabs.Indicator />
                </Tabs.List>
            </Tabs.Root>

            <Tabs.Root defaultValue="tab1" loop={true} activateOnFocus={false}>
                <h4 className="text-sm font-medium mb-4">
                    순환 내비게이션 <code>(loop: true)</code>
                </h4>
                <Tabs.List>
                    <Tabs.Trigger value="tab1">탭 1</Tabs.Trigger>
                    <Tabs.Trigger value="tab2">탭 2</Tabs.Trigger>
                    <Tabs.Trigger value="tab3">탭 3</Tabs.Trigger>
                    <Tabs.Indicator />
                </Tabs.List>
            </Tabs.Root>
        </VStack>
    );
}

Props Table


Tabs.Root

Tabs의 루트 컨테이너로, 전체 Tabs 컴포넌트의 상태와 동작을 관리합니다.

PropDefaultType
variant?
'line'
'line''plain'
size?
'md'
'sm''md''lg''xl'
orientation?
'horizontal'
'horizontal''vertical'
disabled?
false
boolean
activateOnFocus?
true
boolean
loop?
true
boolean
value?
null
string
defaultValue?
null
string
onValueChange?
null
(value: string) => void
className?
null
string

Tabs.List

탭 트리거들을 담는 컨테이너입니다. 탭의 배치와 스타일을 관리합니다.

PropDefaultType
className?
null
string
children?
null
React.ReactNode

Tabs.Trigger

개별 탭을 나타내는 버튼 컴포넌트입니다. 클릭하거나 키보드로 활성화할 수 있습니다.

PropDefaultType
value?
null
string
disabled?
false
boolean
className?
null
string
children?
null
React.ReactNode

Tabs.Indicator

현재 활성화된 탭을 시각적으로 표시하는 인디케이터입니다. 탭 전환 시 부드럽게 이동합니다.

PropDefaultType
className?
null
string
children?
null
React.ReactNode

Tabs.Panel

각 탭에 연결된 콘텐츠 패널입니다. 해당 탭이 활성화되었을 때만 표시됩니다.

PropDefaultType
value?
null
string
className?
null
string
children?
null
React.ReactNode