Fluxo UIFluxo UIv0.4.1

TabView

A flexible tab component with multiple style variants, positions, scrolling, icons, closable tabs, and extensive customization options.

Basic Usage

Basic TabView

Simple tab navigation with multiple panels

Dashboard

Welcome to the dashboard. Here you can see an overview of your data.

import { TabView, TabPage } from 'fluxo-ui';

function MyComponent() {
  const [activeIndex, setActiveIndex] = useState(0);

  return (
    <TabView activeIndex={activeIndex} onTabChange={(e) => setActiveIndex(e.index)}>
      <TabPage header="Dashboard">Dashboard content</TabPage>
      <TabPage header="Analytics">Analytics content</TabPage>
      <TabPage header="Settings">Settings content</TabPage>
    </TabView>
  );
}

Style Variants

Default

Standard underline indicator

Overview of your workspace and recent activity.

Pills

Rounded pill-shaped active indicator with filled background

Overview of your workspace and recent activity.

Enclosed

Browser-style tabs with bordered active panel

Overview of your workspace and recent activity.

Segment

iOS-style segmented control with subtle background

Overview of your workspace and recent activity.

Editor

VS Code / code editor style with top accent border

Overview of your workspace and recent activity.

Thick Border

Bold top border highlight for the active tab

Overview of your workspace and recent activity.

Elevated

Larger active tab with font size change and thick bottom border

Overview of your workspace and recent activity.

<TabView variant="pills">...</TabView>
<TabView variant="enclosed">...</TabView>
<TabView variant="segment">...</TabView>
<TabView variant="editor">...</TabView>
<TabView variant="thick-border">...</TabView>
<TabView variant="elevated">...</TabView>

Scrollable Tabs

Scrollable Tabs

Tab navigation with scroll arrows when tabs overflow

Home

Home page content goes here.

<TabView scrollable activeIndex={activeIndex} onTabChange={(e) => setActiveIndex(e.index)}>
  <TabPage header="Home">Home content</TabPage>
  <TabPage header="Products">Products content</TabPage>
  <TabPage header="Services">Services content</TabPage>
  <TabPage header="About">About content</TabPage>
  <TabPage header="Contact">Contact content</TabPage>
  <TabPage header="Support">Support content</TabPage>
  <TabPage header="Documentation">Docs content</TabPage>
</TabView>

Positions

Left Position

Tab headers positioned on the left side

Profile

Manage your profile information and preferences.

Right Position

Tab headers positioned on the right side

Profile

Manage your profile information and preferences.

Bottom Position

Tab headers at the bottom

Profile

Manage your profile information and preferences.

<TabView position="left">
  <TabPage header="Profile">Profile content</TabPage>
  <TabPage header="Account">Account content</TabPage>
  <TabPage header="Security">Security content</TabPage>
</TabView>

<TabView position="right">...</TabView>
<TabView position="bottom">...</TabView>

With Icons

Left Icons

SVG icons on the left side of tab headers

Welcome to the home page with a home icon.

Left & Right Icons

Icons on both sides of tab headers

User profile with both left and right icons.

With Disabled Tab

Tabs with icons and a disabled state

Active tab content.

<TabView>
  <TabPage header="Home" leftIcon={<HomeIcon />}>Home</TabPage>
  <TabPage header="Analytics" leftIcon={<ChartIcon />}>Analytics</TabPage>
  <TabPage header="Settings" leftIcon={<SettingsIcon />}>Settings</TabPage>
</TabView>
<TabView>
  <TabPage header="Profile" leftIcon={<UserIcon />} rightIcon={<BadgeIcon />}>
    Profile
  </TabPage>
  <TabPage header="Notifications" leftIcon={<BellIcon />} rightIcon={<BadgeIcon />}>
    Notifications
  </TabPage>
</TabView>

Closable Tabs

Closable Tabs

Tabs with close buttons for dynamic tab management

Content of index.tsx

<TabView
  activeIndex={activeIndex}
  onTabChange={(e) => setActiveIndex(e.index)}
  onTabClose={(e) => {
    setTabs(tabs.filter((_, i) => i !== e.index));
    if (e.index <= activeIndex) setActiveIndex(Math.max(0, activeIndex - 1));
  }}
