Tabs Component

September 5, 2025 ยท View on GitHub

Production-ready advanced tabbed interface component with keyboard navigation, drag-to-reorder functionality, lazy loading capabilities, and full TypeScript compliance with AI metadata support.

Usage

import '@nexcraft/forge/organisms/tabs';

// Basic usage
html`
  <forge-tabs .tabs=${this.tabData}></forge-tabs>
`;

Properties

PropertyTypeDefaultDescription
tabsTabItem[][]Array of tab items to display
activeTabstring''ID of the currently active tab
orientation'horizontal' | 'vertical''horizontal'Tab orientation
reorderablebooleanfalseEnable drag-to-reorder functionality
lazyLoadbooleanfalseEnable lazy loading of tab content
closeablebooleanfalseAllow tabs to be closed globally
showScrollButtonsbooleantrueShow scroll buttons when tabs overflow

TabItem Interface

interface TabItem {
  id: string;
  label: string;
  icon?: string;
  badge?: string | number;
  disabled?: boolean;
  closeable?: boolean;
  panel?: string | TemplateStringsArray;
}

Events

EventDetailDescription
forge-tab-change{ tabId: string, previousTabId: string }Fired when the active tab changes
forge-tab-close{ tabId: string }Fired when a tab is closed
forge-tab-reorder{ fromIndex: number, toIndex: number }Fired when tabs are reordered

Methods

Public Methods

MethodParametersReturnsDescription
activateTab(tabId)tabId: stringvoidProgrammatically activate a tab
closeTab(tabId)tabId: stringvoidProgrammatically close a tab
addTab(tab, index?)tab: TabItem, index?: numbervoidAdd a new tab at specified position
scrollToTab(tabId)tabId: stringvoidScroll to make a specific tab visible

AI Metadata Methods

MethodReturnsDescription
explainState()stringReturns detailed explanation of current state
getPossibleActions()AIAction[]Returns available actions based on current state
aiStateAIStateCurrent component state for AI analysis

Keyboard Navigation

KeyAction
Arrow Left/RightNavigate between tabs (horizontal)
Arrow Up/DownNavigate between tabs (vertical)
HomeGo to first tab
EndGo to last tab
Enter/SpaceActivate focused tab
DeleteClose focused tab (if closeable)

Styling

CSS Custom Properties

forge-tabs {
  --forge-tab-bg: #ffffff;
  --forge-tab-border: #e0e0e0;
  --forge-tab-active-color: #007bff;
  --forge-tab-hover-bg: #f8f9fa;
  --forge-tab-disabled-opacity: 0.5;
  --forge-tab-padding: 12px 16px;
  --forge-tab-border-radius: 4px;
  --forge-tab-transition: all 0.2s ease;
}

CSS Parts

PartDescription
tabs-containerMain container element
tabs-headerHeader containing tab buttons
tab-buttonIndividual tab button
tab-panelsContainer for tab content
tab-panelIndividual tab panel
scroll-buttonNavigation scroll buttons

Examples

Basic Tabs

const basicTabs = [
  { id: 'home', label: 'Home', panel: html`<div>Home content</div>` },
  { id: 'about', label: 'About', panel: html`<div>About content</div>` },
  { id: 'contact', label: 'Contact', panel: html`<div>Contact content</div>` }
];

html`
  <forge-tabs .tabs=${basicTabs}></forge-tabs>
`;

Tabs with Icons and Badges

const tabsWithIcons = [
  { 
    id: 'inbox', 
    label: 'Inbox', 
    icon: 'mail', 
    badge: '12',
    panel: html`<div>Inbox content</div>` 
  },
  { 
    id: 'sent', 
    label: 'Sent', 
    icon: 'send',
    panel: html`<div>Sent content</div>` 
  },
  { 
    id: 'drafts', 
    label: 'Drafts', 
    icon: 'draft',
    badge: '3',
    panel: html`<div>Drafts content</div>` 
  }
];

html`
  <forge-tabs .tabs=${tabsWithIcons}></forge-tabs>
`;

Vertical Tabs with Reordering

html`
  <forge-tabs 
    .tabs=${this.tabs}
    orientation="vertical"
    reorderable
    @forge-tab-reorder=${this.handleReorder}
  ></forge-tabs>
`;

private handleReorder(e: CustomEvent) {
  const { fromIndex, toIndex } = e.detail;
  // Update your data model
  this.reorderTabs(fromIndex, toIndex);
}

Closeable Tabs

html`
  <forge-tabs 
    .tabs=${this.tabs}
    closeable
    @forge-tab-close=${this.handleTabClose}
  ></forge-tabs>
`;

private handleTabClose(e: CustomEvent) {
  const { tabId } = e.detail;
  this.tabs = this.tabs.filter(tab => tab.id !== tabId);
}

Lazy Loading

html`
  <forge-tabs 
    .tabs=${this.tabs}
    lazy-load
    @forge-tab-change=${this.handleTabChange}
  ></forge-tabs>
`;

private handleTabChange(e: CustomEvent) {
  const { tabId } = e.detail;
  // Load content for the activated tab
  this.loadTabContent(tabId);
}

Accessibility

  • Full WCAG 2.1 AA compliance
  • Keyboard navigation support
  • ARIA attributes for screen readers:
    • role="tablist" on tab container
    • role="tab" on tab buttons
    • role="tabpanel" on content panels
    • aria-selected and aria-expanded states
  • Focus management and visual indicators
  • Announcements for tab changes and actions

Performance Considerations

  • Lazy loading prevents rendering of inactive tab content
  • Virtual scrolling for large numbers of tabs
  • Efficient event delegation
  • Memory cleanup in disconnectedCallback
  • Optimized drag-and-drop implementation

Browser Support

  • Chrome 84+
  • Firefox 78+
  • Safari 14+
  • Edge 84+