GUILD OF GLEKS UIv21.4.4

gog-tabs / gog-tab

Tabs

A tablist over projected <gog-tab> children. Each tab declares its own header text, icon and disabled state, so a tab is defined in exactly one place rather than split between a header array and a content block.

Overview

Import both components and nest them.

typescript
import { TabComponent, TabsComponent } from '@guildofgleks/ui';

@Component({
  // ...
  imports: [TabsComponent, TabComponent],
})

Basic usage:

Profile content.

<gog-tabs ariaLabel="Account" [(activeIndex)]="activeIndex">
  <gog-tab label="Profile">Profile content.</gog-tab>
  <gog-tab label="Settings" iconName="info">Settings content.</gog-tab>
  <gog-tab label="Billing" [disabled]="true">Not available.</gog-tab>
</gog-tabs>

Eager or lazy content

Content written directly inside a <gog-tab> renders eagerly and is merely hidden while inactive — which is what you want for cheap content, because scroll position, un-submitted input and any state the DOM is holding all survive a switch. Wrap it in an <ng-template gogTabContent> and it is instead built on first activation and kept alive after.

Which you get is decided by whether that template is present — there is no lazy input to keep in sync with it.

Type in the first tab, switch to the second and back: the text is still there. The third tab's content is not in the DOM until you open it.

<gog-tabs ariaLabel="Reports">
  <!-- Eager: rendered up front, merely hidden while inactive. Scroll position and
       half-typed input survive a switch. -->
  <gog-tab label="Summary">
    <input placeholder="Type here, switch away, come back" />
  </gog-tab>

  <!-- Lazy: built on first activation, kept alive after. -->
  <gog-tab label="Expensive report">
    <ng-template gogTabContent>
      <app-expensive-report />
    </ng-template>
  </gog-tab>
</gog-tabs>

Examples

Alignment

stretch makes the headers share the full width; the other three pack them to one end or the middle.

Overview.

Overview.

Overview.

Overview.

<gog-tabs align="start"></gog-tabs>
<gog-tabs align="center"></gog-tabs>
<gog-tabs align="end"></gog-tabs>
<gog-tabs align="stretch"></gog-tabs>

Vertical

The tablist runs down the side. Arrow keys follow the orientation, so ArrowDown moves between tabs here and is left to the page when horizontal.

General settings.

Overflowing headers 21.3.1

Too many headers to fit scroll inside a gog-scroll rather than a native overflow-x — a native scrollbar is the one piece of chrome no --gog-* token can reach.

scrollActiveIntoView (on by default) then keeps the selected tab visible: arrow-key through the headers and the row follows, instantly on first render and smoothly afterwards — instantly again under prefers-reduced-motion. Before this, the keyboard could move focus to a tab that stayed off-screen.

showScrollTrack controls the track itself, and unset it followsscrollActiveIntoView: hidden while that is on, because a track the user never has to drag is chrome rather than help — and shown once it is off, where it is the only hint that there is more to reach.

Inbox.

Custom headers

A gogTabHeader template replaces the header button's content for every tab, with the gog-tab itself plus active, disabled and index in its context.

Unread messages.

<gog-tabs ariaLabel="Inbox">
  <ng-template gogTabHeader let-tab let-active="active">
    <span>{{ tab.label() }}</span>
    @if (active) {
      <gog-tag variant="info" size="xsm">now</gog-tag>
    }
  </ng-template>

  <gog-tab label="Unread"></gog-tab>
  <gog-tab label="Archived"></gog-tab>
</gog-tabs>

Accessibility

The headers form a real tablist: one tab stop for the whole row, arrow keys to move between tabs (following orientation, so a horizontal tablist leaves ArrowDown to the page), and Home/End to jump to the ends. Disabled tabs are skipped rather than merely unclickable.

Each panel is a tabpanel labelled by its header and is itself focusable, so tabbing out of the tablist lands in the content. Set ariaLabel on <gog-tabs> to name the set.

API Reference

gog-tabs — inputs

NameTypeDefaultDescription
scrollActiveIntoView21.3.1booleantrueWith an overflowing header row, selecting a tab scrolls it into view — instantly on first render, smoothly afterwards (and instantly under prefers-reduced-motion).
showScrollTrack21.3.1boolean | undefinedundefinedWhether the header row shows a scrollbar track. Unset it follows scrollActiveIntoView: hidden while that is on (the scrolling is driven for you), shown once it is off, where the track is the only hint that there is more to reach.
activeIndexnumber0Index of the visible tab. Two-way bindable with [(activeIndex)].
align'start' | 'center' | 'end' | 'stretch''start'How the headers distribute along the tablist. stretch makes them share the width.
orientation'horizontal' | 'vertical''horizontal'Which way the tablist runs.
size'xsm' | 'sm' | 'md' | 'lg' | 'slg''md'Header typography and padding.
fullWidthbooleanfalseStretches the whole component to fill its container.
ariaLabelstring''Accessible name for the tablist.

gog-tabs — outputs

NamePayloadDescription
gogTabChangenumberEmitted with the new index when the active tab changes.
activeIndexChangenumberThe activeIndex model’s change event, for [(activeIndex)].

gog-tab — inputs

NameTypeDefaultDescription
labelstring''Header text. A tab declares its own header, so it is defined in exactly one place.
iconNameGogIconName | nullnullOptional leading icon in the header.
disabledbooleanfalseMakes the tab unreachable by click and skipped by arrow navigation.

Content slots

DirectiveDeclared onDescription
gogTabContentgog-tabMakes that tab's content lazy — built on first activation, kept alive after.
gogTabHeadergog-tabs Replaces the header button's content. Context: $implicit (the tab), active, disabled, index.

Styling Tokens

Every CSS custom property the tabs paint with. Override any of them — on a single instance, a subtree, or a theme — to restyle them. See the Theming guide for the full token-layering model, or the Theme Generator to tweak these live.

TokenDescription
--gog-tabs-rest-color / -hover-color / -active-colorTab header label, per state.
--gog-tabs-indicator-color / -indicator-thickness / -indicator-radiusThe bar marking the active tab.
--gog-tabs-header-border-color / -header-border-width / -header-border-styleThe rule under the tablist.
--gog-tabs-{size}-font-size / -{size}-paddingHeader typography and padding, per size step (sm/md/lg/slg).
--gog-tabs-tab-gap / -gap / -icon-sizeGap between headers, between a header’s icon and its label, and icon size.
--gog-tabs-panel-padding / -panel-colorThe content panel below the tablist.
--gog-tabs-focus-ring-color / -focus-ring-width / -focus-ring-offset / -disabled-opacityKeyboard focus ring and the disabled state.