Tabs
Line and pill tab navigation with optional panel wiring.
Tabs is a compound component: a host, a trigger directive, and an optional panel directive.
import { KuiTabs, KuiTab, KuiTabPanel } from '@kikita-labs/ui';Bind value to the active tab and pair each kuiTab with a matching kuiTabPanel.
<kui-tabs [(value)]="activeTab">
<button kuiTab value="overview">Overview</button>
<button kuiTab value="settings">Settings</button>
<button kuiTab value="logs">Logs</button>
<div kuiTabPanel value="overview">Overview content.</div>
<div kuiTabPanel value="settings">Settings content.</div>
<div kuiTabPanel value="logs">Log content.</div>
</kui-tabs>Set variant to pill for a soft background indicator. hasError adds a small danger dot to a tab without changing its selected state.
<kui-tabs variant="pill" [(value)]="activeTab">
<button kuiTab value="daily">Daily</button>
<button kuiTab value="weekly" hasError errorLabel="Contains validation errors">Weekly</button>
<button kuiTab value="monthly">Monthly</button>
<div kuiTabPanel value="daily">Daily report content.</div>
<div kuiTabPanel value="weekly">Weekly report content.</div>
<div kuiTabPanel value="monthly">Monthly report content.</div>
</kui-tabs>Set orientation to vertical to stack the tab list in a column. Add inverted when the panel should sit before the tab list and the indicator should move to the start edge.
<kui-tabs orientation="vertical" [(value)]="activeTab">
<button kuiTab value="profile">Profile</button>
<button kuiTab value="billing">Billing</button>
<button kuiTab value="security">Security</button>
<div kuiTabPanel value="profile">Profile content.</div>
<div kuiTabPanel value="billing">Billing content.</div>
<div kuiTabPanel value="security">Security content.</div>
</kui-tabs>Set controlsPanels to false when tabs act as navigation and the routed content is rendered elsewhere, such as a router-outlet, instead of local kuiTabPanel elements.
<kui-tabs [(value)]="currentSection" [controlsPanels]="false" aria-label="Sections">
<button kuiTab value="/overview">Overview</button>
<button kuiTab value="/settings">Settings</button>
<button kuiTab value="/team">Team</button>
</kui-tabs>
<p class="navigation-tabs-example__note">
Selected value: <code>{{ currentSection() }}</code>
</p>Set defaults.tabs once for the application or for a subtree. Each option resolves as local input > defaults.tabs.<option> > built-in default.
import { provideKikitaUi } from '@kikita-labs/ui';
export const appConfig: ApplicationConfig = {
providers: [
provideKikitaUi({
defaults: {
tabs: {
/* options below */
},
},
}),
],
};| Name | Type | Default | Description |
|---|---|---|---|
| size | 'xs' | 'sm' | 'md' | 'lg' | — | Component size. Takes precedence over the global defaults.size. |
| variant | 'line' | 'pill' | — | Default variant. |
| orientation | 'horizontal' | 'vertical' | — | Default orientation. |
| previousIcon | KuiIconGlyph | — | Icon of the previous control. Takes precedence over defaults.icons.previous. See Structural Icons. |
| nextIcon | KuiIconGlyph | — | Icon of the next control. Takes precedence over defaults.icons.next. See Structural Icons. |
Set any of these on the component or an ancestor to restyle one part. Each token is optional: when it is not set, the part uses the role or scale token in the default column.
| Name | Type | Default | Description |
|---|---|---|---|
| --kui-tabs-scroll-btn-color | CSS custom property | --kui-color-text-secondary | S scroll btn color |
| --kui-tabs-scroll-btn-color-hover | CSS custom property | --kui-color-text | S scroll btn color, hover |
| --kui-tabs-scroll-fade-color | CSS custom property | --kui-color-bg | S scroll fade color |
| --kui-tab-focus-ring-color | CSS custom property | --kui-color-focus | focus ring color |
| --kui-tab-panel-focus-ring-color | CSS custom property | --kui-color-focus | panel focus outline color |
Every text the component owns (accessible names, visible words, announcements) is a typed message with an English default. Override it for the application with provideKikitaUi({ messages }), or for a subtree with provideKuiMessages.
| Name | Type | Default | Description |
|---|---|---|---|
| scrollLeft | string | — | Scroll left button. Default Scroll tabs left. |
| scrollRight | string | — | Scroll right button. Default Scroll tabs right. |
| errorIndicator | string | — | Hidden text of the error dot. Default has error. |
Inputs verified against @kikita-labs/ui v2.0.0 v2.0.0 public typings.
| Name | Type | Default | Description |
|---|---|---|---|
| variant | 'line' | 'pill' | undefined | undefined | Tab visual style: underline indicator (line) or pill background (pill). Falls back to defaults.tabs.variant, then line. |
| size | 'xs' | 'sm' | 'md' | 'lg' | undefined | undefined | Tab trigger height and font size. Falls back to defaults.tabs.size, then the root size, then md. |
| orientation | 'horizontal' | 'vertical' | undefined | undefined | Layout direction of the tab list (defaults.tabs.orientation, then horizontal). Vertical stacks triggers in a column with the indicator on the side edge. |
| inverted | boolean | false | Flips the tab edge. Horizontal tabs render panels above and the indicator on top; vertical tabs render panels before the list and the indicator on the start edge. |
| controlsPanels | boolean | true | Whether tabs expose aria-controls links to projected kuiTabPanel elements. Set to false when tabs are used as navigation and content is rendered elsewhere, such as a router-outlet. |
| [(value)] | string | - | Value of the active tab. |
| [(selected)] | string | - | Deprecated alias for value, kept in sync with it. Use value instead; planned for removal in the next major version. |
| [kuiTab] value | string | - | Identifier for this tab trigger. Must match a kuiTabPanel value when controlsPanels is true. |
| [kuiTab] hasError | boolean | false | Shows a small danger dot next to the tab label without changing the selected state or tab color. |
| [kuiTab] errorLabel | string | undefined | undefined | Screen-reader-only text announced alongside the error dot. Falls back to the tabs.errorIndicator message (has error). |
| [kuiTabPanel] value | string | - | Identifier matching a [kuiTab] value. Panel is shown when its value matches the tabs value. |
| --kui-tabs-gap | CSS length | 2px | Gap between tab triggers in the list. |
| --kui-tabs-border | CSS color | var(--kui-color-border) | Border color of the tab list edge (bottom for horizontal, side for vertical). |
| --kui-tabs-panel-gap | CSS length | var(--kui-space-4) | Gap between the tab list and the active panel. |
| --kui-tab-height | CSS length | var(--kui-btn-height) | Tab trigger block size. Overridden per size. |
| --kui-tab-px | CSS length | var(--kui-btn-px) | Tab trigger inline padding. Overridden per size. |
| --kui-tab-indicator | CSS color | var(--kui-color-primary-fill) | Color of the selected-tab indicator (underline for line, background for pill). |
| --kui-tab-fg-active | CSS color | var(--kui-color-text) | Text color of the selected tab. |
| --kui-tab-gap | CSS custom property | - | Gap inside a tab trigger. |
| --kui-tab-radius | CSS custom property | - | Tab trigger corner radius. |
| --kui-tab-fg | CSS custom property | - | Tab foreground. |
| --kui-tab-fg-hover | CSS custom property | - | Tab foreground on hover. |
| --kui-tab-bg-hover | CSS custom property | - | Tab background on hover. |
| --kui-tab-indicator-size | CSS custom property | - | Thickness of the active indicator. |
| --kui-tab-font-size | CSS custom property | - | Tab font size. |
| --kui-tab-font-weight | CSS custom property | - | Tab font weight. |
| --kui-tab-font-weight-active | CSS custom property | - | Active tab font weight. |
| --kui-tab-pill-gap | CSS custom property | - | Gap between pill tabs. |
| --kui-tab-pill-radius | CSS custom property | - | Pill tab corner radius. |
| --kui-tab-pill-bg-hover | CSS custom property | - | Pill tab background on hover. |
| --kui-tab-pill-bg-active | CSS custom property | - | Active pill tab background. |
| --kui-tab-pill-fg-active | CSS custom property | - | Active pill tab foreground. |
| KuiTabsOptions | interface | - | Shape of defaults.tabs: size, variant, orientation, previousIcon and nextIcon. |
Tabs owns keyboard navigation and the tablist/tab/tabpanel ARIA structure.
- The list container uses
role="tablist". - Each trigger uses
role="tab"witharia-selectedand rovingtabindex. - Each panel uses
role="tabpanel". aria-controlsis emitted by default and should point to a matching[kuiTabPanel]; disable this wiring with[controlsPanels]="false"for navigation-style tabs without local panels.ArrowLeft/ArrowRightmove focus between tabs.Homefocuses the first tab;Endfocuses the last tab.- Scroll buttons are named by the
tabs.scrollLeftandtabs.scrollRightmessages, and the error dot text bytabs.errorIndicator. - At narrow widths the tablist scrolls horizontally and exposes accessible scroll buttons when needed.
- Tabs covers keyboard navigation and static ARIA review. Screen reader and other assistive-technology verification has not been completed for this primitive yet; see
state-coverage.mdin the library repository for current review status.
Consumer-visible changes of @kikita-labs/ui 2.0 for Tabs.
- The classes are
KuiTabs,KuiTabandKuiTabPanel; theComponentandDirectivesuffixes are gone. - Size, variant and orientation defaults moved to
provideKuiDefaults({ tabs: { ... } }), together withpreviousIconandnextIconglyphs; the inputs are nowundefineduntil set. - Scroll button names and the default
errorLabelcome from thetabsmessages. - Hover and pressed fills read
--kui-color-state-hoverand--kui-color-state-active, and--kui-tab-indicator-sizesets the indicator thickness. - The scroll fade no longer carries a literal colour fallback.