Skip to main content
TabNavigation (Deprecated)
@coinbase/cds-web@8.30.1
Organizes content across different screens or data sets.
This component is deprecated. Please use the Tabs component instead.
Import
import { TabNavigation } from '@coinbase/cds-web/tabs/TabNavigation'
SourceView source codeStorybookView StorybookFigmaView Figma (internal only)
Related components
View as Markdown

Basic Example

Loading...
Live Code
function TabNavigationExample() {
  // TAB MOCK DATA
  const tabs = useMemo(() => [
    { id: 'first_primary_tab', label: 'Tab one' },
    { id: 'second_primary_tab', label: 'Tab two' },
    { id: 'third_primary_tab', label: 'Tab three' },
    { id: 'fourth_primary_tab', label: 'Tab four' },
    { id: 'fifth_primary_tab', label: 'Tab five' },
  ]);
  const secondaryTabs = useMemo(() => [
    { id: 'first_secondary_tab', label: 'Tab one' },
    { id: 'second_secondary_tab', label: 'Tab two' },
  ]);

  const [primary, setPrimary] = useState();
  const [secondary, setSecondary] = useState();

  return (
    <VStack gap={2}>
      <TabNavigation value={primary} tabs={tabs} onChange={setPrimary} />
      <TabNavigation
        variant="secondary"
        value={secondary}
        tabs={secondaryTabs}
        onChange={setSecondary}
      />
    </VStack>
  );
}

Accessibility

Screen reader

Screen reader will read all tab labels in the group regardless if some are behind the overflow menu. Ensure that the nextArrowAccessibilityLabel and previousArrowAccessibilityLabel props are set if the tab list has overflow content

Keyboarding

Once a tab button is focused, other tabs can be selected by using the arrow keys, following the w3.org Tabs Design Pattern. Tabs are focus trapped, so pressing RightArrow on the last element will cycle back to the first element.

Tab:
  • When focus moves into the tab list, places focus on the active tab element.
  • When the tab list contains the focus, moves focus to the next element in the page tab sequence outside the tablist, which is the tabpanel unless the first element containing meaningful content inside the tabpanel is focusable.
When focus is on a tab element :
  • Left Arrow: moves focus to the previous tab. If focus is on the first tab, this action moves focus to the last tab. Optionally, activates the newly focused tab (See note below).
  • Right Arrow: Moves focus to the next tab. If focus is on the last tab element, this action moves focus to the first tab. Optionally, activates the newly focused tab (See note below).
  • Space or Enter: Activates the tab.
Loading...
Live Code
function TabNavigationExample() {
  // TAB MOCK DATA
  const tabs = useMemo(() => [
    { id: 'first_primary_tab', label: 'Tab one' },
    { id: 'second_primary_tab', label: 'Tab two' },
    { id: 'third_primary_tab', label: 'Tab three' },
  ]);

  const [primary, setPrimary] = useState(tabs[0].id);

  // This should be kept out of the fn
  const MockTabPanel = ({ id, children }) => {
    /** This is a naive and simple approach to
     *  illustrate the proper a11y configuration
     *  Ideally you'll be using some nice animations
     **/
    const display = useMemo(() => (primary !== id ? 'none' : undefined), [primary, id]);

    return (
      <VStack
        /**
         * ACCESSIBILITY PROPS
         * These three props are required to create a truly accessible
         * tab system, and must be named in the following format
         * */
        role="tabpanel"
        id={`tabpanel--${id}`}
        accessibilityLabelledBy={`tab--${id}`}
        // Make sure you're properly showing/hiding this tabpanel
        display={display}
        // Style as you wish
        padding={2}
        gap={1}
        bordered
        borderRadius={400}
        background="bgPrimaryWash"
      >
        {children}
      </VStack>
    );
  };

  // This should be kept out of the fn
  const MockTabPanels = ({ activeId }) => {
    const tabDisplay = useMemo(
      () => ({
        one: activeId !== tabs[0].id ? 'none' : 'block',
        two: activeId !== tabs[1].id ? 'none' : 'block',
        three: activeId !== tabs[2].id ? 'none' : 'block',
      }),
      [activeId, tabs],
    );

    return (
      <>
        <MockTabPanel id={tabs[0].id}>
          <Text as="h2" font="title1" paddingBottom={2}>
            Let's tab!
          </Text>
          <Text as="p" font="body">
            Press the tab key until the <b>Tab one</b> tab is focused.
          </Text>
          <Text as="p" font="body">
            Now try using the right arrow key to move through the tab list.
          </Text>
          <Text as="p" font="body">
            Pretty neat, hey? Okay, what happens if you press the right arrow key when you're at the
            end of the list?
          </Text>
          <Text as="p" font="body">
            <Link to="https://www.w3.org/WAI/ARIA/apg/example-index/tabs/tabs-manual.html">
              This link
            </Link>{' '}
            in the body of the tab is here to provide another thing to focus on.
          </Text>
        </MockTabPanel>
        <MockTabPanel id={tabs[1].id}>
          <Text as="h2" font="title1" paddingBottom={2}>
            You made it to tab two!
          </Text>
          <Text as="p" font="body">
            You're a natural 🕺
          </Text>
          <Text as="p" font="body">
            Can you make it to tab three?
          </Text>
        </MockTabPanel>
        <MockTabPanel id={tabs[2].id}>
          <Text as="h2" font="title1" paddingBottom={2}>
            Heyooo, tab three!
          </Text>
          <Text as="p" font="body">
            Now if you really want to have some fun, turn on a screen reader like{' '}
            <Link href="https://www.apple.com/voiceover/info/guide/_1121.html">VoiceOver</Link> and
            see how it sounds!
          </Text>
        </MockTabPanel>
      </>
    );
  };

  return (
    <VStack gap={2}>
      <Text as="h2" font="title1" id="tab-label">
        Tab navigation example
      </Text>
      <TabNavigation
        value={primary}
        tabs={tabs}
        onChange={setPrimary}
        accessibilityLabelledBy="tab-label"
      />
      <MockTabPanels activeId={primary} />
    </VStack>
  );
}

Is this page useful?

Coinbase Design is an open-source, adaptable system of guidelines, components, and tools that aid the best practices of user interface design for crypto products.