GitHub
Core
Glass
Brutal
Humanist

Container Tabs

Container Tabs provide navigation with rounded container styling for each tab. Available in two sizes (default and small), two color variants (primary and neutral), and two visual styles (simple and expressive).

Horizontal Container Tabs Playground

Horizontal Container Tabs Playground
Preview
Code
Controls
Size:
Default
Small
Variant:
Primary
Neutral
Style:
Simple
Expressive
Icons:
Badges:

Vertical Container Tabs Playground

Vertical Container Tabs Playground
Preview
Code
Controls
Size:
Default
Small
Variant:
Primary
Neutral
Style:
Simple
Expressive
Icons:
Badges:

Installation

You can add the container tabs component to your project manually:

1

Install the following dependencies:

npm install class-variance-authority clsx @phosphor-icons/react @react-aria/focus
2

Copy and paste the following code into your project.

Loading source code...
3

Update the import paths to match your project setup.

Update the import aliases (e.g. @/components, @/utils) in the copied files to match your project's path configuration.

Basic Usage

Horizontal Tabs

import { useState } from 'react';
import { HorizontalContainerTabs } from '@versaui/ui/components/ContainerTab';
import { HouseIcon, ChartBarIcon, StackIcon, GearIcon } from '@phosphor-icons/react';

function Navigation() {
  const [selectedId, setSelectedId] = useState('dashboard');
  const tabs = [
    { id: 'dashboard', label: 'Dashboard', icon: <HouseIcon size={20} />, badge: 12 },
    { id: 'analytics', label: 'Analytics', icon: <ChartBarIcon size={20} /> },
    { id: 'projects', label: 'Projects', icon: <StackIcon size={20} /> },
    { id: 'settings', label: 'Settings', icon: <GearIcon size={20} /> },
  ];
  return (
    <HorizontalContainerTabs
      items={tabs}
      selectedId={selectedId}
      onChange={setSelectedId}
    />
  );
}

Small Size

<HorizontalContainerTabs
  items={tabs}
  selectedId={selectedId}
  onChange={setSelectedId}
  size="small"
/>

Expressive Style

<HorizontalContainerTabs
  items={tabs}
  selectedId={selectedId}
  onChange={setSelectedId}
  variant="primary"
  style="expressive"
/>

Neutral Variant

<HorizontalContainerTabs
  items={tabs}
  selectedId={selectedId}
  onChange={setSelectedId}
  variant="neutral"
  style="simple"
/>

Vertical Tabs

import { VerticalContainerTabs } from '@versaui/ui/components/ContainerTab';

<VerticalContainerTabs
  items={tabs}
  selectedId={selectedId}
  onChange={setSelectedId}
  width={200}
/>

With Icons

Add icons to tab items for visual context:

import { HouseIcon, ChartBarIcon, StackIcon, GearIcon } from '@phosphor-icons/react';

const tabs = [
  { id: 'dashboard', label: 'Dashboard', icon: <HouseIcon size={20} /> },
  { id: 'analytics', label: 'Analytics', icon: <ChartBarIcon size={20} /> },
  { id: 'projects', label: 'Projects', icon: <StackIcon size={20} /> },
  { id: 'settings', label: 'Settings', icon: <GearIcon size={20} /> },
];

<HorizontalContainerTabs
  items={tabs}
  selectedId={selectedId}
  onChange={setSelectedId}
/>

ContainerTabItem Interface

interface ContainerTabItem {
  id: string;        // Unique identifier
  label: string;     // Tab label
  icon?: ReactNode;  // Optional leading icon
  badge?: number;    // Optional badge count
  disabled?: boolean; // Disabled state
}

Accessibility

  • Uses role="tablist" and role="tab" with proper aria-selected and aria-disabled
  • Full keyboard navigation:
    • ArrowLeft/Right for horizontal tabs
    • ArrowUp/Down for vertical tabs
    • Home/End to jump to first/last tab
  • Focus ring visible on keyboard navigation
  • Disabled tabs are skipped in keyboard navigation

ContainerTab Props

PropTypeDefaultDescription
childrenReactNode—Required. Tab label content.
orientation'horizontal' | 'vertical''horizontal'Tab orientation.
size'default' | 'small''default'Tab size. Small uses 32px height, 8px padding, 2px gap, H9 text, and 16px icons.
variant'primary' | 'neutral''primary'Color scheme variant. Primary uses brand colors; neutral uses surface outline and neutral colors.
style'simple' | 'expressive''simple'Visual style treatment. Simple uses clean solid surfaces; expressive uses rich gradient fills and outlines.
state'default' | 'hovered' | 'selected' | 'disabled''default'Visual state.
showIconbooleantrueShow leading icon.
leadingIconReactNodeCirclesThreeCustom leading icon.
showBadgebooleantrueShow badge.
badgeCountnumber24Badge count value.
selectedboolean—Controlled selected state.
disabledbooleanfalseDisabled state.
onClick() => void—Click handler.
classNamestring''Additional CSS classes.

HorizontalContainerTabs Props

PropTypeDefaultDescription
itemsContainerTabItem[]—Required. Array of tab items.
selectedIdstring—Currently selected tab ID.
onChange(id: string) => void—Selection change handler.
showIconsbooleantrueShow icons if provided in items.
size'default' | 'small''default'Tab size for all items.
variant'primary' | 'neutral''primary'Color scheme variant for all items.
style'simple' | 'expressive''simple'Visual style treatment for all items.
classNamestring''Additional CSS classes.

VerticalContainerTabs Props

PropTypeDefaultDescription
itemsContainerTabItem[]—Required. Array of tab items.
selectedIdstring—Currently selected tab ID.
onChange(id: string) => void—Selection change handler.
showIconsbooleantrueShow icons if provided in items.
size'default' | 'small''default'Tab size for all items.
variant'primary' | 'neutral''primary'Color scheme variant for all items.
style'simple' | 'expressive''simple'Visual style treatment for all items.
widthstring | number160Container width.
classNamestring''Additional CSS classes.

On this page