ComponentStandalone

Tabs

Tabbed container. Use projected content for simple tabs, or set routerLink on children to switch into router mode.

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.

Overview content — short and friendly.

<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

Active
<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

NameDescriptionTypeDefault
activeActive tab key. Two-way bindable.string | nullnull
sizeVisual size variant.'sm' | 'md' | 'lg''md'

Tab API

NameDescriptionTypeDefault
titlerequiredVisible label.string
keyStable id.stringauto
routerLinkWhen set, the tab becomes a [routerLink] link; the parent skips its content panel.string | readonly string[] | nullnull
disabledDisable the tab.booleanfalse

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.

VariableDefaultDeclared on
--wr-tabs-bordervar(--wr-color-outline).wr-tabs
--wr-tabs-colorvar(--wr-color-on-surface-muted).wr-tabs
--wr-tabs-color-activevar(--wr-color-primary-ink).wr-tabs
--wr-tabs-color-hovervar(--wr-color-on-surface).wr-tabs
--wr-tabs-fade1.5rem.wr-tabs__strip
--wr-tabs-fade-axisto right.wr-tabs__strip +1 variant override
--wr-tabs-fade-end0px.wr-tabs__strip +1 variant override
--wr-tabs-fade-start0px.wr-tabs__strip +1 variant override
--wr-tabs-font-sizevar(--wr-control-font-size-md).wr-tabs +2 variant overrides
--wr-tabs-indicatorvar(--wr-color-primary).wr-tabs
--wr-tabs-line-heightvar(--wr-control-line-height-md).wr-tabs +2 variant overrides
--wr-tabs-padding-x1rem.wr-tabs +2 variant overrides
--wr-tabs-padding-y0.625rem.wr-tabs +2 variant overrides