Skip to content
Lenso UI

Tabs

Tabs organize content into multiple sections and allow users to navigate between them.

Usage

import { Tabs } from '@lenso/ui';
"use client";
import { Tabs } from "@lenso/ui";import * as stylex from "@stylexjs/stylex";
const styles = stylex.create({ root: { width: "100%", maxWidth: 448 }, panel: { paddingTop: 16 } });export function Basic() {  return (    <Tabs defaultValue="overview" xstyle={styles.root}>      <Tabs.ListContainer>        <Tabs.List activateOnFocus aria-label="Options">          <Tabs.Tab value="overview">Overview</Tabs.Tab>          <Tabs.Tab value="analytics">Analytics</Tabs.Tab>          <Tabs.Tab value="reports">Reports</Tabs.Tab>          <Tabs.Indicator />        </Tabs.List>      </Tabs.ListContainer>      <Tabs.Panel xstyle={styles.panel} value="overview">        <p>View your project overview and recent activity.</p>      </Tabs.Panel>      <Tabs.Panel xstyle={styles.panel} value="analytics">        <p>Track your metrics and analyze performance data.</p>      </Tabs.Panel>      <Tabs.Panel xstyle={styles.panel} value="reports">        <p>Generate and download detailed reports.</p>      </Tabs.Panel>    </Tabs>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

Anatomy

import { Tabs } from '@lenso/ui';
export default () => (  <Tabs>    <Tabs.ListContainer>      <Tabs.List aria-label="Options">        <Tabs.Tab>          <Tabs.Separator /> {/* Optional */}          <Tabs.Indicator />        </Tabs.Tab>      </Tabs.List>    </Tabs.ListContainer>    <Tabs.Panel/>  </Tabs>)

Examples

Vertical

"use client";export { Vertical } from "./source";

Local adaptation source above. Derived from HeroUI v3.2.6 source.

Overflow

When the tab list exceeds the available space, Tabs.ListContainer automatically renders scroll chevrons and fading edges so users can navigate the hidden tabs. This works the same way for both horizontal and vertical orientations.

"use client";export { Overflow } from "./source";

Local adaptation source above. Derived from HeroUI v3.2.6 source.

Disabled Tab

"use client";export { Disabled } from "./source";

Local adaptation source above. Derived from HeroUI v3.2.6 source.

With Separator

Add <Tabs.Separator /> inside each <Tabs.Tab> (except the first) to display separator lines between tabs.

"use client";export { WithSeparator } from "./source";

Local adaptation source above. Derived from HeroUI v3.2.6 source.

Secondary Variant

"use client";export { Secondary } from "./source";

Local adaptation source above. Derived from HeroUI v3.2.6 source.

Secondary Variant Vertical

"use client";export { SecondaryVertical } from "./source";

Local adaptation source above. Derived from HeroUI v3.2.6 source.

Alignment

Tab content is centered by default. Use align to align it to the start or end instead, which is especially useful for vertical, sidebar-style navigation. Individual tabs can still be overridden with className on Tabs.Tab.

"use client";export { VerticalAlignment } from "./source";

Local adaptation source above. Derived from HeroUI v3.2.6 source.

Render Function

"use client";// Adapted from HeroUI v3.2.6 (e385ac2), Apache-2.0. Native anchors supply real navigation.import { Tabs } from "@lenso/ui";import Link from "next/link";import { styles } from "./source.stylex";export function RenderFunction() {  return (    <Tabs      defaultValue="getting-started"      xstyle={styles.root}      render={(props) => <div {...props} data-custom="foo" />}    >      <Tabs.ListContainer>        <Tabs.List aria-label="Options">          <Tabs.Tab            value="getting-started"            nativeButton={false}            render={<Link href="/docs/react/getting-started" />}          >            Getting Started          </Tabs.Tab>          <Tabs.Tab            value="components"            nativeButton={false}            render={<Link href="/docs/react/components" />}          >            Components          </Tabs.Tab>          <Tabs.Tab            value="releases"            nativeButton={false}            render={<Link href="/docs/react/releases" />}          >            Releases          </Tabs.Tab>          <Tabs.Indicator />        </Tabs.List>      </Tabs.ListContainer>      <Tabs.Panel value="overview" xstyle={styles.panel}>        <p>View your project overview and recent activity.</p>      </Tabs.Panel>      <Tabs.Panel value="analytics" xstyle={styles.panel}>        <p>Track your metrics and analyze performance data.</p>      </Tabs.Panel>      <Tabs.Panel value="reports" xstyle={styles.panel}>        <p>Generate and download detailed reports.</p>      </Tabs.Panel>    </Tabs>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

Customization

Tailwind CSS

"use client";export { CustomStyles } from "./source";

Local adaptation source above. Derived from HeroUI v3.2.6 source.

Global CSS

To customize the Tabs component classes, you can use the @layer components directive. Learn more.

@layer components {  .tabs__list {    @apply rounded-xl border border-border bg-surface p-1;  }
  .tabs__tab {    @apply rounded-lg font-medium;  }
  .tabs__indicator {    @apply rounded-lg bg-foreground shadow-sm;  }
  .tabs--secondary > .tabs__list-container > .tabs__list {    @apply border-b border-border bg-transparent p-0;  }
  .tabs--secondary > .tabs__list-container .tabs__indicator {    @apply rounded-none bg-accent;  }}

Styling Reference

HeroUI follows the BEM methodology to ensure component variants and states are reusable and easy to customize.

CSS Classes

The Tabs component uses these CSS classes (View source styles):

Base Classes [!toc]

  • .tabs - Base tabs container
  • .tabs__list-container - Tab list container wrapper
  • .tabs__list-container__scroller - Scrollable wrapper around the tab list (handles overflow and fading edges)
  • .tabs__list-container__scroll-prev - Scroll chevron button for the previous (left / up) direction
  • .tabs__list-container__scroll-next - Scroll chevron button for the next (right / down) direction
  • .tabs__list - Tab list container
  • .tabs__tab - Individual tab button
  • .tabs__separator - Separator between tabs
  • .tabs__panel - Tab panel content
  • .tabs__indicator - Tab indicator

Orientation Attributes [!toc]

  • .tabs[data-orientation="horizontal"] - Horizontal tab layout (default)
  • .tabs[data-orientation="vertical"] - Vertical tab layout

Variant Classes [!toc]

  • .tabs--secondary - Secondary variant with underline indicator

Alignment Classes [!toc]

  • .tabs--align-start - Aligns tab content to the start
  • .tabs--align-end - Aligns tab content to the end

Interactive States

The component supports both CSS pseudo-classes and data attributes:

  • Selected: [aria-selected="true"]
  • Hover: :hover or [data-hovered="true"]
  • Focus: :focus-visible or [data-focus-visible="true"]
  • Disabled: [aria-disabled="true"]

API Reference

Tabs

PropTypeDefaultDescription
variant"primary" | "secondary""primary"Visual style variant. Primary uses a filled indicator, secondary uses an underline indicator
orientation"horizontal" | "vertical""horizontal"Tab layout orientation
align"start" | "center" | "end""center"Alignment of the content inside each tab
selectedKeystring-Controlled selected tab key
defaultSelectedKeystring-Default selected tab key
onSelectionChange(key: Key) => void-Selection change handler
classNamestring-Additional CSS classes
renderDOMRenderFunction<keyof React.JSX.IntrinsicElements, TabsRenderProps>-Overrides the default DOM element with a custom render function.

Tabs.List

PropTypeDefaultDescription
aria-labelstring-Accessibility label for tab list
classNamestring-Additional CSS classes
renderDOMRenderFunction<keyof React.JSX.IntrinsicElements, TabListRenderProps>-Overrides the default DOM element with a custom render function.

Tabs.Tab

PropTypeDefaultDescription
idstring-Unique tab identifier
isDisabledbooleanfalseWhether tab is disabled
classNamestring-Additional CSS classes
renderDOMRenderFunction<keyof React.JSX.IntrinsicElements, TabRenderProps>-Overrides the default DOM element with a custom render function.

Tabs.Separator

PropTypeDefaultDescription
classNamestring-Additional CSS classes

Tabs.Panel

PropTypeDefaultDescription
idstring-Panel identifier matching tab id
classNamestring-Additional CSS classes
renderDOMRenderFunction<keyof React.JSX.IntrinsicElements, TabPanelRenderProps>-Overrides the default DOM element with a custom render function.

See upstream Tabs showcases. Product showcases are not part of the local component runtime.