>
  {tabs.map((tab) => (
    <TabPage key={tab} header={tab} closable>
      Content of {tab}
    </TabPage>
  ))}
</TabView>

Header End

Header End Content

Custom content in the tab header row's trailing space

Overview content with a trailing action button.

<TabView
  headerEnd={<button className="...">+ Add Tab</button>}
>
  <TabPage header="Tab 1">Content</TabPage>
  <TabPage header="Tab 2">Content</TabPage>
</TabView>

Event Handling

import { TabView, TabPage, TabChangeEvent, TabCloseEvent } from 'fluxo-ui';

function MyComponent() {
  const handleTabChange = (e: TabChangeEvent) => {
    console.log('Tab changed to index:', e.index);
  };

  const handleBeforeTabChange = (e: TabChangeEvent) => {
    if (e.index === 2) {
      alert('Cannot switch to this tab');
      return false;
    }
    return true;
  };

  const handleTabClose = (e: TabCloseEvent) => {
    console.log('Closing tab at index:', e.index);
  };

  return (
    <TabView
      onTabChange={handleTabChange}
      onBeforeTabChange={handleBeforeTabChange}
      onTabClose={handleTabClose}
    >
      <TabPage header="Allowed">Content 1</TabPage>
      <TabPage header="Allowed">Content 2</TabPage>
      <TabPage header="Restricted">Content 3</TabPage>
    </TabView>
  );
}

Import

import { TabView, TabPage } from 'fluxo-ui';
import type { TabChangeEvent, TabCloseEvent, TabViewVariant } from 'fluxo-ui';

TabView Props

activeIndex
number"0"

Index of the active tab

onTabChange
(e: TabChangeEvent) => void

Callback fired when tab changes

onBeforeTabChange
(e: TabChangeEvent) => boolean | Promise<boolean>

Callback before tab changes. Return false to prevent change.

onTabClose
(e: TabCloseEvent) => void

Callback when a closable tab is closed

headerEnd
React.ReactNode

Content rendered at the trailing end of the tab header row

variant
'default' | 'pills' | 'enclosed' | 'segment' | 'editor' | 'thick-border' | 'elevated'"'default'"

Visual style variant

scrollable
boolean"false"

Show scroll arrows when tabs overflow

position
'top' | 'bottom' | 'left' | 'right'"'top'"

Position of tab headers

activationMode
'auto' | 'manual'"'auto'"

How tabs activate via keyboard. 'auto' selects on arrow-key navigation; 'manual' moves focus only and requires Enter/Space to activate.

ariaLabel
string

Accessible name for the tablist (announced by screen readers when entering the tabs).

preMount
boolean"false"

Render all tab panels at once (hiding inactive ones) instead of mounting only the active panel.

className
string

Additional CSS class names

style
React.CSSProperties

Inline styles

children
React.ReactNode

TabPage components

TabPage Props

headerreq
React.ReactNode

Tab header content

leftIcon
string | React.ComponentType | React.ReactElement

Icon on the left side of the header

rightIcon
string | React.ComponentType | React.ReactElement

Icon on the right side of the header

closable
boolean"false"

Show a close button on the tab header

visible
boolean"true"

Whether the tab is visible

disabled
boolean"false"

Whether the tab is disabled

className
string

CSS class for tab content panel

style
React.CSSProperties

Inline styles for tab content panel

children
React.ReactNode

Tab panel content

Features

Style Variants

Seven visual styles: default, pills, enclosed, segment (iOS), editor (VS Code), thick-border, and elevated.

Flexible Positioning

Tab headers on top, bottom, left, or right to suit any layout.

Scrollable Tabs

Automatic scroll arrows when tabs overflow the available space.

Icon Support

Left and right icons on any tab header via strings, components, or elements.

Closable Tabs

Dynamic tab management with close buttons and onTabClose callback.

Before-Change Guard

Validate or cancel tab switches before they happen.

Keyboard Navigation

Arrow keys, Home/End for accessible tab switching.

Header End Slot

Place custom components at the trailing end of the tab header row.