Skip to content

Tabs

⚠️ This documentation file needs to be reviewed ⚠️, but the component is ready to use.

Tabs separate related content into groups within a single context.

Basic Usage

To implement the Tabs component, you need to import it first:

import { Tabs, TabsItem } from '@react-ui-org/react-ui';

And use it:

React.createElement(() => {
  const [activeTab, setActiveTab] = React.useState(1);
  const navigate = (event, tab) => {
    setActiveTab(tab);
    event.preventDefault();
  };
  return (
    <div
      style={{
        paddingTop: 'var(--rui-dimension-space-3)',
        // background-base is overridden in previews, let's use light
        backgroundColor: 'var(--rui-color-background-light)'
      }}
    >
      <Tabs>
        <TabsItem
          href="#design"
          isActive={activeTab === 1}
          label="Design"
          onClick={(e) => navigate(e, 1)}
        />
        <TabsItem
          href="#code"
          isActive={activeTab === 2}
          label="Code"
          onClick={(e) => navigate(e, 2)}
        />
        <TabsItem
          href="#resources"
          isActive={activeTab === 3}
          label="Resources"
          onClick={(e) => navigate(e, 3)}
        />
      </Tabs>
    </div>
  );
})

See API for all available options.

General Guidelines

  • Tabs are designed for the default page background.

  • Use tabs to divide similar content. Tabs make sense when the content they contain is related.

  • Make sure everything necessary to complete a single task is contained within one tab. Users don't like switching context to get their task done.

  • Make labels short and clear. Long tab names impede comprehension. Use as few words as possible, preferably just one.

  • Limit the number of tabs. Having too many tabs increases clutter and can be overwhelming for users. Try to have no more than 5 or 6 tabs.

Tabs with Icons

Tab titles can be accompanied by icons. Once you decide to have icons, use one for each tab and don't leave some tabs without an icon.

React.createElement(() => {
  const [activeTab, setActiveTab] = React.useState(1);
  const navigate = (event, tab) => {
    setActiveTab(tab);
    event.preventDefault();
  };
  return (
    <div
      style={{
        paddingTop: 'var(--rui-dimension-space-3)',
        // background-base is overridden in previews, let's use light
        backgroundColor: 'var(--rui-color-background-light)'
      }}
    >
      <Tabs>
        <TabsItem
          beforeLabel={<Icon icon="pencil" />}
          href="#design"
          isActive={activeTab === 1}
          label="Design"
          onClick={(e) => navigate(e, 1)}
        />
        <TabsItem
          beforeLabel={<Icon icon="cogwheel" />}
          href="#code"
          isActive={activeTab === 2}
          label="Code"
          onClick={(e) => navigate(e, 2)}
        />
        <TabsItem
          beforeLabel={<Icon icon="globe" />}
          href="#resources"
          isActive={activeTab === 3}
          label="Resources"
          onClick={(e) => navigate(e, 3)}
        />
      </Tabs>
    </div>
  );
});

Scrollable Tabs

If you have more than a few tabs, you may need to make sure they will be all accessible no matter the space they have around. Wrap Tabs into ScrollView to make them scrollable if necessary.

React.createElement(() => {
  const [activeTab, setActiveTab] = React.useState(1);
  const navigate = (event, tab) => {
    setActiveTab(tab);
    event.preventDefault();
  };
  return (
    <div
      style={{
        width: '19rem',
        paddingTop: 'var(--rui-dimension-space-3)',
        // background-base is overridden in previews, let's use light
        backgroundColor: 'var(--rui-color-background-light)'
      }}
    >
      <ScrollView
        direction="horizontal"
        endShadowBackground="linear-gradient(
          var(--rui-local-end-shadow-direction),
          var(--rui-color-background-light),
          rgb(from var(--rui-color-background-light) r g b / 0))
        "
        startShadowBackground="linear-gradient(
          var(--rui-local-start-shadow-direction),
          var(--rui-color-background-light),
          rgb(from var(--rui-color-background-light) r g b / 0))
        "
      >
        <Tabs>
          <TabsItem
            href="#design"
            isActive={activeTab === 1}
            label="Design"
            onClick={(e) => navigate(e, 1)}
          />
          <TabsItem
            href="#code"
            isActive={activeTab === 2}
            label="Code"
            onClick={(e) => navigate(e, 2)}
          />
          <TabsItem
            href="#resources"
            isActive={activeTab === 3}
            label="Resources"
            onClick={(e) => navigate(e, 3)}
          />
          <TabsItem
            href="#other"
            isActive={activeTab === 4}
            label="Other"
            onClick={(e) => navigate(e, 4)}
          />
          <TabsItem
            href="#more"
            isActive={activeTab === 5}
            label="More"
            onClick={(e) => navigate(e, 5)}
          />
        </Tabs>
      </ScrollView>
    </div>
  );
})

Forwarding HTML Attributes

In addition to the options below in the component's API section, you can specify React synthetic events or any HTML attribute you like. All attributes that don't interfere with the API are forwarded to the <nav> HTML element in case of Tabs component and to the <a> HTML element in case of TabsItem. This enables making the component interactive and helps to improve its accessibility.

👉 Refer to the MDN reference for the full list of supported attributes of the nav and li element.

API

TabsItem

Theming

Tabs Theming

Custom Property Description
--rui-Tabs__border-bottom-width Width of decorative bottom border
--rui-Tabs__border-bottom-color Color of decorative bottom border
--rui-Tabs__gap--xs Gap between individual tab items on smallest screens
--rui-Tabs__gap--sm Gap between individual tab items from sm breakpoint up
--rui-Tabs__gap--md Gap between individual tab items from md breakpoint up
--rui-Tabs__padding-x Horizontal padding

TabsItem Theming

Custom Property Description
--rui-Tabs__item__padding--xs Padding of tab items on smallest screens
--rui-Tabs__item__padding--sm Padding of tab items from sm breakpoint up
--rui-Tabs__item__padding--md Padding of tab items from md breakpoint up
--rui-Tabs__item__font-weight Label font weight
--rui-Tabs__item__color Label color
--rui-Tabs__item__border-width Border width, allows specifying for individual sides
--rui-Tabs__item__border-color Border color, allows specifying for individual sides
--rui-Tabs__item__border-radius Top corners radius
--rui-Tabs__item__background-color Background color
--rui-Tabs__item__box-shadow Box shadow
--rui-Tabs__item__icon__gap Gap between label and accompanying elements, e.g. icons

Theming TabsItem Hover and Active States

Most of TabsItem options can be adjusted for hover and active states as follows:

--rui-Tabs__item--<STATE>__<PROPERTY>

Where:

  • <STATE> is one of hover or active,
  • <PROPERTY> is one of font-weight, color, border-width, border-color, background-color, box-shadow, shift-y (shifts vertically the whole item), or label__shift-y (tweaks vertical position of tab label).