Atomic Angular — Doc interne

Tabs

A thin Tailwind styling layer over Angular's official @angular/aria/tabs primitives — roles, focus and keyboard navigation come entirely from Angular.

Tabs is a thin styling layer over Angular's official ARIA tabs primitives (@angular/aria/tabs). TabsComponent, TabListComponent, TabComponent and TabPanelComponent each apply the matching @angular/aria/tabs directive as a host directive — roles, focus management, keyboard navigation and ARIA attributes are entirely delegated to @angular/aria; galactik only contributes visual variants and classes.

Minimal example

Unlike atomic-ui's Tabs, TabsComponent ships no default layout classes — always add your own (flex flex-col for stacked tabs above panels, flex flex-row for side-by-side vertical tabs).

Three tabs, stacked above their panels
sample.component.ts
import { Component } from "@angular/core";
import { TabsComponent, TabListComponent, TabComponent, TabPanelComponent } from "@sinequa/galactik";

@Component({
  selector: "app-tabs-example",
  imports: [TabsComponent, TabListComponent, TabComponent, TabPanelComponent],
  template: `
    <Tabs class="flex flex-col">
      <TabList selectedTab="overview" (selectedTabChange)="onTabChange($event)">
        <Tab value="overview">Overview</Tab>
        <Tab value="activity">Activity</Tab>
      </TabList>

      <div class="rounded-b-md border border-t-0 p-3">
        <TabPanel value="overview">Overview panel.</TabPanel>
        <TabPanel value="activity">Activity panel.</TabPanel>
      </div>
    </Tabs>
  `,
})
export class TabsExampleComponent {
  onTabChange(value: string) {
    console.log("Selected tab:", value);
  }
}

selectedTab on TabList sets the initially active tab; selection then becomes user-driven, or bind [(selectedTab)] for full two-way control from the host.

How it works

click / arrow keys roving focus / selection selectionMode follow/explicit updates selectedTabChange matches value visible() true/false preserveContent User Tab TabList @angular/aria/tabs pattern selectedTab model Host component Tabs container TabPanel [class.hidden] DeferredContentAware

selectionMode="follow" (default) activates a tab as soon as focus reaches it — best for stateless content. selectionMode="explicit" only highlights the tab on focus; the user must press Space/Enter to activate it — best when activation is expensive (a network fetch, a heavy render).

Recipes

Vertical orientation

Set orientation="vertical" on TabList and switch the wrapping Tabs to a row layout so the list and panels sit side by side. Arrow-key navigation automatically switches to Up/Down.

Vertical tabs, side by side with their panels
vertical-tabs.component.ts
import { Component } from "@angular/core";
import { TabsComponent, TabListComponent, TabComponent, TabPanelComponent } from "@sinequa/galactik";

@Component({
  selector: "app-vertical-tabs",
  imports: [TabsComponent, TabListComponent, TabComponent, TabPanelComponent],
  template: `
    <Tabs class="flex flex-row">
      <TabList orientation="vertical" variant="secondary" selectedTab="general" class="min-w-40 border-r">
        <Tab variant="secondary" value="general">General</Tab>
        <Tab variant="secondary" value="advanced">Advanced</Tab>
      </TabList>

      <div class="grow p-3">
        <TabPanel value="general">General settings.</TabPanel>
        <TabPanel value="advanced">Advanced settings.</TabPanel>
      </div>
    </Tabs>
  `,
})
export class VerticalTabsComponent {}

Preserving panel content, and disabled tabs

Set preserveContent on a TabPanel to keep it mounted (merely hidden via .hidden) while inactive — useful for forms that must retain user input. softDisabled on TabList (default true) keeps a disabled tab reachable by keyboard even though it cannot be activated.

<TabPanel value="form" preserveContent>
  <input placeholder="Stateful — survives tab switches" />
</TabPanel>

<Tab value="billing" disabled>Billing</Tab>

Options

Prop

Type

--tab-max-width (fallback 100%) caps a tab's label width on any ancestor; noTruncate exempts a single tab from it.

Pitfalls

What's next

On this page