Tabs

Tabs enables users to switch among content panels using clickable tab headers. It provides an efficient way to present multiple related sections in a single interface area, with each tab containing distinct content defined by TabItem components.

Key features:

  • Content organization: Efficiently displays multiple content sections in a single interface area
  • Flexible orientation: Supports both horizontal (tabs on top) and vertical (tabs on side) layouts
  • Active tab control: Programmatically set which tab is initially selected
  • Custom header templates: Configurable tab appearance via headerTemplate property
  • Navigation methods: Built-in methods for programmatic tab switching (next(), prev(), setActiveTabIndex(), setActiveTabById())
  • External ID support: Optional id prop for TabItems with context exposure
  • Dynamic content: Works seamlessly with Items for data-driven tabs

Using Tabs

The component accepts only TabItem components as children. Other child components will not be displayed. Each TabItem has a label property for the tab button text, with content provided by placing child components within the TabItem.

<App>
  <Tabs>
    <TabItem label="Account">
      <Text>Account</Text>
    </TabItem>
    <TabItem label="Stream">
      <Text>Stream</Text>
    </TabItem>
    <TabItem label="Support">
      <Text>Support</Text>
    </TabItem>
  </Tabs>
</App>
Example: using Tabs
<App>
  <Tabs>
    <TabItem label="Account">
      <Text>Account</Text>
    </TabItem>
    <TabItem label="Stream">
      <Text>Stream</Text>
    </TabItem>
    <TabItem label="Support">
      <Text>Support</Text>
    </TabItem>
  </Tabs>
</App>

Dynamic Tabs

You can create TabItem children dynamically:

<App>
  <Tabs>
    <Items data="{[1, 2, 3, 4]}">
      <TabItem label="Account {$item}">
        <Card title="Tab Content for Account {$item}"/>
      </TabItem>
    </Items>
  </Tabs>
</App>
Example: using Tabs with dynamic items
<App>
  <Tabs>
    <Items data="{[1, 2, 3, 4]}">
      <TabItem label="Account {$item}">
        <Card title="Tab Content for Account {$item}"/>
      </TabItem>
    </Items>
  </Tabs>
</App>

Behaviors

This component supports the following behaviors:

BehaviorProperties
Animationanimation, animationOptions
Bookmarkbookmark, bookmarkLevel, bookmarkTitle, bookmarkOmitFromToc
Component Labellabel, labelPosition, labelWidth, labelBreak, required, enabled, shrinkToLabel, style, readOnly
Publish/SubscribesubscribeToTopic
Tooltiptooltip, tooltipMarkdown, tooltipOptions
Styling Variantvariant

Properties

accordionView

default: false

When enabled, displays tabs in an accordion-like view where tab headers are stacked vertically and only the active tab's content is visible. Each tab header remains visible and clicking a header opens its content while closing others. When enabled, the orientation property is ignored.

The accordionView property enables an accordion-like layout where tab headers are stacked vertically and only the active tab's content is visible. All tab headers remain visible, and clicking a header opens its content while closing others.

When accordionView is enabled, the orientation property is ignored.

<App>
  <Tabs accordionView="true">
    <TabItem label="Account Information">
      <Card title="Account Details">
        <Text>Your account is active and in good standing.</Text>
        <Text>Account ID: 12345</Text>
        <Text>Member since: January 2024</Text>
      </Card>
    </TabItem>
    <TabItem label="Billing & Payments">
      <Card title="Payment Methods">
        <Text>Current Plan: Professional</Text>
        <Text>Next billing date: November 1, 2025</Text>
        <Text>Payment method: xxxx 4242</Text>
      </Card>
    </TabItem>
    <TabItem label="Security Settings">
      <Card title="Security Options">
        <Text>Two-factor authentication: Enabled</Text>
        <Text>Last password change: September 15, 2025</Text>
        <Text>Active sessions: 2</Text>
      </Card>
    </TabItem>
  </Tabs>
</App>
Example: accordionView
<App>
  <Tabs accordionView="true">
    <TabItem label="Account Information">
      <Card title="Account Details">
        <Text>Your account is active and in good standing.</Text>
        <Text>Account ID: 12345</Text>
        <Text>Member since: January 2024</Text>
      </Card>
    </TabItem>
    <TabItem label="Billing & Payments">
      <Card title="Payment Methods">
        <Text>Current Plan: Professional</Text>
        <Text>Next billing date: November 1, 2025</Text>
        <Text>Payment method: xxxx 4242</Text>
      </Card>
    </TabItem>
    <TabItem label="Security Settings">
      <Card title="Security Options">
        <Text>Two-factor authentication: Enabled</Text>
        <Text>Last password change: September 15, 2025</Text>
        <Text>Active sessions: 2</Text>
      </Card>
    </TabItem>
  </Tabs>
