NUIv3.0.7

Tabs

A composable, accessible Tabs component for modern React applications.

tsx
import { Tabs } from '@nofinite/nui';

Interactive Preview

Loading preview...

A composable, accessible tabs component implementing Dual-Mode Architecture, controlled and uncontrolled state, roving tabindex keyboard navigation, and ARIA-linked triggers and panels.

NUI lets you choose between Plug and Play (PnP) mode for rapid data-driven tab rendering, or Composable Compound Primitives for full layout customization.


Usage

1. Plug and Play (PnP) Mode — Zero Boilerplate

Pass an array of tab definitions directly via the data prop. NUI automatically constructs the tab bar, keyboard navigation, and panel visibility without manual subcomponent declarations:

tsx
import { Tabs } from '@nofinite/nui';

export function QuickTabs() {
  const tabs = [
    { value: 'account', label: 'Account', content: <div className="p-4">Account settings and profile details.</div> },
    { value: 'password', label: 'Password', content: <div className="p-4">Update your password and security keys.</div> },
    { value: 'billing', label: 'Billing', content: <div className="p-4">Invoices, payment methods, and plans.</div> },
  ];

  return <Tabs data={tabs} defaultValue="account" />;
}

2. Composable Compound Mode — Full Structural Control

When you need custom layouts, right-aligned toolbar buttons, or customized trigger styles, assemble the compound primitives directly:

tsx
import { Tabs } from '@nofinite/nui';

export function CustomTabs() {
  return (
    <Tabs defaultValue="account">
      <Tabs.List>
        <Tabs.Trigger value="account">Account</Tabs.Trigger>
        <Tabs.Trigger value="password">Password</Tabs.Trigger>
        <Tabs.Trigger value="billing">Billing</Tabs.Trigger>
      </Tabs.List>

      <Tabs.Content value="account">Account content</Tabs.Content>
      <Tabs.Content value="password">Password content</Tabs.Content>
      <Tabs.Content value="billing">Billing content</Tabs.Content>
    </Tabs>
  );
}

Controlled State

tsx
import { useState } from 'react';
import { Tabs } from '@nofinite/nui';

export function ControlledTabs() {
  const [activeTab, setActiveTab] = useState('account');

  return (
    <Tabs value={activeTab} onChange={setActiveTab}>
      <Tabs.List>
        <Tabs.Trigger value="account">Account</Tabs.Trigger>
        <Tabs.Trigger value="billing">Billing</Tabs.Trigger>
      </Tabs.List>

      <Tabs.Content value="account">Current: {activeTab}</Tabs.Content>
      <Tabs.Content value="billing">Current: {activeTab}</Tabs.Content>
    </Tabs>
  );
}

Props Reference

Tabs (Root)

PropTypeDefaultDescription
dataTabDataItem[]Plug and Play Mode: Array of tab items { value, label, content }.
defaultValuestringThe initial active tab value (uncontrolled).
valuestringControlled active tab value.
onChange(val: string) => voidCallback fired when the active tab changes.
childrenReactNodeCompound primitives (used in compound mode).

Tabs.Trigger

PropTypeDefaultDescription
valuestringrequiredUnique identifier matching corresponding Tabs.Content.
disabledbooleanfalseIf true, disables tab and skips in keyboard sequence.
childrenReactNodeTab label or icon content.

Tabs.Content

PropTypeDefaultDescription
valuestringrequiredUnique identifier matching corresponding Tabs.Trigger.
childrenReactNodePanel content rendered when active.

Subcomponents

  • Tabs.List
  • Tabs.Trigger
  • Tabs.Content

Accessibility

  • Roving Tabindex: Arrow keys cycle through tabs; only the active tab has tabIndex={0}.
  • WAI-ARIA Attributes: role="tablist", role="tab", and role="tabpanel" are automatically configured with aria-controls and aria-labelledby.
  • Keyboard Navigation: ArrowLeft / ArrowRight seamlessly move between tabs.

API Reference

PropTypeDefaultDescription
valuestringControlled state value representing the active tab
defaultValuestringUncontrolled initial value
onChange((value: string) => void)Callback fired when the active tab changes
dataTabDataItem[]Data array for Smart Mode mapping