Installation
import { WrTabs, WrTab } from 'ngwr/tabs';
@Component({ imports: [WrTabs, WrTab] })
export class MyComponent {}Content tabs
Children project body content; parent renders an active-tab panel.
<wr-tabs [(active)]="key">
<wr-tab key="overview" title="Overview">Overview content…</wr-tab>
<wr-tab key="details" title="Details">Details content…</wr-tab>
<wr-tab key="logs" title="Logs">Logs content…</wr-tab>
</wr-tabs>Router tabs
Set routerLink on any child to switch the whole strip into router mode. The parent skips its content panel — drop a <router-outlet> below.
<!-- imports: [WrTabs, WrTab, WrTabsRouting] from 'ngwr/tabs' + 'ngwr/tabs/router' -->
<wr-tabs wrTabsRouting>
<wr-tab title="Overview" routerLink="overview" />
<wr-tab title="Details" routerLink="details" />
<wr-tab title="Logs" routerLink="logs" />
</wr-tabs>
<router-outlet />Disabled tab
<wr-tab title="WIP" disabled>…</wr-tab>Router adapter — template reference
[wrTabsRouting] exports itself under its own name, so a template can ask the router adapter the same questions the strip does.
<wr-tabs wrTabsRouting #routing="wrTabsRouting">
<wr-tab title="Overview" routerLink="overview" />
<wr-tab title="Details" routerLink="details" />
</wr-tabs>
<!-- Anywhere else in the same template -->
<a [href]="routing.href('overview')">Permalink to the first tab</a>Tabs API
| Name | Description | Type | Default |
|---|---|---|---|
active | Active tab key. Two-way bindable. | string | null | null |
size | Visual size variant. | 'sm' | 'md' | 'lg' | 'md' |
Tab API
| Name | Description | Type | Default |
|---|---|---|---|
titlerequired | Visible label. | string | — |
key | Stable id. | string | auto |
routerLink | When set, the tab becomes a [routerLink] link; the parent skips its content panel. | string | readonly string[] | null | null |
disabled | Disable the tab. | boolean | false |
CSS variables
Custom properties ngwr/tabs publishes. Each default below is declared on the component's own selector, so a :root override is shadowed by it — set them on that selector, on a wrapper you scope yourself, or inline on the element. Unlike the BEM class names, these are the supported way to restyle the component.
| Variable | Default | Declared on |
|---|---|---|
--wr-tabs-border | var(--wr-color-outline) | .wr-tabs |
--wr-tabs-color | var(--wr-color-on-surface-muted) | .wr-tabs |
--wr-tabs-color-active | var(--wr-color-primary-ink) | .wr-tabs |
--wr-tabs-color-hover | var(--wr-color-on-surface) | .wr-tabs |
--wr-tabs-fade | 1.5rem | .wr-tabs__strip |
--wr-tabs-fade-axis | to right | .wr-tabs__strip +1 variant override |
--wr-tabs-fade-end | 0px | .wr-tabs__strip +1 variant override |
--wr-tabs-fade-start | 0px | .wr-tabs__strip +1 variant override |
--wr-tabs-font-size | var(--wr-control-font-size-md) | .wr-tabs +2 variant overrides |
--wr-tabs-indicator | var(--wr-color-primary) | .wr-tabs |
--wr-tabs-line-height | var(--wr-control-line-height-md) | .wr-tabs +2 variant overrides |
--wr-tabs-padding-x | 1rem | .wr-tabs +2 variant overrides |
--wr-tabs-padding-y | 0.625rem | .wr-tabs +2 variant overrides |