Tab Selector

Tab interface for switching between different views or content sections.

When to use

  • To organize content into distinct, navigable sections
  • For settings pages with multiple categories
  • To display different views of the same data (e.g., table view, card view)
  • In product detail pages for description, specifications, reviews, etc.

Key features

  • Multiple variants - Underline (default), solid, and pills
  • Three sizes - Small, medium (default), and large
  • Full width option - Tabs can span the full width of their container
  • Icon support - Add icons to tab labels
  • Badge support - Display counts or indicators on tabs
  • Keyboard navigation - Full arrow key support, Home/End, and Enter/Space
  • Accessible - ARIA attributes and focus management

Anatomy

A tab selector consists of:

  • Tab List (.pm7-tab-list) - Container for tab buttons
  • Tab Trigger (.pm7-tab-trigger) - Individual clickable tab button
  • Tab Content (.pm7-tab-content) - The panel displaying content for the selected tab
  • Icon (.pm7-tab-trigger-icon) - Optional visual indicator within a tab
  • Badge (.pm7-tab-trigger-badge) - Optional counter or indicator within a tab

Tip: Use the accordion below to explore different tab selector demos. Click "Open in new tab" to see the full demo page.

Installation

npm install @pm7/core

CSS Classes

<div class="pm7-tab-selector" data-pm7-tab-selector>
  <div class="pm7-tab-list">
    <button class="pm7-tab-trigger" aria-controls="tab-1" data-state="active">Tab 1</button>
    <button class="pm7-tab-trigger" aria-controls="tab-2">Tab 2</button>
    <button class="pm7-tab-trigger" aria-controls="tab-3">Tab 3</button>
  </div>
  
  <div class="pm7-tab-content" id="tab-1" data-state="active">
    <p>Content for Tab 1</p>
  </div>
  <div class="pm7-tab-content" id="tab-2">
    <p>Content for Tab 2</p>
  </div>
  <div class="pm7-tab-content" id="tab-3">
    <p>Content for Tab 3</p>
  </div>
</div>

Data Attributes

Attribute Description
data-pm7-tab-selector Auto-initialize tab selector
data-state="active" Marks active tab and content
aria-controls Links tab trigger to content panel

Basic Usage

Class Description
Container Classes
.pm7-tab-selector Container element
.pm7-tab-list Tab button container
Tab Classes
.pm7-tab-trigger Individual tab button
.pm7-tab-trigger--active Active tab state (alternative to data-state)
.pm7-tab-trigger-icon Icon within tab
.pm7-tab-trigger-badge Badge/counter within tab
Content Classes
.pm7-tab-content Tab panel content
.pm7-tab-content--active Active panel state (alternative to data-state)
Variant Classes
.pm7-tab-selector--solid Solid background variant
.pm7-tab-selector--pills Pill-shaped variant
Size Classes
.pm7-tab-selector--sm Small size
.pm7-tab-selector--lg Large size
Layout Classes
.pm7-tab-selector--full-width Full width tabs

Note: The default tab style uses an underline indicator. No additional class is needed for this variant.

State Management

Tabs use data-state="active" attributes for state management, with fallback support for --active modifier classes:

<!-- Preferred: Using data-state -->
<button class="pm7-tab-trigger" data-state="active">Active Tab</button>
<div class="pm7-tab-content" data-state="active">Active Content</div>

<!-- Alternative: Using modifier classes -->
<button class="pm7-tab-trigger pm7-tab-trigger--active">Active Tab</button>
<div class="pm7-tab-content pm7-tab-content--active">Active Content</div>

Theme Support

PM7 Tab Selector includes built-in support for:

  • Dark Mode - Automatically adapts when the .dark class is present on a parent element
  • RTL Support - Fully supports right-to-left layouts with dir="rtl"

The component uses standard PM7 design tokens for consistent theming across your application.

JavaScript API

Tab selectors are automatically initialized when the DOM loads:

import { PM7TabSelector } from '@pm7/core';

    import '/packages/core/src/scripts/index.js';
// Create instance for auto-initialized tabs
const tabElement = document.querySelector('[data-pm7-tab-selector]');
const tabs = new PM7TabSelector(tabElement);

// Use the instance
tabs.selectTabById('settings-panel');
tabs.selectTabByIndex(2);

// Get active tab information
const activeTab = tabs.getActiveTab();
const activeIndex = tabs.getActiveIndex();

// Manual initialization
const customTabs = document.querySelector('.custom-tabs');
const customTabInstance = new PM7TabSelector(customTabs);

// TypeScript support
const element = document.querySelector('[data-pm7-tab-selector]') as HTMLElement;
const tabSelector = new PM7TabSelector(element);
tabSelector.selectTabById('profile-panel');

Dynamic Tabs Example

<!-- Tab selector with dynamic content -->
<div class="pm7-tab-selector pm7-tab-selector--underline" data-pm7-tab-selector>
  <div class="pm7-tab-list">
    <button class="pm7-tab-trigger" aria-controls="settings-panel">Settings</button>
    <button class="pm7-tab-trigger" aria-controls="profile-panel">Profile</button>
    <button class="pm7-tab-trigger" aria-controls="security-panel">Security</button>
  </div>
  
  <div class="pm7-tab-content" id="settings-panel">
    <h3>Settings</h3>
    <div class="pm7-form-group">
      <label class="pm7-label">Language</label>
      <select class="pm7-input">
        <option>English</option>
        <option>Dutch</option>
      </select>
    </div>
  </div>
  
  <div class="pm7-tab-content" id="profile-panel">
    <h3>Profile</h3>
    <p>Update your profile information here.</p>
  </div>
  
  <div class="pm7-tab-content" id="security-panel">
    <h3>Security</h3>
    <p>Manage your password and security settings.</p>
  </div>
</div>

Accessibility

  • Uses ARIA tablist, tab, and tabpanel roles
  • Proper aria-controls and aria-selected attributes
  • Keyboard navigation follows ARIA authoring practices
  • Focus management for screen readers

Keyboard Navigation

  • Tab - Move focus into tab list
  • Arrow Left/Up - Move to previous tab
  • Arrow Right/Down - Move to next tab
  • Home - Jump to first tab
  • End - Jump to last tab
  • Enter or Space - Activate focused tab

Best Practices

  • Clear labels - Use descriptive, concise tab labels
  • Logical order - Arrange tabs in a logical sequence
  • Limited number - Avoid more than 5-7 tabs in one group
  • Consistent content - Each tab should contain related content
  • Visual feedback - Always show which tab is active

Copy this link that can be used as documentation for working with this component:

https://raw.githubusercontent.com/patrickmast/pm7-ui/main/packages/core/src/components/tab-selector/README.md

🤖 AI-Optimized Documentation

This link contains complete Markdown documentation that is perfectly readable by AI assistants, developers, and other automated systems. Directly accessible on GitHub - including all essential PM7 Tab Selector implementation guidance.

Perfect for ChatGPT, Claude, and other AI code assistants