Tabs
@xui/tabsTabbed navigation. Arrow keys move between tabs (roving tabindex), Home/End jump to the ends, and disabled tabs are skipped. [(selectedTabId)] two-way binding; animate slides an indicator, orientation/fill/large adjust layout.
Install
pnpm add @xui/tabs Add the barrel to a standalone component's imports:
import { XuiTabsImports } from '@xui/tabs';@Component({ imports: [XuiTabsImports], // …})Examples
Default
Loading preview…
<div class="w-[32rem]"> <xui-tabs [(selectedTabId)]="selected"> <xui-tab id="overview" title="Overview"> <p class="text-sm">A high-level summary of the project and its status.</p> </xui-tab> <xui-tab id="activity" title="Activity"> <p class="text-sm">Recent activity across the team.</p> </xui-tab> <xui-tab id="settings" title="Settings"> <p class="text-sm">Configuration and preferences.</p> </xui-tab> <xui-tab id="archived" title="Archived" [disabled]="true"> <p class="text-sm">Archived items.</p> </xui-tab> </xui-tabs></div>Animated
Loading preview…
<div class="w-[32rem]"> <xui-tabs animate selectedTabId="two"> <xui-tab id="one" title="First">First panel</xui-tab> <xui-tab id="two" title="Second">Second panel</xui-tab> <xui-tab id="three" title="Third">Third panel</xui-tab> </xui-tabs></div>Fill
Loading preview…
<div class="w-[32rem]"> <xui-tabs fill animate selectedTabId="a"> <xui-tab id="a" title="Files">Files panel</xui-tab> <xui-tab id="b" title="Commits">Commits panel</xui-tab> <xui-tab id="c" title="Branches">Branches panel</xui-tab> </xui-tabs></div>From data
Loading preview…
<div class="w-[32rem]"> <xui-tabs animate [(selectedTabId)]="selected"> @for (item of items; track item.id) { <xui-tab [id]="item.id" [title]="item.title"> <p class="text-sm">{{ item.body }}</p> </xui-tab> } </xui-tabs></div>Without ids
Loading preview…
<div class="w-[32rem]"> <xui-tabs> <xui-tab title="Description">What the thing is.</xui-tab> <xui-tab title="Reviews">What people made of it.</xui-tab> <xui-tab title="Shipping">When it turns up.</xui-tab> </xui-tabs></div>Vertical
Loading preview…
<div class="w-[32rem]"> <xui-tabs orientation="vertical" animate selectedTabId="profile"> <xui-tab id="profile" title="Profile">Profile settings</xui-tab> <xui-tab id="account" title="Account">Account settings</xui-tab> <xui-tab id="security" title="Security">Security settings</xui-tab> </xui-tabs></div>API
Marks an <ng-template> inside a xui-tab as the tab's title, for when a plain title string is not enough (icons, tags, …).
A single tab. Its projected content is the panel body (rendered lazily via an <ng-template>); the tab strip label comes from the title input or a [xuiTabTitle] template.
Inputs
idstringStable identifier used for selection and ARIA wiring. Optional: a tab left without one takes a generated id, which is enough for the ARIA wiring and for the tab strip to work uncontrolled. Give real ids to the tabs whose selection is driven from outside — [(selectedTabId)] can only name a tab it can spell.injectUniqueId('xui-tab')titlestringPlain-text tab-strip label (ignored when a [xuiTabTitle] template is given).''disabledbooleanMake the tab unselectable. It stays in the list, is skipped by the arrow keys, and is never chosen as the default selection.falseA tab set: a role="tablist" of titles over the panel of whichever xui-tab is selected.
Variants
animatedfalselargefalsefillfalseInputs
classClassValueExtra classes, merged into the component's own rather than replacing them.''selectedTabIdstring | nullThe active tab id. Two-way bindable with [(selectedTabId)]. Left null it settles on the first enabled tab and writes that back after the first render; an id naming no live tab falls back the same way.nullorientation'horizontal' | 'vertical'Run the tab list across the top (horizontal) or down the side (vertical). Also picks which arrow keys move the selection.this.config.orientationfillbooleanStretch the tabs to share the list's full width. Horizontal orientation only.falselargebooleanUse the roomier tab padding and base font size.this.config.largeanimatebooleanSlide an indicator bar under the active tab instead of a static underline.this.config.animaterenderActiveTabPanelOnlybooleanKeep only the active panel in the DOM (the others are not rendered).false