</App>

The accordion view is particularly useful for mobile layouts or when you need to present expandable sections in a vertical format. Each section can be opened independently by clicking its header.

<App>
  <Tabs accordionView="true">
    <Items data="{[
        {title: 'Overview', content: 'Dashboard and quick statistics'},
        {title: 'Reports', content: 'Monthly and annual reports'},
        {title: 'Analytics', content: 'User behavior and metrics'},
        {title: 'Export', content: 'Download data in various formats'}
      ]}">
      <TabItem label="{$item.title}">
        <Card>
          <Text>{$item.content}</Text>
        </Card>
      </TabItem>
    </Items>
  </Tabs>
</App>
Example: accordionView with dynamic content
<App>
  <Tabs accordionView="true">
    <Items data="{[
        {title: 'Overview', content: 'Dashboard and quick statistics'},
        {title: 'Reports', content: 'Monthly and annual reports'},
        {title: 'Analytics', content: 'User behavior and metrics'},
        {title: 'Export', content: 'Download data in various formats'}
      ]}">
      <TabItem label="{$item.title}">
        <Card>
          <Text>{$item.content}</Text>
        </Card>
      </TabItem>
    </Items>
  </Tabs>
</App>

activeTab

This property indicates the index of the active tab. The indexing starts from 0, representing the starting (leftmost) tab. If not set, the first tab is selected by default.

headerTemplate

This property declares the template for the clickable tab area.

<App>
  <Tabs>
    <property name="headerTemplate">
      <Icon name="chevronright" />
      <Text color="green">Account {$header.index}</Text>
    </property>
    <Items data="{[
        {id: 1, name: 'AcmeCorp'}, 
        {id: 2, name: 'BetaLLC'}, 
        {id: 3, name: 'GammaInc'}]
      }">
      <TabItem label="Account {$item}">
        <Card title="Tab Content for Account {$item.name}"/>
      </TabItem>
    </Items>
  </Tabs>
</App>
Example: headerTemplate
<App>
  <Tabs>
    <property name="headerTemplate">
      <Icon name="chevronright" />
      <Text color="green">Account {$header.index}</Text>
    </property>
    <Items data="{[
        {id: 1, name: 'AcmeCorp'}, 
        {id: 2, name: 'BetaLLC'}, 
        {id: 3, name: 'GammaInc'}]
      }">
      <TabItem label="Account {$item}">
        <Card title="Tab Content for Account {$item.name}"/>
      </TabItem>
    </Items>
  </Tabs>
</App>

The headerTemplate property allows you to customize the appearance of tab headers. The template receives a $header context variable with the following properties:

  • id (optional): External ID if provided to TabItem
  • index: Zero-based index of the tab
  • label: The tab's label text
  • isActive: Boolean indicating if this tab is currently active

Individual tab items have an optional identifier, which is passed to the header template.

<App>
  <Tabs>
    <property name="headerTemplate">
      {$header.label}{$header.id ? ' | ID: ' + $header.id : ''}
    </property>
    <TabItem label="Home" id="home-tab">
      Home content
    </TabItem>
    <TabItem label="Accounts" id="accounts-tab">
      Accounts content
    </TabItem>
    <TabItem label="Settings">
      Settings content
    </TabItem>
  </Tabs>
</App>
Example: headerTemplate
<App>
  <Tabs>
    <property name="headerTemplate">
      {$header.label}{$header.id ? ' | ID: ' + $header.id : ''}
    </property>
    <TabItem label="Home" id="home-tab">
      Home content
    </TabItem>
    <TabItem label="Accounts" id="accounts-tab">
      Accounts content
    </TabItem>
    <TabItem label="Settings">
      Settings content
    </TabItem>
  </Tabs>
</App>

Individual TabItem children can customize their header templates, too.

orientation

default: "horizontal"

This property indicates the orientation of the component. In horizontal orientation, the tab sections are laid out on the left side of the content panel, while in vertical orientation, the buttons are at the top. Note: This property is ignored when accordionView is set to true.

Available values: horizontal (default), vertical

tabAlignment

default: "start"

This property controls how tabs are aligned within the tab header container in horizontal orientation. Use 'start' to align tabs to the left, 'end' to align to the right, 'center' to center the tabs, and 'stretch' to make tabs fill the full width of the header. Note: This property is ignored when orientation is set to 'vertical' or when accordionView is enabled.

Available values: start (default), end, center, stretch

The tabAlignment property controls how tabs are aligned within the tab header container in horizontal orientation. It accepts four values: start, end, center, and stretch.

