Tabs

Jump to Props

Organise related information into different categories to reduce cognitive load.

Import

import { Tabs } from "@vitality-ds/components";

Usage

Tabs provide an easy way to organise content. By grouping similar information into different categories, Tabs help to reduce cognitive load and avoid overwhelming amounts of content. The tabbed navigation pattern allows a lot of content to be viewed without having to navigate away from a single page.

() => {
  const tabsData = [
    {
      value: "item1",
      label: "Item One",
      contentRenderer: () => "Content for Item One",
    },
    {
      value: "item2",
      label: "Item Two",
      contentRenderer: () => "Content for Item Two",
    },
    {
      value: "item3",
      label: "Item Three",
      contentRenderer: () => "Content for Item Three",
      disabled: true,
    },
  ];
  return (
    <Tabs
      tabListAriaLabel="Sample Tabs showing Basic Usage"
      tabsData={tabsData}
    />
  );
};

Tabs can be used to organize content such as forms, settings, and dashboards so a user does not have to navigate away from their workflow to complete their task. Use tabs to group related information into different categories, helping to reduce cognitive load.

Examples of Tabs usage.
Avoid
  • Tabs should not be used to indicate progress. Use the progress indicator instead.
  • Tabs should not be used if the user is comparing information in two groups, as this would result in the user having to click back and forth to complete a task.

Anatomy

The Tabs component is made up of an individual Tab, Tabs and Tab Content. There is no styling applied to a tab's content, as this is left up to the individual use case to determine. The Tabs themselves have various attributes that make up their anatomy:

Anatomy of tabs in Vitality
  1. Selected: The active tab.
  2. Default: The other available tabs.
  3. Divider: Thin line separating tabs from their content
  4. Badge indicator: Used in tabs that need to hint at their contens
  5. Icon: Optional visual support for a tab's meaning.

Interaction States

When the user interacts with a tab, the below states are shown.

Different states of tabs in Vitality
  1. Selected: The tab when selected.
  2. Default: The default view.
  3. Hover: Hovering over a tab.
  4. Disabled: The tab when disabled
  5. Active: When the user has pressed down on the tab and in its active state.
  6. Focus Visible: Keyboard focus on a tab.

Tab Alignment

Tabs can be aligned either left or stretch to fill their container. By default tabs are aligned to the left and only take up the amount of space required for their contents.

Set the property to either stretch or intial using the tabAlignment prop.

() => {
  const [stretch, setStretch] = React.useState(false);
  return (
    <DocsBox css={{ width: 500, backgroundColor: "$primary1", padding: "$xl" }}>
      <Stack direction="horizontal" justify="end">
        <Switch
          value={stretch}
          checked={stretch}
          id="stretch"
          onCheckedChange={() => setStretch(!stretch)}
        />
        <label for="stretch">Stretch?</label>
      </Stack>
      <Tabs
        tabsData={[
          {
            value: "item1",
            label: "Item One",
            contentRenderer: () => "Item One",
          },
          {
            value: "item2",
            label: "Item Two",
            contentRenderer: () => "Item Two",
          },
          {
            value: "item3",
            label: "Item Three",
            contentRenderer: () => "Item Three",
          },
        ]}
        tabListAriaLabel="Tabs Displaying Clinical Options"
        tabAlignment={stretch ? "stretch" : null}
      />
    </DocsBox>
  );
};

Additional actions

<DocsBox css={{ background: "$neutral1", padding: "$lg", width: "100%" }}>
  <Tabs
    tabsData={[
      { value: "item1", label: "Item One", contentRenderer: () => "Item One" },
      { value: "item2", label: "Item Two", contentRenderer: () => "Item Two" },
    ]}
    tabListAriaLabel="Sample Tabs"
    additionalActions={
      <Stack direction="horizontal" spacing="sm">
        <Button>Wrap-Up</Button>
        <Button appearance="primary">Add</Button>
      </Stack>
    }
  />
</DocsBox>

Content Guidelines

Text

Tab labels should be short and to-the-point. They should describe the unique categorisation of the content compared to the other content. For instance, if one tab's content is focused on a patient's clinical record and another focused on their account details, use Clinical and Account.

Aim For
  • Use Title Case when writing tab content.
  • Use short, succinct tab labels.
  • Add a tooltip if extra detail needed.
Avoid
  • Tab labels breaking over two lines
  • Using phrases or sentences in tab labels.
<DocsBox css={{ background: "$neutral1", padding: "$lg", width: "100%" }}>
  <Tabs
    tabsData={[
      {
        value: "item1",
        label: "Clinical",
        contentRenderer: () => "All things related to clinical",
      },
      {
        value: "item2",
        label: "Account",
        contentRenderer: () => "Everything about a patient's account",
      },
      {
        value: "item4",
        label: (
          <Tooltip content="Use Tooltips to provide additional helper text.">
            <span>Diagnostic Reports</span>
          </Tooltip>
        ),
        contentRenderer: () => "Note the tooltip used in this tab.",
      },
      {
        value: "item3",
        label: "Don't make the tab label long.",
        disabled: true,
        contentRenderer: () => "Everything about a patient's account",
      },
    ]}
    tabListAriaLabel="Sample Tabs"
  />
</DocsBox>

Use of Tooltips

Although a Tab's text should be clear and concise, you can wrap the content in a Tooltip to provide useful information on hover.

<DocsBox css={{ background: "$neutral1", padding: "$lg", width: "100%" }}>
  <Tabs
    tabsData={[
      {
        value: "item1",
        label: (
          <Tooltip content="Use Tooltips to provide additional helper text.">
            <span>Diagnostic Reports</span>
          </Tooltip>
        ),
        contentRenderer: () => "Note the tooltip used in this tab.",
      },
      {
        value: "item2",
        label: (
          <Tooltip content="Use Tooltips to provide additional helper text.">
            <span>Incoming Correspondence</span>
          </Tooltip>
        ),
        contentRenderer: () => "All information about incoming correspondence.",
      },
    ]}
    tabListAriaLabel="Sample Tabs"
  />
</DocsBox>

Icon Only

() => {
  const tabsData = [
    {
      value: "item0",
      label: "All",
      contentRenderer: () => "Item One",
    },
    {
      value: "item1",
      label: <ConsultNote />,
      contentRenderer: () => "Item Two",
    },
    {
      value: "item2",
      label: <Letter />,
      contentRenderer: () => "Item Three",
    },
    {
      value: "item3",
      label: <DiagnosticReport />,
      contentRenderer: () => "Item Four",
    },
    {
      value: "item4",
      label: <Obstetrics />,
      contentRenderer: () => "Item Five",
    },
    {
      value: "item5",
      label: <Procedure />,
      contentRenderer: () => "Item Six",
    },
  ];
  return (
    <DocsBox css={{ flex: 1, backgroundColor: "$neutral1" }}>
      <Tabs tabListAriaLabel="Sample Tabs" tabsData={tabsData} />
    </DocsBox>
  );
};

Figma Library

Figma.logo

Props

additionalActions

Description

Pass any react component to the right side of the tabs list area. This component will also be contained by the underline of the tabs list area.

Type

ReactNode

defaultValue

Description

Option to pass in which tab should be displayed by default. Uses the value property of tabsData

Type

string

Default Value

tabsData[0].value

tabAlignment

Description

Option to stretch the tabs to fill their container or to use the initial, left alignment.

Type

"stretch" | "initial"

Default Value

"initial"

tabListAriaLabelRequired

Description

aria-label property which describes the tabs list element.

Type

string

tabsDataRequired

Description

Array of tabsData describing both the tabs and their content

Type

TabsData

© 2025