On this page Tabs Tabs

The m3e-tabs component provides a structured navigation surface for organizing content into distinct views, where only one view is visible at a time.

Installation
npm i @m3e/tabs
Usage

This section outlines usage examples and configuration guidance for the components in this package.

Basic usage

Use m3e-tabs, m3e-tab, and m3e-tab-panel to construct tabbed views. Both m3e-tab and m3e-tab-panel must be direct children of m3e-tabs. To associate a tab with its corresponding panel, set the for attribute on m3e-tab to match the ID of the target m3e-tab-panel.

To select a tab, apply the selected attribute to a single m3e-tab. When a tab is activated, a cancellable input event is emitted followed by a change event. To cancel selection change, call preventDefault during input.Only one tab may be selected at a time.

A tab's label is specified by its content. You can use the icon slot to render an icon before a tab's label.

Video Photos Audio Videos Photos Audio
<m3e-tabs>
  <m3e-tab selected for="videos">
    <m3e-icon slot="icon" name="videocam"></m3e-icon>Video
  </m3e-tab>
  <m3e-tab for="photos">
    <m3e-icon slot="icon" name="photo"></m3e-icon>Photos
  </m3e-tab>
  <m3e-tab for="audio">
    <m3e-icon slot="icon" name="music_note"></m3e-icon>Audio
  </m3e-tab>
  <m3e-tab-panel id="videos">Videos</m3e-tab-panel>
  <m3e-tab-panel id="photos">Photos</m3e-tab-panel>
  <m3e-tab-panel id="audio">Audio</m3e-tab-panel>
</m3e-tabs>
Variants

Tabs come in the appearance variants: primary and secondary (default). Use the variant attribute of m3e-tabs to change the appearance.

Video Photos Audio Videos Photos Audio
<m3e-tabs variant="primary">
  <!-- Content omitted for brevity -->
</m3e-tabs>
Stretching

Use the stretch attribute to stretch tabs to fill the header.

Video Photos Audio Videos Photos Audio
<m3e-tabs stretch>
  <!-- Content omitted for brevity -->
</m3e-tabs>
Header positions

A tab's header can be positioned before (default) or after panels. Use the header-position attribute to change the header position.

Video Photos Audio Videos Photos Audio
<m3e-tabs header-position="after">
  <!-- Content omitted for brevity -->
</m3e-tabs>
Disabling

Use the disabled attribute to disable individual tabs.

Video Photos Audio Videos Photos Audio
<m3e-tabs>
  <m3e-tab selected for="videos">
    <m3e-icon slot="icon" name="videocam"></m3e-icon>Video
  </m3e-tab>
  <m3e-tab disabled for="photos">
    <m3e-icon slot="icon" name="photo"></m3e-icon>Photos
  </m3e-tab>
  <!-- Additional content omitted for brevity -->
</m3e-tabs>
Pagination

By default, directional pagination controls appear when the number of tabs exceeds the available horizontal space. You can disable this using the disable-pagination attribute.

The following example demonstrates pagination behavior when tabs overflow. To observe it in action, reduce your screen width until directional controls appear.

Tab 1 Tab 2 Tab 3 Tab 4 Tab 5 Tab 6 Tab 7 Tab 8 Tab 9 Tab 10 Tab 11 Tab 12 Tab 13 Tab 14 Tab 15 Tab 16 Tab 17 Tab 18 Tab 19 Tab 20

Accessibility

Tabs implement the ARIA Tabs design pattern and are composed of the tablist, tab, and tabpanel roles. The pattern includes support for keyboard navigation, focus management, and accessible relationships between tabs and their associated panels.

The m3e-tabs component hosts an internal tablist nested within the pagination controls. It contains each m3e-tab, which is assigned the ARIA role="tab". Corresponding m3e-tab-panel elements are given the ARIA role="tabpanel". Each tab is linked to its associated panel using aria-controls, and the aria-selected attribute communicates the selected state of a tab to assistive technologies. When a tab is disabled, aria-disabled="true" communicates its inactive state.

Pagination buttons are intentionally excluded from the tab order and strong focus indicators are not supported. This reduces focus noise and streamlines keyboard navigation.

Use the previous-page-label and next-page-label attributes to provide accessible labels to pagination buttons.

Native module support

This package uses JavaScript Modules. To use it directly in a browser without a bundler, use a module script similar to the following.

<script type="module" src="/node_modules/@m3e/tabs/dist/index.js"></script>

You also need a module script for @m3e/icon-button and m3e/slide-group due to these being a dependency.

<script type="module" src="/node_modules/@m3e/icon-button/dist/index.js"></script>
<script type="module" src="/node_modules/@m3e/slide-group/dist/index.js"></script>

In addition, you must use an import map to include additional dependencies.

<script type="importmap">
  {
    "imports": {
      "lit": "https://cdn.jsdelivr.net/npm/lit@3.3.0/+esm",
      "@m3e/core": "/node_modules/@m3e/core/dist/index.js",
      "@m3e/core/a11y": "/node_modules/@m3e/core/dist/a11y.js"
    }
  }
</script>

For production, use index.min.js and a11y.min.js for faster load times.

API

This package includes a Custom Elements Manifest (custom-elements.json), which documents the properties, attributes, slots, events and CSS custom properties of each component.

You can explore the API below, or integrate the manifest into your own tooling.