This component is used to switch among related views within the same context. It is composed of three elements: wm-tab-list, wm-tab-item and wm-tab-panel.

The tab component can control the display of tab panels, or this can be delegated to the app. If the app is controlling the display of tab panels, the tab id must be retrieved from the emitted wmTabSelected event.

Properties Examples Events Accessibility Notes

* Required property

** Required in certain cases

Properties of wm-tab-list

This determines whether the component will keep track of the interface's state and update the view accordingly. If the tabs are only changed by user interaction (not dynamically) and you're not doing anything special on tab change, you may set this to true. In that case the component takes care of its internal state and you do not need to listen for the wmTabSelected event. Defaults to false.
selected-tab **
The tabId of the tab item to display as selected. It is also the tabId of the tab panel whose content will be displayed. Required when the app is controlling the state of the widget and panel view. You may also use this prop in a controller-enabled tab interface to display a different tab item/tab panel on load other than the first one in the list.
Changes the horizontal padding around all children wm-tab-items. Accepts valid CSS values e.g. 24px.
Changes the component theme. Set to dark for dark theme, unset for default (light) theme. Use sparingly! Dark tabs are an older design and are being phased out.

Properties of wm-tab-item and wm-tab-panel

tab-id *
Required for every tab item. If you are using discrete tab panels to wrap content, each tab panel should also have a tabId matching the tabId of the corresponding tab item. If you are conditionally rendering content in one tab panel, give the tab panel the tabId of tab item that will be selected on load.

Usage in HTML

Edit the code below to see changes reflected in the example above.

Note: The second example demonstrates how the component can be used to dynamically change the content when a tab is selected (using the wmTabSelected event).

Javascript Sample

Example code for functionality.

Usage in Elm

Code generated from HTML.

Emitted when a tab item is selected. The event detail stores a reference to the tab id of the selected tab item, which corresponds to the tab id of a panel.

Screen Readers

The component sets the recommended aria-controls attributes for the tab items and the aria-labelledby attribute for the tab panels. When one tab panel is used to conditionally render content, the component updates these attributes when a new tab item is selected.

Keyboard Support

Key Function
Enter Space Activates the tab item and triggers a change in the view.
  • From outside the component, moves focus to the selected tab item.
  • From a tab item, moves focus to the first focusable element in the tab panel (if there is an interactive element in the panel).
Shift + Tab
  • From a tab item, moves focus out of the tab list to the previous focusable element on the page.
  • From the first focusable element in the tab panel, moves focus to the selected tab item if pressed.
Arrow Left
  • If a tab item is in focus, moves focus to the previous tab item.
  • If focus is on the first tab item, focus moves to the last tab item.
Arrow Right
  • If a tab item is in focus, moves focus to the next tab item.
  • If focus is on the last tab item, focus moves to the first tab item.
Arrow Down Focuses the tab panel. This is to ensure the content in the tab panel is more easily accessible to screen reader users. While in the tab widget, the screen reader is in focus mode, meaning the user is not able to browse using the arrow down key. If the tab panel contains no interactive elements, tabbing would move focus to the first interactive element outside the tab panel, meaning that users would lose their place and access to the tab content. If the component captures the arrow-down event and shifts focus to the tab panel outside the widget, it essentially gives control back to the screen reader, and users can more easily browse the content of the tabpanel.

Most of the time you will want to set the container's width to 100%. If the container's width is unset, it will change according to its content. Since the component in turn checks its parent to determine the available space and adjust its display, this is likely to produce undesirable behavior.

In a compound component like Select or Action Menu, child components are rendered in the parent's slot element, part of its shadow DOM tree. Slots essentially serve as a placeholder for markup that you the developer define in the light DOM tree, like <wm-menuitem>, <wm-option>, text content, or other child elements.

The browser distributes the child elements defined in the light DOM into the shadow DOM of the parent. The result is a flattened DOM tree—a merger of the the light DOM and the shadow DOM. This flattened tree is what you see in DevTools and what is rendered on the page.

With the standard implementation of the component, dynamically updating the child items will throw an error. Elm's efficient diffing of the DOM will register that only the child items have changed and try to update them, but the component has already been composed.

Rendering the component in a Keyed node and giving it a dynamic id will cause the entire component, rather than just the child items, to render anew, avoiding the error.