YaVendio Registry
Components

YA Tabs

A tabs component with default and line types for organizing content into sections

The YaTabs component provides a way to organize content into multiple panels that can be switched between. It supports two visual types (default and line), stretch labels mode, and optional icons on tab triggers.

Quick Start

pnpm dlx shadcn@latest add @yavendio/ya-tabs
npx shadcn@latest add @yavendio/ya-tabs
yarn dlx shadcn@latest add @yavendio/ya-tabs
import { YaTabs, YaTabsList, YaTabsTrigger, YaTabsContent } from '@/components/ui/ya-tabs'

export default function Example() {
  return (
    <YaTabs defaultValue="tab1">
      <YaTabsList>
        <YaTabsTrigger value="tab1">Tab 1</YaTabsTrigger>
        <YaTabsTrigger value="tab2">Tab 2</YaTabsTrigger>
        <YaTabsTrigger value="tab3">Tab 3</YaTabsTrigger>
      </YaTabsList>
      <YaTabsContent value="tab1">Content for Tab 1</YaTabsContent>
      <YaTabsContent value="tab2">Content for Tab 2</YaTabsContent>
      <YaTabsContent value="tab3">Content for Tab 3</YaTabsContent>
    </YaTabs>
  )
}

Types

YaTabs comes with two visual types for different use cases:

TypeDescriptionUsage
defaultContained background with rounded cornersSettings panels, content sections
lineMinimal with bottom border indicatorNavigation, minimal UIs

Default Type

Line Type

Default Type

A contained style with gray background and shadow on the active tab.

Overview content goes here.
<YaTabs type="default" defaultValue="tab1">
  <YaTabsList>
    <YaTabsTrigger value="tab1">Overview</YaTabsTrigger>
    <YaTabsTrigger value="tab2">Settings</YaTabsTrigger>
    <YaTabsTrigger value="tab3">Analytics</YaTabsTrigger>
  </YaTabsList>
  <YaTabsContent value="tab1">Overview content</YaTabsContent>
  <YaTabsContent value="tab2">Settings content</YaTabsContent>
  <YaTabsContent value="tab3">Analytics content</YaTabsContent>
</YaTabs>

Features:

  • Gray background container with rounded corners
  • Selected tab has white background with subtle shadow
  • Unselected tabs have no background

Line Type

A minimal style with underline indicator for the active tab.

Overview content goes here.
<YaTabs type="line" defaultValue="tab1">
  <YaTabsList>
    <YaTabsTrigger value="tab1">Overview</YaTabsTrigger>
    <YaTabsTrigger value="tab2">Settings</YaTabsTrigger>
    <YaTabsTrigger value="tab3">Analytics</YaTabsTrigger>
  </YaTabsList>
  <YaTabsContent value="tab1">Overview content</YaTabsContent>
  <YaTabsContent value="tab2">Settings content</YaTabsContent>
  <YaTabsContent value="tab3">Analytics content</YaTabsContent>
</YaTabs>

Features:

  • No background container
  • Selected tab has a bottom border
  • Clean, minimal appearance

Stretch Labels

Use the stretchLabels prop to make tabs fill the available width.

Without Stretch

With Stretch

// Without stretch - tabs take only the space needed
<YaTabs type="default" stretchLabels={false} defaultValue="tab1">
  <YaTabsList>
    <YaTabsTrigger value="tab1">Tab 1</YaTabsTrigger>
    <YaTabsTrigger value="tab2">Tab 2</YaTabsTrigger>
    <YaTabsTrigger value="tab3">Tab 3</YaTabsTrigger>
  </YaTabsList>
</YaTabs>

// With stretch - tabs expand to fill width
<YaTabs type="default" stretchLabels={true} defaultValue="tab1">
  <YaTabsList>
    <YaTabsTrigger value="tab1">Tab 1</YaTabsTrigger>
    <YaTabsTrigger value="tab2">Tab 2</YaTabsTrigger>
    <YaTabsTrigger value="tab3">Tab 3</YaTabsTrigger>
  </YaTabsList>
