Skip to main content
react-md - Tabs - Demos


Tabs allow you to organize content across different screens, data sets, and other interactions. The @react-md/tabs package provides a bunch of components to help create accessible tabs, but here's a list of the most important components:

  • TabsManager - The main wrapper component for all the Tabs. You must provide a tabsId, a list of tab configuration, and optional settings for your tabs. You'll need to ensure that this component is a parent of all the next components.

  • Tabs - This component will render all the tabs from the TabsManager component ensuring correct keyboard accessibility and updating tabs to be active when needed.

  • TabPanels - This component is a wrapper for the TabPanel component that manages switching out the active TabPanel as needed and animating these panels in and out of view. It will also reset scrolling when the tab has changed. The children for this component must be the TabPanel component without any conditional rendering. This component will clone in the required id and aria-* props into the child TabPanel that is active.

  • TabPanel - The final component that creates an accessible tabpanel widget that links to a Tab within the Tabs component with the aria-labelledby attribute.

The Tabs component will also allow the user to navigate through tabs with the left and right arrow keys and optionally auto-select the tabs. Check out the demos below to see example usage and explanations for the TabPanels/TabPanel components.

Basic Usage

As stated above, you'll want to use the TabsManager, Tabs, TabPanels, and TabPanel components to render your general tab layout. For each tab within the tabs list, you'll need to have a matching TabPanel in the TabsPanel component.

Panel 1

Simple Two Page Tab

Even though you'll normally use the tab components together, you don't actually need to use them all within the same component. You can move the Tabs into a custom header with the AppBar or even move the content into separate components to render complex data. The only requirement still is that the TabPanels must only have children of TabPanel.

Check out the example below for separated components as well as adding icons to the tabs.

My pictures

Persistent Tabs

One of the downsides about the default behavior for tabs is that when a tab is not currently active, it will be removed from the DOM. This means that if your component fetches data or has local state, it will be reset once the tab becomes inactive. This means that if you want to maintain state between the tabs, you'll need to move the state up above the TabPanels component and pass it down to your panels instead.

Since this isn't always ideal, you can also enable the persistent flag which will always render all the tab panels and apply the hidden attribute for inactive tabs so they can't be tab focusable.

Tab 1 Content

Configurable Tabs

Unlike most of the components within react-md, tabs actually done have their own theme. This is really because tabs are generally rendered in AppBars or inline with other content on the page. If you want to apply your own theme, it's as simple as adding a background-color and optionally updating the indicator's background color of the primary theme color is not visible on the new background.

This example below will allow you to configure the tabs with a few different options as well as show how you can define your own custom theme and updating the indicator color with rmd-tabs-theme-update-var mixin.

Tabs Options
Icon Options
Tab Panel Options

Panel 1

Swipeable Tabs

Creating swipeable tabs are not build into the library at this point since swipe behavior is pretty opinionated and hard to add a reasonable default. That being said, you can use a library like react-swipeable along with the @react-md/tabs package to get your desired swipe behavior.

To add swiping, you'll want to control the activeIndex state for the TabsManager by providing an activeIndex prop and onActiveIndexChange callback prop. The onActiveIndexChange is required so that when a tab is clicked or keyboard navigated and clicked, the activeIndex will automatically be updated as expected.

From here, you'll want to update the TabPanels to be persisent so that you can apply a transform style to the active tab and the next tab that should become visible. While the user is swiping, you'll also want to enable the disableTransition prop so that once the swipe is completed, the tab updates immediately instead of possibly re-animating the entire swiped distance again.

Finally, you'll want to create a custom SwipeablePanel that accepts all the TabPanel props along with:

  • the swipe distance
  • the index of the panel
  • the current active index

When the user starts swiping, you'll manually add a style object to the current active panel along with the panel that is being swiped towards with a transform: translateX(${distance}) as well as removing the hidden prop for the panel.

Check out the example below that also works for "mouse swiping". The example code also has some comments about where things might need to be improved and other oddities.

Content 1