Tabs
Navigate between views within a context.
Basic Tabs
Content for Tab 1. This panel is active by default.
Content for Tab 2. Click the tab to see this content.
Content for Tab 3. Use tabs to organize related content.
<div class="ui-tabs" data-ui-tabs>
<div class="ui-tabs__list" role="tablist">
<button class="ui-tabs__trigger" data-ui-tab="tab1">Tab 1</button>
<button class="ui-tabs__trigger" data-ui-tab="tab2">Tab 2</button>
<button class="ui-tabs__trigger" data-ui-tab="tab3">Tab 3</button>
</div>
<div class="ui-tabs__content">
<div id="tab1" class="ui-tabs__panel ui-tabs__panel--active">Content 1</div>
<div id="tab2" class="ui-tabs__panel">Content 2</div>
<div id="tab3" class="ui-tabs__panel">Content 3</div>
</div>
</div>
<div class="ui-tabs" data-ui-tabs>
<div class="ui-tabs__list" role="tablist">
<button class="ui-tabs__trigger"
data-ui-tab="tab1"
ng-click="onTabChange('tab1')">{{ tabs[0].label }}</button>
<button class="ui-tabs__trigger"
data-ui-tab="tab2"
ng-click="onTabChange('tab2')">{{ tabs[1].label }}</button>
</div>
<div class="ui-tabs__content">
<div id="tab1" class="ui-tabs__panel ui-tabs__panel--active">{{ tabs[0].content }}</div>
<div id="tab2" class="ui-tabs__panel">{{ tabs[1].content }}</div>
</div>
</div>
<div class="ui-tabs" data-ui-tabs>
<div class="ui-tabs__list" role="tablist">
<button class="ui-tabs__trigger"
data-ui-tab="tab1"
(click)="onTabChange('tab1')">{{ tabs[0].label }}</button>
<button class="ui-tabs__trigger"
data-ui-tab="tab2"
(click)="onTabChange('tab2')">{{ tabs[1].label }}</button>
</div>
<div class="ui-tabs__content">
<div id="tab1" class="ui-tabs__panel ui-tabs__panel--active">{{ tabs[0].content }}</div>
<div id="tab2" class="ui-tabs__panel">{{ tabs[1].content }}</div>
</div>
</div>
<div className="ui-tabs" data-ui-tabs>
<div className="ui-tabs__list" role="tablist">
<button className="ui-tabs__trigger"
data-ui-tab="tab1"
onClick={() => handleTabChange('tab1')}>{tabs[0].label}</button>
<button className="ui-tabs__trigger"
data-ui-tab="tab2"
onClick={() => handleTabChange('tab2')}>{tabs[1].label}</button>
</div>
<div className="ui-tabs__content">
<div id="tab1" className="ui-tabs__panel ui-tabs__panel--active">{tabs[0].content}</div>
<div id="tab2" className="ui-tabs__panel">{tabs[1].content}</div>
</div>
</div>
Pill Tabs
Add the ui-tabs--pills modifier for pill-style tabs.
Overview content
Details content
Settings content
<div class="ui-tabs ui-tabs--pills" data-ui-tabs>
<div class="ui-tabs__list" role="tablist">
<button class="ui-tabs__trigger" data-ui-tab="pill1">Overview</button>
<button class="ui-tabs__trigger" data-ui-tab="pill2">Details</button>
<button class="ui-tabs__trigger" data-ui-tab="pill3">Settings</button>
</div>
<div class="ui-tabs__content">
<div id="pill1" class="ui-tabs__panel ui-tabs__panel--active">Overview content</div>
<div id="pill2" class="ui-tabs__panel">Details content</div>
<div id="pill3" class="ui-tabs__panel">Settings content</div>
</div>
</div>
Events
Tabs emit custom events that you can listen to.
| Event | Description |
|---|---|
ui:tabs:change |
Fired before tab change (cancelable) |
ui:tabs:changed |
Fired after tab changed |
document.addEventListener('ui:tabs:changed', (e) => {
console.log('Tab changed:', e.detail);
});
// In your controller
angular.module('app').controller('TabsCtrl', function($scope, $document) {
$document[0].addEventListener('ui:tabs:changed', function(e) {
$scope.$apply(function() {
$scope.activeTab = e.detail.tabId;
console.log('Tab changed:', e.detail);
});
});
});
import { Component, OnInit, OnDestroy } from '@angular/core';
@Component({ ... })
export class TabsComponent implements OnInit, OnDestroy {
activeTab: string;
private changeHandler = (e: CustomEvent) => {
this.activeTab = e.detail.tabId;
console.log('Tab changed:', e.detail);
};
ngOnInit() {
document.addEventListener('ui:tabs:changed', this.changeHandler);
}
ngOnDestroy() {
document.removeEventListener('ui:tabs:changed', this.changeHandler);
}
}
import { useEffect, useState } from 'react';
function TabsExample() {
const [activeTab, setActiveTab] = useState('tab1');
useEffect(() => {
const handleChange = (e) => {
setActiveTab(e.detail.tabId);
console.log('Tab changed:', e.detail);
};
document.addEventListener('ui:tabs:changed', handleChange);
return () => document.removeEventListener('ui:tabs:changed', handleChange);
}, []);
return ( /* ... */ );
}
Data Attributes
| Attribute | Description |
|---|---|
data-ui-tabs |
Marks container as a tabs component (required) |
data-ui-tab="panelId" |
Links trigger to panel by ID (without #) |
CSS Classes Reference
| Class | Description |
|---|---|
.ui-tabs |
Base tabs container |
.ui-tabs--pills |
Pill-style variant |
.ui-tabs__list |
Tab button container |
.ui-tabs__trigger |
Individual tab button |
.ui-tabs__trigger--active |
Active tab state |
.ui-tabs__content |
Tab panels container |
.ui-tabs__panel |
Individual tab panel (hidden by default) |
.ui-tabs__panel--active |
Active panel state (visible) |
Accessibility
- Use
role="tablist"on the tab list container - Use
role="tab"on tab buttons - Use
role="tabpanel"on content panels - Keyboard navigation: Arrow keys to move between tabs
- Enter/Space to activate a tab