</YaTabs>

Stretch Labels with Line Type

Overview content
<YaTabs type="line" stretchLabels={true} defaultValue="tab1">
  <YaTabsList>
    <YaTabsTrigger value="tab1">Overview</YaTabsTrigger>
    <YaTabsTrigger value="tab2">Settings</YaTabsTrigger>
    <YaTabsTrigger value="tab3">Analytics</YaTabsTrigger>
  </YaTabsList>
  <YaTabsContent value="tab1">Overview content</YaTabsContent>
  <YaTabsContent value="tab2">Settings content</YaTabsContent>
  <YaTabsContent value="tab3">Analytics content</YaTabsContent>
</YaTabs>

Icons

Add icons to the left or right of tab text:

Home content
import { Home, Settings, BarChart } from 'lucide-react'

<YaTabs type="default" defaultValue="home">
  <YaTabsList>
    <YaTabsTrigger value="home" leftIcon={<Home />}>
      Home
    </YaTabsTrigger>
    <YaTabsTrigger value="settings" leftIcon={<Settings />}>
      Settings
    </YaTabsTrigger>
    <YaTabsTrigger value="analytics" rightIcon={<BarChart />}>
      Analytics
    </YaTabsTrigger>
  </YaTabsList>
  <YaTabsContent value="home">Home content</YaTabsContent>
  <YaTabsContent value="settings">Settings content</YaTabsContent>
  <YaTabsContent value="analytics">Analytics content</YaTabsContent>
</YaTabs>

Icons are automatically sized to 12px to match the design system specifications.

States

Controlled State

Use the value and onValueChange props for controlled behavior:

Active tab: tab1

Content for Tab 1
'use client'

import { useState } from 'react'
import { YaTabs, YaTabsList, YaTabsTrigger, YaTabsContent } from '@/components/ui/ya-tabs'

export default function ControlledTabs() {
  const [activeTab, setActiveTab] = useState('tab1')

  return (
    <>
      <p>Active tab: {activeTab}</p>
      <YaTabs value={activeTab} onValueChange={setActiveTab}>
        <YaTabsList>
          <YaTabsTrigger value="tab1">Tab 1</YaTabsTrigger>
          <YaTabsTrigger value="tab2">Tab 2</YaTabsTrigger>
        </YaTabsList>
        <YaTabsContent value="tab1">Content 1</YaTabsContent>
        <YaTabsContent value="tab2">Content 2</YaTabsContent>
      </YaTabs>
    </>
  )
}

Disabled Tabs

Disable individual tabs using the disabled prop:

Available content
<YaTabs defaultValue="tab1">
  <YaTabsList>
    <YaTabsTrigger value="tab1">Available</YaTabsTrigger>
    <YaTabsTrigger value="tab2" disabled>
      Coming Soon
    </YaTabsTrigger>
    <YaTabsTrigger value="tab3">Active</YaTabsTrigger>
  </YaTabsList>
  <YaTabsContent value="tab1">Available content</YaTabsContent>
  <YaTabsContent value="tab2">Coming soon content</YaTabsContent>
  <YaTabsContent value="tab3">Active content</YaTabsContent>
</YaTabs>

Examples

Overview

Welcome to your dashboard.

<YaTabs type="line" defaultValue="overview" className="w-full">
  <YaTabsList>
    <YaTabsTrigger value="overview">Overview</YaTabsTrigger>
    <YaTabsTrigger value="documents">Documents</YaTabsTrigger>
    <YaTabsTrigger value="settings">Settings</YaTabsTrigger>
  </YaTabsList>
  <YaTabsContent value="overview">
    <h2>Overview</h2>
    <p>Welcome to your dashboard.</p>
  </YaTabsContent>
  <YaTabsContent value="documents">
    <h2>Documents</h2>
    <p>Your documents will appear here.</p>
  </YaTabsContent>
  <YaTabsContent value="settings">
    <h2>Settings</h2>
    <p>Manage your account settings.</p>
  </YaTabsContent>