The tabAlignment property is ignored when orientation is set to vertical or when accordionView is enabled.

Alignment: start

Aligns tabs to the left side of the container:

<App>
  <Tabs tabAlignment="start" style="width: 100%">
    <TabItem label="Home">Home content</TabItem>
    <TabItem label="Profile">Profile content</TabItem>
    <TabItem label="Settings">Settings content</TabItem>
  </Tabs>
</App>
Example: tabAlignment='start'
<App>
  <Tabs tabAlignment="start" style="width: 100%">
    <TabItem label="Home">Home content</TabItem>
    <TabItem label="Profile">Profile content</TabItem>
    <TabItem label="Settings">Settings content</TabItem>
  </Tabs>
</App>

Alignment: center

Centers tabs within the container:

<App>
  <Tabs tabAlignment="center" style="width: 100%">
    <TabItem label="Home">Home content</TabItem>
    <TabItem label="Profile">Profile content</TabItem>
    <TabItem label="Settings">Settings content</TabItem>
  </Tabs>
</App>
Example: tabAlignment='center'
<App>
  <Tabs tabAlignment="center" style="width: 100%">
    <TabItem label="Home">Home content</TabItem>
    <TabItem label="Profile">Profile content</TabItem>
    <TabItem label="Settings">Settings content</TabItem>
  </Tabs>
</App>

Alignment: end

Aligns tabs to the right side of the container:

<App>
  <Tabs tabAlignment="end" style="width: 100%">
    <TabItem label="Home">Home content</TabItem>
    <TabItem label="Profile">Profile content</TabItem>
    <TabItem label="Settings">Settings content</TabItem>
  </Tabs>
</App>
Example: tabAlignment='end'
<App>
  <Tabs tabAlignment="end" style="width: 100%">
    <TabItem label="Home">Home content</TabItem>
    <TabItem label="Profile">Profile content</TabItem>
    <TabItem label="Settings">Settings content</TabItem>
  </Tabs>
</App>

Alignment: stretch

Makes tabs fill the full width of the container, distributing them evenly:

<App>
  <Tabs tabAlignment="stretch" style="width: 100%">
    <TabItem label="Home">Home content</TabItem>
    <TabItem label="Profile">Profile content</TabItem>
    <TabItem label="Settings">Settings content</TabItem>
  </Tabs>
</App>
Example: tabAlignment='stretch'
<App>
  <Tabs tabAlignment="stretch" style="width: 100%">
    <TabItem label="Home">Home content</TabItem>
    <TabItem label="Profile">Profile content</TabItem>
    <TabItem label="Settings">Settings content</TabItem>
  </Tabs>
</App>

Events

contextMenu

This event is triggered when the Tabs is right-clicked (context menu).

Signature: contextMenu(event: MouseEvent): void

  • event: The mouse event object.

didChange

This event is triggered when value of Tabs has changed.

Signature: didChange(newValue: any): void

  • newValue: The new value of the component.

The event handler gets these parameters, which refer to the active tab after the change:

  • index: The active tab index
  • id: The identifier of the active tab (if not defined, the framework provides an auto-generated id)
  • label: The label of the active tab
<App var.lastTab="(none)">
  <Tabs onDidChange="
    (newIndex, id, label) => 
      lastTab = newIndex + ': ' + label + ' (' + id + ')'
    ">
    <TabItem id="account" label="Account">
      <Text>Account</Text>
    </TabItem>
    <TabItem label="Stream">
      <Text>Stream</Text>
    </TabItem>
    <TabItem label="Support">
      <Text>Support</Text>
    </TabItem>
  </Tabs>
  <Text>Tab index changed to {lastTab}</Text>
</App>
Example: didChange
<App var.lastTab="(none)">
  <Tabs onDidChange="
    (newIndex, id, label) => 
      lastTab = newIndex + ': ' + label + ' (' + id + ')'
    ">
    <TabItem id="account" label="Account">
      <Text>Account</Text>
    </TabItem>
    <TabItem label="Stream">
      <Text>Stream</Text>
    </TabItem>
    <TabItem label="Support">
      <Text>Support</Text>
    </TabItem>
  </Tabs>
  <Text>Tab index changed to {lastTab}</Text>
</App>

Exposed Methods

next

This method selects the next tab. If the current tab is the last one, it wraps around to the first tab.

Signature: next(): void

<App>
  <Fragment>
    <Tabs id="myTabs">
      <TabItem label="Tab 1">Content 1</TabItem>
      <TabItem label="Tab 2">Content 2</TabItem>
      <TabItem label="Tab 3">Content 3</TabItem>
    </Tabs>
    <Button onClick="myTabs.next()">Next Tab</Button>
  </Fragment>
