Skip to content

Tabs

Splits content into sections that are shown one at a time. TabsTrigger and TabsContent are matched by their value.

The fields of the entry.
Tabs.tsx
import {Tabs, TabsContent, TabsList, TabsTrigger} from 'alinea/components'

export function TabsExample() {
  return (
    <Tabs defaultValue="document">
      <TabsList aria-label="Entry">
        <TabsTrigger value="document">Document</TabsTrigger>
        <TabsTrigger value="metadata">Metadata</TabsTrigger>
        <TabsTrigger value="history">History</TabsTrigger>
      </TabsList>
      <TabsContent value="document">The fields of the entry.</TabsContent>
      <TabsContent value="metadata">
        Title and description for search.
      </TabsContent>
      <TabsContent value="history">Earlier versions of the entry.</TabsContent>
    </Tabs>
  )
}

Variants

line underlines the selected tab, subtle gives it a background and enclosed sets the tabs in a track, like a segmented control.

TabsVariants.tsx
import {Tabs, TabsList, TabsTrigger} from 'alinea/components'

const variants = ['line', 'subtle', 'enclosed'] as const

export function TabsVariantsExample() {
  return (
    <div style={{display: 'grid', gap: 24}}>
      {variants.map(variant => (
        <Tabs key={variant} variant={variant} defaultValue="all">
          <TabsList aria-label={`Filter, ${variant}`}>
            <TabsTrigger value="all">All</TabsTrigger>
            <TabsTrigger value="published">Published</TabsTrigger>
            <TabsTrigger value="drafts">Drafts</TabsTrigger>
          </TabsList>
        </Tabs>
      ))}
    </div>
  )
}

Vertical

With orientation="vertical" the tabs stand next to their content, which suits settings with many sections.

Site name and logo.
TabsVertical.tsx
import {Tabs, TabsContent, TabsList, TabsTrigger} from 'alinea/components'

export function TabsVerticalExample() {
  return (
    <Tabs orientation="vertical" variant="subtle" defaultValue="general">
      <TabsList aria-label="Settings">
        <TabsTrigger value="general">General</TabsTrigger>
        <TabsTrigger value="languages">Languages</TabsTrigger>
        <TabsTrigger value="media" disabled>
          Media
        </TabsTrigger>
      </TabsList>
      <TabsContent value="general">Site name and logo.</TabsContent>
      <TabsContent value="languages">
        English, Nederlands, Français.
      </TabsContent>
      <TabsContent value="media">Upload limits.</TabsContent>
    </Tabs>
  )
}

Props

<Tabs>

A set of layered sections of content, displayed one at a time

PropTypeDefaultDescription
valuestringDefault –
defaultValuestringDefault –
onValueChange(value: string) => voidDefault –
orientationOrientationDefault 'horizontal'
variant'line' | 'subtle' | 'enclosed'Default 'line'
disabledbooleanDefault –
idstringDefault –

Also accepts className and style and data-* attributes.

<TabsList>

The row of tab triggers, it scrolls horizontally when the triggers do not fit.

PropTypeDefaultDescription
children*ReactNodeDefault –

Also accepts className and style, id and aria-* labelling attributes and data-* attributes.

<TabsTrigger>

PropTypeDefaultDescription
value*stringDefault –
disabledbooleanDefault –
aria-labelstringDefault –

Also accepts className and style and data-* attributes.

<TabsContent>

PropTypeDefaultDescription
value*stringDefault –

Also accepts className and style and data-* attributes.

Accessibility

The arrow keys move between tabs, Home and End jump to the first and last one. Only the selected tab is in the tab order, so Tab moves on to its content.