Honeycomb

tabs

Props

Prop nameTypeDefaultDescription
tabsReactElement<any, string | JSXElementConstructor<any>> | TabItemComp[]Required

Array of TabItem components. See TabItem

panelsReactElement<any, string | JSXElementConstructor<any>> | TabPanelComp[]Required

One or more TabPanel components. See TabPanel

navRestOmit<NavHorizontalProps, "children"> | Omit<ProgressTrackerProps, "children"> | undefined

Rest props forwarded to NavHorizontal component.

onTabActivated((tabId: string, event: SyntheticEvent<Element, Event>) => void) | undefined

Callback fired when a tab is activated.

ComponentFC<NavHorizontalProps> | FC<ProgressTrackerProps> | undefined

Component to be used for the tabs.

The Tabs controller provides an abstraction for the "tabbed" behavior for navigation components.

With the Component you can change the underlying nav component used to render the tabs. By default this component is the NavHorizontal, but since version 13.0 the Tabs controller also supports ProgressTracker.

You must provide the tabs and panels props with their correct ids.

The controller will then handle the following:

  • Add the correct role attributes to create a "tabs" component
  • Create a NavHorizontal or ProgressTracker component with the necessary modifiers and correct HTML elements
  • Connect all components by aria attributes and their respective ids
  • Manage focus and keyboard navigation
  • Create an internal state to manage the active tab and tab switching

The ...navRest props will be forwarded to nav component component, so you can still customize the appearance of it if you wish.

import { Tabs, TabItem, TabPanel, Box } from '@flixbus/honeycomb-react';
import { Icon, IconBusDouble } from '@flixbus/honeycomb-icons-react';

const tabs = (
  <>
    <TabItem id="upper-deck-tab-1" panelId="upper-deck-panel-1">
      Upper deck
    </TabItem>
    <TabItem id="lower-deck-tab-1" panelId="lower-deck-panel-1">
      Lower deck
    </TabItem>
  </>
);

const panels = (
  <>
    <TabPanel id="upper-deck-panel-1" tabId="upper-deck-tab-1">
      <Box extraClasses="hcr-space-2-top hcr-has-text-centered">
        <Icon InlineIcon={IconBusDouble} alt="double decker bus" />
        Upper deck
      </Box>
    </TabPanel>
    <TabPanel id="lower-deck-panel-1" tabId="lower-deck-tab-1">
      <Box extraClasses="hcr-space-2-top hcr-has-text-centered">
        <Icon InlineIcon={IconBusDouble} alt="double decker bus" />
        Lower deck
      </Box>
    </TabPanel>
  </>
);

<Tabs navRest={{ Elem: 'section', 'aria-label': 'Bus deck selection' }} tabs={tabs} panels={panels} />

ProgressTracker

import { Tabs, TabItem, TabPanel, ProgressTracker, Box, spaceHelpers, alignmentHelpers } from '@flixbus/honeycomb-react';

const { 4: space4 } = spaceHelpers();
const { textCentered } = alignmentHelpers();

const tabsData = [{
  id: 'get-honeycomb',
  tab: 'Get Honeycomb',
  panel: 'Get Honeycomb package',
}, {
  id: 'use-it',
  tab: 'Use it',
  panel: 'Use it in your project',
}, {
  id: 'enjoy',
  tab: 'Enjoy',
  panel: 'Enjoy it',
}, {
  id: 'spread-the-word',
  tab: 'Spread the word',
  panel: 'And spread the word',
}];

const tabs = [];
const panels = [];

tabsData.forEach(({ id, tab, panel }) => {
  const tabId = `${id}-tab`;
  const panelId = `${id}-panel`;

  tabs.push(
    <TabItem key={tabId} id={tabId} panelId={panelId}>
      {tab}
    </TabItem>
  );

  panels.push(
    <TabPanel key={panelId} id={panelId} tabId={tabId}>
      <Box extraClasses={textCentered}>
        {panel}
      </Box>
    </TabPanel>
  );
});

<Tabs Component={ProgressTracker} tabs={tabs} panels={panels} navRest={{ extraClasses: space4.bottom }} />

onTabActivated

By default the component will make the first item as the active one but you can chose which item is initially active by passing the active or current prop to the respective TabItem or TabItemProgress.

You can also use the handy onTabActivated prop to pass a callback that will be called with the activated tab id and the event that triggered it.

import { Tabs, TabItem, TabPanel, Box, Button } from '@flixbus/honeycomb-react';
import { Icon, IconBusDouble } from '@flixbus/honeycomb-icons-react';

const [active, setActive] = React.useState('lower-deck-tab-2');

const tabs = (
  <>
    <TabItem id="upper-deck-tab-2" panelId="upper-deck-panel-2" active={active === 'upper-deck-tab-2'}>
      Upper deck
    </TabItem>
    <TabItem id="lower-deck-tab-2" panelId="lower-deck-panel-2" active={active === 'lower-deck-tab-2'}>
      Lower deck
    </TabItem>
  </>
);

const panels = (
  <>
    <TabPanel id="upper-deck-panel-2" tabId="upper-deck-tab-2">
      <Box extraClasses="hcr-space-2-top hcr-has-text-centered">
        <Icon InlineIcon={IconBusDouble} alt="double decker bus" />
        Upper deck
      </Box>
    </TabPanel>
    <TabPanel id="lower-deck-panel-2" tabId="lower-deck-tab-2">
      <Box extraClasses="hcr-space-2-top hcr-has-text-centered">
        <Icon InlineIcon={IconBusDouble} alt="double decker bus" />
        Lower deck
      </Box>
    </TabPanel>
  </>
);

<>
  <Button onClick={() => setActive(active === 'upper-deck-tab-2' ? 'lower-deck-tab-2' : 'upper-deck-tab-2')}>External tab toggle</Button>
  <Tabs
    navRest={{ Elem: 'section', 'aria-label': 'Bus deck selection' }}
    onTabActivated={(tabId, event) => console.log(tabId, event)}
    tabs={tabs}
    panels={panels}
  />
</>