Primitives
Dynamically show and hide content based on an active tab.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam ultricies lacinia arcu, in dignissim magna mollis in. Proin ac faucibus sem. Aliquam sit amet augue non risus commodo volutpat id sit amet nisi. Integer posuere nisl in ligula faucibus vestibulum. Nulla facilisi. Aliquam erat volutpat. Cras eget sem ac velit pellentesque lobortis at in ex. Vestibulum nisl diam, eleifend eget malesuada a, cursus id ante. Morbi fringilla, metus nec consectetur maximus, leo purus gravida est, eu fringilla dui quam fermentum sapien. Vivamus tempus ullamcorper lectus, nec cursus sapien consectetur vel. Praesent vehicula erat ac massa egestas viverra. Pellentesque urna magna, consectetur convallis ante vel, posuere aliquet arcu. Duis eu nulla id sapien lobortis bibendum eget vel velit. Donec sed nisi ac lacus placerat iaculis. Donec blandit eros sit amet nibh accumsan cursus. Morbi sit amet ex et enim tempus porttitor non eu erat. /** This example uses ng-primitives styles, which are imported from ng-primitives/example-theme/index.css in the global styles file **/
import { Component, signal } from "@angular/core";
import {
NgpTabButton,
NgpTabList,
NgpTabPanel,
NgpTabset,
} from "ng-primitives/tabs";
@Component({
selector: "app-root",
imports: [NgpTabset, NgpTabList, NgpTabButton, NgpTabPanel],
styles: `
:host {
display: contents;
}
[ngpTabset] {
width: 100%;
max-width: 512px;
border-radius: 0.75rem;
background-color: var(--ngp-background);
padding: 0.25rem 1rem;
box-shadow: var(--ngp-button-shadow);
}
[ngpTabList] {
display: flex;
gap: 1.5rem;
border-bottom: 1px solid var(--ngp-border);
}
[ngpTabButton] {
border: none;
background-color: transparent;
margin-bottom: -1px;
border-bottom: 2px solid transparent;
padding: 0.5rem 0;
outline: none;
transition: background-color 150ms cubic-bezier(0.4, 0, 0.2, 1);
}
[ngpTabButton][data-focus-visible] {
outline: 2px solid var(--ngp-focus-ring);
outline-offset: 2px;
}
[ngpTabButton][data-active] {
border-color: var(--ngp-background-inverse);
color: var(--ngp-text-primary);
}
[ngpTabPanel] {
padding: 0.5rem 0;
outline: none;
}
[ngpTabPanel]:not([data-active]) {
display: none;
}
`,
template: `
<div [(ngpTabsetValue)]="selectedTab" ngpTabset>
<div ngpTabList>
<button ngpTabButton ngpTabButtonValue="overview">Overview</button>
<button ngpTabButton ngpTabButtonValue="features">Features</button>
<button ngpTabButton ngpTabButtonValue="pricing">Pricing</button>
</div>
<div ngpTabPanel ngpTabPanelValue="overview">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam
ultricies lacinia arcu, in dignissim magna mollis in. Proin ac
faucibus sem. Aliquam sit amet augue non risus commodo volutpat id sit
amet nisi. Integer posuere nisl in ligula faucibus vestibulum. Nulla
facilisi. Aliquam erat volutpat.
</p>
</div>
<div ngpTabPanel ngpTabPanelValue="features">
<p>
Cras eget sem ac velit pellentesque lobortis at in ex. Vestibulum nisl
diam, eleifend eget malesuada a, cursus id ante. Morbi fringilla,
metus nec consectetur maximus, leo purus gravida est, eu fringilla dui
quam fermentum sapien. Vivamus tempus ullamcorper lectus, nec cursus
sapien consectetur vel.
</p>
</div>
<div ngpTabPanel ngpTabPanelValue="pricing">
<p>
Praesent vehicula erat ac massa egestas viverra. Pellentesque urna
magna, consectetur convallis ante vel, posuere aliquet arcu. Duis eu
nulla id sapien lobortis bibendum eget vel velit. Donec sed nisi ac
lacus placerat iaculis. Donec blandit eros sit amet nibh accumsan
cursus. Morbi sit amet ex et enim tempus porttitor non eu erat.
</p>
</div>
</div>
`,
})
export class AppComponent {
/**
* The selected tab
*/
readonly selectedTab = signal<Tab>("overview");
}
type Tab = "overview" | "features" | "pricing";
Import the Tabs primitives from ng-primitives/tabs
.
import { NgpTabset, NgpTabList, NgpTabButton, NgpTabPanel } from 'ng-primitives/tabs';
Assemble the tabs directives in your template.
<div ngpTabset>
<div ngpTabList>
<button ngpTabButton ngpTabButtonValue="tab1">Tab 1</button>
<button ngpTabButton ngpTabButtonValue="tab2">Tab 2</button>
<button ngpTabButton ngpTabButtonValue="tab3">Tab 3</button>
</div>
<div ngpTabPanel ngpTabPanelValue="tab1">Tab 1 content</div>
<div ngpTabPanel ngpTabPanelValue="tab2">Tab 2 content</div>
<div ngpTabPanel ngpTabPanelValue="tab3">Tab 3 content</div>
</div>
Create reusable components that uses the tab directives.
import { Component } from '@angular/core';
import { Tab } from './tab';
import { Tabs } from './tabs';
@Component({
selector: 'app-root',
imports: [Tabs, Tab],
template: `
<app-tabs>
<app-tab value="tab1" label="Tab 1">
<p>Tab 1 content</p>
</app-tab>
<app-tab value="tab2" label="Tab 2">
<p>Tab 2 content</p>
</app-tab>
<app-tab value="tab3" label="Tab 3">
<p>Tab 3 content</p>
</app-tab>
</app-tabs>
`,
})
export default class App {}
Generate a reusable tab components using the Angular CLI.
ng g ng-primitives:primitive tabs
path
: The path at which to create the component file.prefix
: The prefix to apply to the generated component selector.componentSuffix
: The suffix to apply to the generated component class name.fileSuffix
: The suffix to apply to the generated component file name. Defaults to component
.exampleStyles
: Whether to include example styles in the generated component file. Defaults to true
.The following directives are available to import from the ng-primitives/tabs
package:
Apply the `ngpTabset` directive to an element to manage the tabs. Define the active tab
The orientation of the tabset
Whether tabs should activate on focus
Emit the value of the selected tab when it changes
[ngpTabset]
ngpTabset
The following data attributes are applied to the ngpTabset
directive:
Attribute | Description | Value |
---|---|---|
data-orientation |
The orientation of the tabs. | horizontal | vertical |
Apply the `ngpTabList` directive to an element that represents the list of tab buttons.[ngpTabList]
ngpTabList
The following data attributes are applied to the ngpTabList
directive:
Attribute | Description | Value |
---|---|---|
data-orientation |
The orientation of the tabs. | horizontal | vertical |
Apply the `ngpTabButton` directive to an element within a tab list to represent a tab button. This directive should be applied to a button element. The value of the tab this trigger controls
Whether the tab is disabled
[ngpTabButton]
ngpTabButton
The following data attributes are applied to the ngpTabButton
directive:
Attribute | Description | Value |
---|---|---|
data-orientation |
The orientation of the tabs. | horizontal | vertical |
data-active |
Applied when the tab is active. | - |
data-disabled |
Applied when the tab is disabled. | - |
data-hover |
Applied when the tab is hovered. | - |
data-focus-visible |
Applied when the tab is focused. | - |
data-press |
Applied when the tab is pressed. | - |
Apply the `ngpTabPanel` directive to an element that represents the content of a tab. The value of the tab
[ngpTabPanel]
ngpTabPanel
The following data attributes are applied to the ngpTabPanel
directive:
Attribute | Description | Value |
---|---|---|
data-active |
Applied when the tab is active. | - |
data-orientation |
The orientation of the tabs. | horizontal | vertical |
You can configure the default options for all tabs in your application by using the provideTabsConfig
function in a providers array.
import { provideTabsConfig } from 'ng-primitives/tabs';
bootstrapApplication(AppComponent, {
providers: [
provideTabsConfig({
orientation: 'horizontal',
activateOnFocus: false,
wrap: false,
}),
],
});
The following options are available to configure the default tab options:
Define the default orientation of the tabs.
Define whether the tab should activate on focus.
Define whether the tabs should wrap around the tab list.
Adheres to the Tabs WAI-ARIA design pattern.
Copyright © 2025 Angular Primitives