Tabs Component

The Tabs component is a flexible, fully responsive UI primitive built with TypeScript. It supports multiple layouts, visual variants, keyboard navigation, and mobile-aware behaviors — making it ideal for dashboards, settings panels, and structured content navigation.

Use variant and position to control layout and styling, mobileVariant for responsive behavior, and TabList + TabPanels for structured composition. Customize appearance with semantic theme classes, CSS variables, className, and layout props like radius.

Import Component From Library

javascript
1import { Tabs, Tab, TabList, TabPanels, TabPanel } from "@neuctra/ui";

Basic Usage Code

Start with a simple tab system. The component provides flexible tab navigation with multiple layouts and responsive behavior.

jsx
1import { Tabs, TabList, Tab, TabPanels, TabPanel } from '@neuctra/ui';
2
3function BasicExample() {
4  return (
5    <Tabs>
6      <TabList>
7        <Tab index={0}>Overview</Tab>
8        <Tab index={1}>Settings</Tab>
9        <Tab index={2}>Profile</Tab>
10      </TabList>
11      <TabPanels>
12        <TabPanel index={0}>
13          <div className="p-6">Overview content</div>
14        </TabPanel>
15        <TabPanel index={1}>
16          <div className="p-6">Settings content</div>
17        </TabPanel>
18        <TabPanel index={2}>
19          <div className="p-6">Profile content</div>
20        </TabPanel>
21      </TabPanels>
22    </Tabs>
23  );
24}

Basic Usage

Overview content

Tabs Props

PropTypeDefaultDescription
childrenReactNode—TabList and TabPanels composition
defaultActivenumber0Initial active tab index
position"top" | "bottom" | "left" | "right""top"Tabs layout position
variant"solid" | "outline" | "underline" | "pill""solid"Visual style of tabs
fullWidthbooleanfalseMakes tabs stretch full width
radiusnumber8Border radius of tabs
transitionDurationnumber200Animation duration in ms
borderedbooleanfalseAdds outer border wrapper
tabCountnumberautoManually define tab count
mobileBreakpointnumber768Breakpoint for mobile behavior
mobileVariant"drawer" | "scroll" | "stack" | "collapse""scroll"Mobile layout behavior
primaryColorstring"var(--primary)"Context color token for custom tab extensions
activeColorstring"var(--foreground)"Context color token for custom tab extensions
textColorstring""Context color token for custom tab extensions
hoverColorstring"var(--primary)"Context color token for custom tab extensions
borderColorstring"var(--border)"Context color token for custom tab extensions
disabledColorstring"var(--muted-foreground)"Context color token for custom tab extensions
backgroundColorstring—Root container background color (falls back to var(--background))
onTabChange (index: number) => void—Triggered when tab changes
classNamestring—Root wrapper class
styleReact.CSSProperties—Root inline styles
javascript
1<TabList gap={8} drawerLabel="Select tab" />

TabList Props

PropTypeDefaultDescription
gapnumber8Spacing between tabs
drawerLabelReactNode"Select tab"Label shown in mobile drawer trigger
drawerIconReactNode—Accepted for a custom drawer chevron icon, but not yet rendered (the built-in chevron is always used)
classNamestring—Wrapper class styling
styleReact.CSSProperties—Inline styles for TabList
triggerClassNamestring—Styles the drawer trigger button (mobileVariant="drawer" only)
menuClassNamestring—Styles the dropdown menu panel (mobileVariant="drawer" only)
javascript
1<Tab icon={<Icon />} disabled={false}>Tab 1</Tab>

Tab Props

PropTypeDefaultDescription
childrenReactNode—Tab label content
iconReactNode—Optional icon
disabledbooleanfalseDisable tab interaction
ariaLabelstring—Accessibility label
indexnumberautoManual tab index override
classNamestring—Tab button styling
iconClassNamestring—Styles the wrapper around the icon node
styleReact.CSSProperties—Accepted by the type, but not currently applied by the component
activeStyleReact.CSSProperties—Accepted by the type, but not currently applied by the component
inactiveStyleReact.CSSProperties—Accepted by the type, but not currently applied by the component
javascript
1<TabPanels>
2  <TabPanel index={0}>Content</TabPanel>
3</TabPanels>

TabPanels Props

PropTypeDefaultDescription
childrenReactNode—Wrapper for multiple TabPanel components
classNamestring—Custom class for panels container
styleReact.CSSProperties—Inline styles for panels wrapper
javascript
1<TabPanel index={0} keepMounted>
2  Content
3</TabPanel>

TabPanel Props

PropTypeDefaultDescription
childrenReactNode—Panel content
indexnumber—Tab index it belongs to
keepMountedbooleanfalseKeep in DOM when inactive
classNamestring—Panel wrapper class
styleReact.CSSProperties—Inline styles

Common Mistakes

<TabPanel>Content</TabPanel>

Each TabPanel must have a matching index

<TabList><Tab /> x3</TabList> + <TabPanel /> x2

Number of Tabs and TabPanels should match

<Tab index={5} />

Avoid manually setting index unless necessary — auto indexing is handled internally

<TabPanel outside <Tabs> />

All components must be inside <Tabs> provider

<Tab disabled /> + expecting click

Disabled tabs do not trigger setActive

<Tabs><TabList /><TabPanels /></Tabs>

Always follow the correct structure hierarchy

Pro Tips

  • Use variant="underline" for clean navigation-style tabs, and pill for dashboards.
  • Combine position="left" with fullWidth for sidebar layouts.
  • Use mobileVariant="drawer" for better UX on small screens.
  • Prefer keepMounted when tab content has expensive re-renders.
  • Use onTabChange to sync tabs with routing or state (e.g. query params).
  • Add icon in <Tab> for better visual scanning.
  • Use fullWidth for equal tab sizing in forms or mobile layouts.
  • Customize with CSS variables (--primary, --accent) instead of inline styles.
  • Avoid heavy content inside tabs unless using keepMounted.
  • Keyboard navigation is built-in — ensure focus styles are visible for accessibility.

Frequently Asked Questions

How do I install and import the Tabs component?

Install the @neuctra/ui package, then import it with: import { Tabs } from "@neuctra/ui";

What variants and sizes does Tabs support?

Tabs supports variants: solid, outline, underline, pill. Use the variant and size props to switch between them, or pass a className to layer on custom Tailwind CSS classes.

Is the Tabs component accessible?

Tabs is built with semantic HTML and standard ARIA attributes, and supports keyboard navigation and focus states out of the box, so it works well with screen readers and keyboard-only users.

Built with React, Tailwind CSS & TypeScript.