</YaTabs>

Settings Panel

Profile settings content

import { User, Lock, Bell, CreditCard } from 'lucide-react'

<YaTabs type="default" stretchLabels={true} defaultValue="profile">
  <YaTabsList>
    <YaTabsTrigger value="profile" leftIcon={<User />}>
      Profile
    </YaTabsTrigger>
    <YaTabsTrigger value="security" leftIcon={<Lock />}>
      Security
    </YaTabsTrigger>
    <YaTabsTrigger value="notifications" leftIcon={<Bell />}>
      Notifications
    </YaTabsTrigger>
    <YaTabsTrigger value="billing" leftIcon={<CreditCard />}>
      Billing
    </YaTabsTrigger>
  </YaTabsList>
  <YaTabsContent value="profile">Profile settings content</YaTabsContent>
  <YaTabsContent value="security">Security settings content</YaTabsContent>
  <YaTabsContent value="notifications">Notification preferences</YaTabsContent>
  <YaTabsContent value="billing">Billing information</YaTabsContent>
</YaTabs>

Compact Tabs

<YaTabs type="default" defaultValue="all">
  <YaTabsList>
    <YaTabsTrigger value="all">All</YaTabsTrigger>
    <YaTabsTrigger value="active">Active</YaTabsTrigger>
    <YaTabsTrigger value="pending">Pending</YaTabsTrigger>
    <YaTabsTrigger value="completed">Completed</YaTabsTrigger>
  </YaTabsList>
</YaTabs>

Props

YaTabs

PropTypeDefaultDescription
type'default' | 'line''default'Visual style type
stretchLabelsbooleanfalseWhether tabs stretch to fill width
defaultValuestring-Initially active tab (uncontrolled)
valuestring-Active tab (controlled)
onValueChange(value: string) => void-Callback when active tab changes
orientation'horizontal' | 'vertical''horizontal'Tab orientation
classNamestring-Additional classes

YaTabsList

PropTypeDefaultDescription
classNamestring-Additional classes

YaTabsTrigger

PropTypeDefaultDescription
valuestringrequiredUnique value for the tab
leftIconReactNode-Icon on the left
rightIconReactNode-Icon on the right
disabledbooleanfalseDisable the tab
classNamestring-Additional classes

YaTabsContent

PropTypeDefaultDescription
valuestringrequiredValue matching a trigger
forceMountbooleanfalseKeep content mounted when hidden
classNamestring-Additional classes

Accessibility

<YaTabs defaultValue="tab1">
  <YaTabsList aria-label="Account settings">
    <YaTabsTrigger value="tab1">Profile</YaTabsTrigger>
    <YaTabsTrigger value="tab2">Security</YaTabsTrigger>
  </YaTabsList>
  <YaTabsContent value="tab1">Profile settings</YaTabsContent>
  <YaTabsContent value="tab2">Security settings</YaTabsContent>
</YaTabs>

Best Practices

DoDon't
Use default type for contained sectionsLine type for dense settings panels
Use line type for navigationDefault type for minimal UIs
Enable stretchLabels for primary navigationStretch labels for auxiliary tabs
Use concise, descriptive labelsVague labels like "Tab 1", "Tab 2"
Provide aria-label on YaTabsListMissing accessibility attributes
Use icons consistently (all tabs or none)Mix icon placement styles

TypeScript

import { type VariantProps } from 'class-variance-authority'
import { yaTabsListVariants, yaTabsTriggerVariants } from '@/components/ui/ya-tabs'

// Extract variant types
type TabsListType = VariantProps<typeof yaTabsListVariants>['type']
type TriggerType = VariantProps<typeof yaTabsTriggerVariants>['type']

// Use in your components
interface MyComponentProps {
  tabType?: TabsListType
}

On this page