Tabs

Tab navigation component for organizing content into switchable sections.

Tab Variants

Standard Tabs

Basic horizontal tabs with underline indicator

Overview Content

This is the overview tab content. It provides general information about the property or item being displayed.

Features Content

List of features and amenities available with this property.

Specifications Content

Detailed technical specifications and measurements.

Reviews Content

Customer reviews and ratings for this property.

Pills Style Tabs

Tabs with pill-style background

Showing all properties

Properties available for sale

Properties available for rent

Recently sold properties

Tabs with Icons

Tabs enhanced with icons

Property overview and details

Location information and map

Pricing and payment options

Tabs with Badges

Tabs with notification badges

You have 3 new messages

12 new notifications

No new updates

Real Estate Use Cases

Property Details Tabs

Property Details

  • 3 Bedrooms, 2 Bathrooms
  • 150 m² Living Space
  • Built in 2020
  • Energy Class A+

Floor Plans

Interactive floor plans would be displayed here

Virtual Tour

360° virtual tour interface

Neighborhood Information

Schools, transport, shopping nearby

Contact Agent

Agent contact form and information

Implementation Guide

HTML Structure

<!-- Standard Tabs -->
<div class="lyd-tabs">
    <div class="lyd-tabs-list">
        <button class="lyd-tab active" onclick="switchTab(event, 'tab1')">Tab 1</button>
        <button class="lyd-tab" onclick="switchTab(event, 'tab2')">Tab 2</button>
        <button class="lyd-tab" onclick="switchTab(event, 'tab3')">Tab 3</button>
    </div>
    
    <div class="lyd-tab-panels">
        <div id="tab1" class="lyd-tab-panel active">
            <p>Tab 1 content</p>
        </div>
        <div id="tab2" class="lyd-tab-panel">
            <p>Tab 2 content</p>
        </div>
        <div id="tab3" class="lyd-tab-panel">
            <p>Tab 3 content</p>
        </div>
    </div>
</div>

<!-- Pills Style -->
<div class="lyd-tabs-list pills">
    <button class="lyd-tab active">Option 1</button>
    <button class="lyd-tab">Option 2</button>
</div>

<!-- Tab with Icon and Badge -->
<button class="lyd-tab">
    <span class="lyd-tab-icon">
        <svg>...</svg>
        Messages
    </span>
    <span class="lyd-tab-badge">3</span>
</button>

JavaScript Tab Switching

// Switch tabs
function switchTab(event, tabId) {
    // Get tab container
    const tabContainer = event.target.closest('.lyd-tabs');
    
    // Remove active from all tabs
    tabContainer.querySelectorAll('.lyd-tab').forEach(tab => {
        tab.classList.remove('active');
    });
    
    // Remove active from all panels
    tabContainer.querySelectorAll('.lyd-tab-panel').forEach(panel => {
        panel.classList.remove('active');
    });
    
    // Add active to clicked tab
    event.target.classList.add('active');
    
    // Add active to corresponding panel
    const panel = tabContainer.querySelector(`#${tabId}`);
    if (panel) {
        panel.classList.add('active');
    }
}

// Keyboard navigation
document.querySelectorAll('.lyd-tabs-list').forEach(tabList => {
    const tabs = tabList.querySelectorAll('.lyd-tab');
    
    tabs.forEach((tab, index) => {
        tab.addEventListener('keydown', (e) => {
            if (e.key === 'ArrowRight') {
                const nextTab = tabs[index + 1] || tabs[0];
                nextTab.focus();
                nextTab.click();
            } else if (e.key === 'ArrowLeft') {
                const prevTab = tabs[index - 1] || tabs[tabs.length - 1];
                prevTab.focus();
                prevTab.click();
            }
        });
    });
});

React/Next.js Component

// components/Tabs.tsx
import { useState, ReactNode } from 'react';

interface Tab {
  id: string;
  label: string;
  icon?: ReactNode;
  badge?: number;
  content: ReactNode;
}

interface TabsProps {
  tabs: Tab[];
  variant?: 'underline' | 'pills';
  orientation?: 'horizontal' | 'vertical';
  defaultTab?: string;
}

export const Tabs = ({
  tabs,
  variant = 'underline',
  orientation = 'horizontal',
  defaultTab
}: TabsProps) => {
  const [activeTab, setActiveTab] = useState(defaultTab || tabs[0]?.id);
  
  const tabListClasses = [
    'lyd-tabs-list',
    variant === 'pills' && 'pills'
  ].filter(Boolean).join(' ');
  
  const tabsClasses = [
    'lyd-tabs',
    orientation === 'vertical' && 'vertical'
  ].filter(Boolean).join(' ');
  
  return (
    <div className={tabsClasses}>
      <div className={tabListClasses}>
        {tabs.map((tab) => (
          <button
            key={tab.id}
            className={`lyd-tab ${activeTab === tab.id ? 'active' : ''}`}
            onClick={() => setActiveTab(tab.id)}
          >
            {tab.icon && (
              <span className="lyd-tab-icon">
                {tab.icon}
                {tab.label}
              </span>
            )}
            {!tab.icon && tab.label}
            {tab.badge && (
              <span className="lyd-tab-badge">{tab.badge}</span>
            )}
          </button>
        ))}
      </div>
      
      <div className="lyd-tab-panels">
        {tabs.map((tab) => (
          <div
            key={tab.id}
            id={tab.id}
            className={`lyd-tab-panel ${activeTab === tab.id ? 'active' : ''}`}
          >
            {tab.content}
          </div>
        ))}
      </div>
    </div>
  );
};

API Reference

Class Description
.lyd-tabs Main tabs container
.lyd-tabs-list Tab buttons container
.lyd-tab Individual tab button
.lyd-tab-panels Tab content panels container
.lyd-tab-panel Individual tab panel
.lyd-tab-icon Tab icon wrapper
.lyd-tab-badge Tab notification badge
.pills Pills style variant
.vertical Vertical orientation
.active Active tab/panel state

Accessibility & Best Practices

Keyboard Navigation

  • Tab to focus tab list
  • Arrow keys to navigate between tabs
  • Enter/Space to activate tab
  • Tab to move into panel content

ARIA Attributes

  • role="tablist" on tab container
  • role="tab" on tab buttons
  • role="tabpanel" on content panels
  • aria-selected on active tab
  • aria-controls linking tabs to panels

Best Practices

  • Keep tab labels short and descriptive
  • Limit to 5-7 tabs maximum
  • Use icons to enhance recognition
  • Provide visual feedback for active state
  • Consider vertical tabs for many items

Content Organization

  • Group related content logically
  • Order tabs by importance/frequency
  • Maintain consistent panel layouts
  • Preserve state when switching tabs