</App>
Example: next()
<App>
  <Fragment>
    <Tabs id="myTabs">
      <TabItem label="Tab 1">Content 1</TabItem>
      <TabItem label="Tab 2">Content 2</TabItem>
      <TabItem label="Tab 3">Content 3</TabItem>
    </Tabs>
    <Button onClick="myTabs.next()">Next Tab</Button>
  </Fragment>
</App>

prev

This method selects the previous tab. If the current tab is the first one, it wraps around to the last tab.

Signature: prev(): void

<App>
  <Fragment>
    <Tabs id="myTabs">
      <TabItem label="Tab 1">Content 1</TabItem>
      <TabItem label="Tab 2">Content 2</TabItem>
      <TabItem label="Tab 3">Content 3</TabItem>
    </Tabs>
    <Button onClick="myTabs.prev()">Previous Tab</Button>
  </Fragment>
</App>
Example: prev()
<App>
  <Fragment>
    <Tabs id="myTabs">
      <TabItem label="Tab 1">Content 1</TabItem>
      <TabItem label="Tab 2">Content 2</TabItem>
      <TabItem label="Tab 3">Content 3</TabItem>
    </Tabs>
    <Button onClick="myTabs.prev()">Previous Tab</Button>
  </Fragment>
</App>

setActiveTabById

This method sets the active tab by its ID.

Signature: setActiveTabById(id: string): void

<App>
  <Fragment>
    <Tabs id="myTabs">
      <TabItem label="Home" id="home">Home Content</TabItem>
      <TabItem label="Settings" id="settings">Settings Content</TabItem>
      <TabItem label="Help" id="help">Help Content</TabItem>
    </Tabs>
    <Button onClick="myTabs.setActiveTabById('settings')">
      Go to Settings (by ID)
    </Button>
  </Fragment>
</App>
Example: setActiveTabById()
<App>
  <Fragment>
    <Tabs id="myTabs">
      <TabItem label="Home" id="home">Home Content</TabItem>
      <TabItem label="Settings" id="settings">Settings Content</TabItem>
      <TabItem label="Help" id="help">Help Content</TabItem>
    </Tabs>
    <Button onClick="myTabs.setActiveTabById('settings')">
      Go to Settings (by ID)
    </Button>
  </Fragment>
</App>

setActiveTabIndex

This method sets the active tab by index (0-based).

Signature: setActiveTabIndex(index: number): void

<App>
  <Fragment>
    <Tabs id="myTabs">
      <TabItem label="Tab 1">Content 1</TabItem>
      <TabItem label="Tab 2">Content 2</TabItem>
      <TabItem label="Tab 3">Content 3</TabItem>
    </Tabs>
    <Button onClick="myTabs.setActiveTabIndex(2)">Go to Tab 3 (by Index)</Button>
  </Fragment>
</App>
Example: setActiveTabIndex()
<App>
  <Fragment>
    <Tabs id="myTabs">
      <TabItem label="Tab 1">Content 1</TabItem>
      <TabItem label="Tab 2">Content 2</TabItem>
      <TabItem label="Tab 3">Content 3</TabItem>
    </Tabs>
    <Button onClick="myTabs.setActiveTabIndex(2)">Go to Tab 3 (by Index)</Button>
  </Fragment>
</App>

Styling

Theme Variables

VariableDefault Value (Light)Default Value (Dark)
backgroundColor-list-Tabsnonenone
backgroundColor-Tabsnonenone
backgroundColor-trigger-Tabsnonenone
backgroundColor-trigger-Tabs--activenonenone
backgroundColor-trigger-Tabs--hover$color-surface-100$color-surface-100
border-list-Tabsnonenone
border-trigger-Tabsnonenone
borderColor-active-Tabs$color-primary$color-primary
borderColor-Tabs$borderColor$borderColor
borderRadius-list-Tabsnonenone
borderRadius-trigger-Tabsnonenone
borderStyle-Tabssolidsolid
borderWidth-Tabs2px2px
gap-list-Tabs0px0px
padding-trigger-Tabs$space-4$space-4
paddingBottom-trigger-Tabsnonenone
paddingHorizontal-trigger-Tabsnonenone
paddingLeft-trigger-Tabsnonenone
paddingRight-trigger-Tabsnonenone
paddingTop-trigger-Tabsnonenone
paddingVertical-trigger-Tabsnonenone
textColor-trigger-Tabs$color-primary-600$color-primary-600
textColor-trigger-Tabs--active$color-primary-900$color-primary-900
textColor-trigger-Tabs--hover$color-primary-900$color-primary-900