Allra Fintech
Navigation

Tabs

탭 네비게이션을 위한 컴포넌트

Description

Tabs는 콘텐츠를 여러 섹션으로 나누어 표시할 때 사용하는 네비게이션 컴포넌트입니다. 두 가지 스타일을 제공합니다:

  • Box Tabs: 둥근 모서리의 박스 스타일 탭
  • Linear Tabs: 하단 테두리가 있는 선형 스타일 탭

각 탭을 클릭하면 해당 콘텐츠로 전환되며, controlled와 uncontrolled 모드를 모두 지원합니다.

선택된 탭: all
"use client";

import { useState } from "react";
import Tabs from "@/registry/ui/tabs";

const tabs = [
  { label: "전체", value: "all" },
  { label: "진행중", value: "active" },
  { label: "완료", value: "completed" },
] as const;

export default function Example() {
  const [value, setValue] = useState<"all" | "active" | "completed">("all");

  return (
    <Tabs
      type="box"
      value={value}
      onTabChange={setValue}
      tabs={tabs}
    />
  );
}

Installation

pnpx shadcn add @allra/tabs

Usage

Box Tabs

import Tabs from "@/registry/ui/tabs";

<Tabs
  type="box"
  value={value}
  onTabChange={setValue}
  tabs={tabs}
  size="md"
/>

Linear Tabs

import Tabs from "@/registry/ui/tabs";

<Tabs
  type="linear"
  value={value}
  onTabChange={setValue}
  tabs={tabs}
/>

Props

Tabs

PropTypeDefaultDescription
type"box" | "linear"-탭 스타일 타입
valueT-현재 선택된 탭의 값 (controlled)
defaultValueTtabs[0]?.value초기 선택된 탭의 값 (uncontrolled)
tabsreadonly Tab<T>[]-탭 목록
onTabChange(value: T) => void-탭 변경 시 호출되는 콜백 함수
classNamestring-추가 CSS 클래스
size"sm" | "md""md"Box 타입일 때 탭의 크기

Generic 타입: T extends string - 탭의 value 타입을 지정합니다.

Tab 인터페이스

interface Tab<T extends string> {
  label: string;
  value: T;
}

Features

  • 두 가지 스타일: Box와 Linear 스타일 제공
  • Controlled/Uncontrolled: value prop으로 제어 모드 선택
  • 애니메이션: 탭 전환 시 부드러운 애니메이션 효과
  • 접근성: ARIA 속성을 통한 키보드 네비게이션 지원
  • 반응형: 다양한 화면 크기에서 동작

Examples

Box Tabs 기본 사용

둥근 모서리의 박스 스타일 탭입니다. 기본 크기는 md입니다.

선택된 탭: all
"use client";

import { useState } from "react";
import Tabs from "@/registry/ui/tabs";

const tabs = [
  { label: "전체", value: "all" },
  { label: "진행중", value: "active" },
  { label: "완료", value: "completed" },
] as const;

export default function Example() {
  const [value, setValue] = useState<"all" | "active" | "completed">("all");

  return (
    <Tabs
      type="box"
      value={value}
      onTabChange={setValue}
      tabs={tabs}
    />
  );
}

Box Tabs 작은 크기

Box Tabs는 sm 크기를 지원합니다.

선택된 탭: all
<Tabs
  type="box"
  value={value}
  onTabChange={setValue}
  tabs={tabs}
  size="sm"
/>

Linear Tabs 기본 사용

하단 테두리가 있는 선형 스타일 탭입니다.

선택된 탭: all
"use client";

import { useState } from "react";
import Tabs from "@/registry/ui/tabs";

const tabs = [
  { label: "전체", value: "all" },
  { label: "진행중", value: "active" },
  { label: "완료", value: "completed" },
] as const;

export default function Example() {
  const [value, setValue] = useState<"all" | "active" | "completed">("all");

  return (
    <Tabs
      type="linear"
      value={value}
      onTabChange={setValue}
      tabs={tabs}
    />
  );
}

Uncontrolled 모드

defaultValue를 사용하여 초기값을 설정하고, 상태 관리를 컴포넌트 내부에서 처리합니다.

선택된 탭: active
const tabs = [
  { label: "전체", value: "all" },
  { label: "진행중", value: "active" },
  { label: "완료", value: "completed" },
] as const;

<Tabs
  type="box"
  defaultValue="active"
  tabs={tabs}
  onTabChange={(value) => {
    console.log("탭 변경:", value);
  }}
/>

Controlled 모드

외부에서 value를 관리하여 완전한 제어가 가능합니다.

선택된 탭: completed
"use client";

import { useState } from "react";
import Tabs from "@/registry/ui/tabs";

const tabs = [
  { label: "전체", value: "all" },
  { label: "진행중", value: "active" },
  { label: "완료", value: "completed" },
] as const;

export default function Example() {
  const [value, setValue] = useState<"all" | "active" | "completed">("completed");

  const handleTabChange = (newValue: "all" | "active" | "completed") => {
    setValue(newValue);
    // 추가 로직 (예: API 호출, 페이지 이동 등)
  };

  return (
    <Tabs
      type="box"
      value={value}
      onTabChange={handleTabChange}
      tabs={tabs}
    />
  );
}

커스텀 탭 데이터

다양한 탭 데이터를 사용할 수 있습니다. Generic을 통해 타입 안정성을 보장합니다.

선택된 탭: tab2
const customTabs = [
  { label: "첫 번째", value: "tab1" },
  { label: "두 번째", value: "tab2" },
  { label: "세 번째", value: "tab3" },
  { label: "네 번째", value: "tab4" },
] as const;

<Tabs
  type="box"
  defaultValue="tab2"
  tabs={customTabs}
  onTabChange={(value) => {
    // value는 "tab1" | "tab2" | "tab3" | "tab4" 타입으로 추론됩니다
    console.log(value);
  }}
/>