Tabs

Tabs is a component that displays a list of tabs and allows the user to select one.

Usage#

import { Tabs } from 'primereact/tabs';
<Tabs>
    <Tabs.List>
        <Tabs.Tab value="tab1">Tab 1</Tabs.Tab>
    </Tabs.List>
    <Tabs.Panels>
        <Tabs.Panel value="tab1">Tab 1 Content</Tabs.Panel>
    </Tabs.Panels>
</Tabs>

Examples#

Basic#

Update your personal information such as name, email address, and profile picture.

import { Tabs } from 'primereact/tabs';
 
export default function BasicDemo() {
    return (
        <div className="card">
            <Tabs value="tab1">
                <Tabs.List>
                    <Tabs.Tab value="tab1">Account Info</Tabs.Tab>
                    <Tabs.Tab value="tab2">Payment</Tabs.Tab>
                    <Tabs.Tab value="tab3">Preferences</Tabs.Tab>
                    <Tabs.Indicator />
                </Tabs.List>
                <Tabs.Panels>
                    <Tabs.Panel value="tab1">
                        <p>Update your personal information such as name, email address, and profile picture.</p>
                    </Tabs.Panel>
                    <Tabs.Panel value="tab2">
                        <p>Manage your subscription plan, view invoices, and update your payment method.</p>
                    </Tabs.Panel>
                    <Tabs.Panel value="tab3">
                        <p>Customize how the application looks and behaves to match your personal preferences.</p>
                    </Tabs.Panel>
                </Tabs.Panels>
            </Tabs>
        </div>
    );
}

Dynamic#

Update your personal information such as name, email address, and profile picture.

import { Tabs } from 'primereact/tabs';
 
const tabs = [
    { id: 'tab1', title: 'Account Info', content: 'Update your personal information such as name, email address, and profile picture.' },
    { id: 'tab2', title: 'Payment', content: 'Manage your subscription plan, view invoices, and update your payment method.' },
    { id: 'tab3', title: 'Preferences', content: 'Customize how the application looks and behaves to match your personal preferences.' }
];
 
export default function DynamicDemo() {
    return (
        <div className="card">
            <Tabs value="tab1">
                <Tabs.List>
                    {tabs.map((tab) => (
                        <Tabs.Tab key={tab.id} value={tab.id}>
                            {tab.title}
                        </Tabs.Tab>
                    ))}
                    <Tabs.Indicator />
                </Tabs.List>
                <Tabs.Panels>
                    {tabs.map((tab) => (
                        <Tabs.Panel key={tab.id} value={tab.id}>
                            <p>{tab.content}</p>
                        </Tabs.Panel>
                    ))}
                </Tabs.Panels>
            </Tabs>
        </div>
    );
}

Controlled#

Update your personal information such as name, email address, and profile picture.

import { Button } from 'primereact/button';
import { Tabs } from 'primereact/tabs';
import * as React from 'react';
 
const tabs = [
    { id: 'tab1', title: 'Account Info', content: 'Update your personal information such as name, email address, and profile picture.' },
    { id: 'tab2', title: 'Payment', content: 'Manage your subscription plan, view invoices, and update your payment method.' },
    { id: 'tab3', title: 'Preferences', content: 'Customize how the application looks and behaves to match your personal preferences.' }
];
 
export default function ControlledDemo() {
    const [activeTab, setActiveTab] = React.useState('tab1');
 
    return (
        <div className="card space-y-4">
            <Button onClick={() => setActiveTab('tab2')}>Go to Payment</Button>
            <Tabs value={activeTab} onValueChange={(e: any) => setActiveTab(e.value)}>
                <Tabs.List>
                    {tabs.map((tab) => (
                        <Tabs.Tab key={tab.id} value={tab.id}>
                            {tab.title}
                        </Tabs.Tab>
                    ))}
                    <Tabs.Indicator />
                </Tabs.List>
                <Tabs.Panels>
                    {tabs.map((tab) => (
                        <Tabs.Panel key={tab.id} value={tab.id}>
                            <p>{tab.content}</p>
                        </Tabs.Panel>
                    ))}
                </Tabs.Panels>
            </Tabs>
        </div>
    );
}

Scrollable#

Tab 1 Content
import { Tabs } from 'primereact/tabs';
 
const scrollableTabs = Array.from({ length: 50 }, (_, i) => ({ title: `Tab ${i + 1}`, content: `Tab ${i + 1} Content`, value: `${i}` }));
 
export default function ScrollableDemo() {
    return (
        <div className="card">
            <Tabs value="0" scrollable>
                <Tabs.List>
                    {scrollableTabs.map((tab) => (
                        <Tabs.Tab key={tab.value} value={tab.value}>
                            {tab.title}
                        </Tabs.Tab>
                    ))}
                    <Tabs.Indicator />
                </Tabs.List>
                <Tabs.Panels>
                    {scrollableTabs.map((tab) => (
                        <Tabs.Panel key={tab.value} value={tab.value}>
                            {tab.content}
                        </Tabs.Panel>
                    ))}
                </Tabs.Panels>
            </Tabs>
        </div>
    );
}

Disabled#

Update your personal information such as name, email address, and profile picture.

import { Tabs } from 'primereact/tabs';
 
export default function DisabledDemo() {
    return (
        <div className="card">
            <Tabs value="tab1">
                <Tabs.List>
                    <Tabs.Tab value="tab1">Account Info</Tabs.Tab>
                    <Tabs.Tab value="tab2" disabled>
                        Payment
                    </Tabs.Tab>
                    <Tabs.Tab value="tab3">Preferences</Tabs.Tab>
                    <Tabs.Indicator />
                </Tabs.List>
                <Tabs.Panels>
                    <Tabs.Panel value="tab1">
                        <p>Update your personal information such as name, email address, and profile picture.</p>
                    </Tabs.Panel>
                    <Tabs.Panel value="tab2">
                        <p>Manage your subscription plan, view invoices, and update your payment method.</p>
                    </Tabs.Panel>
                    <Tabs.Panel value="tab3">
                        <p>Customize how the application looks and behaves to match your personal preferences.</p>
                    </Tabs.Panel>
                </Tabs.Panels>
            </Tabs>
        </div>
    );
}

Custom Indicator#

Update your personal information such as name, email address, and profile picture.

import { Tabs } from 'primereact/tabs';
 
const tabs = [
    { id: 'tab1', title: 'Account Info', content: 'Update your personal information such as name, email address, and profile picture.' },
    { id: 'tab2', title: 'Payment', content: 'Manage your subscription plan, view invoices, and update your payment method.' },
    { id: 'tab3', title: 'Preferences', content: 'Customize how the application looks and behaves to match your personal preferences.' }
];
 
export default function CustomIndicatorDemo() {
    return (
        <div className="card">
            <Tabs value="tab1">
                <Tabs.List>
                    {tabs.map((tab) => (
                        <Tabs.Tab key={tab.id} value={tab.id} className="border-none z-10">
                            {tab.title}
                        </Tabs.Tab>
                    ))}
                    <Tabs.Indicator className="w-[var(--width)] h-[calc(var(--height)-12px)] bottom-none top-1/2 -translate-y-1/2 bg-surface-100 dark:bg-surface-800 rounded-md" />
                </Tabs.List>
                <Tabs.Panels>
                    {tabs.map((tab) => (
                        <Tabs.Panel key={tab.id} value={tab.id}>
                            <p>{tab.content}</p>
                        </Tabs.Panel>
                    ))}
                </Tabs.Panels>
            </Tabs>
        </div>
    );
}

Template#

Update your personal information such as name, email address, and profile picture.

import { Badge } from 'primereact/badge';
import { Button } from 'primereact/button';
import { InputText } from 'primereact/inputtext';
import { Label } from 'primereact/label';
import { Switch } from 'primereact/switch';
import { Tabs } from 'primereact/tabs';
import { useState } from 'react';
 
const tabs = [
    { id: 'tab1', title: 'Account Info', icon: 'pi pi-user', content: 'Update your personal information such as name, email address, and profile picture.' },
    { id: 'tab2', title: 'Payment', icon: 'pi pi-credit-card', badge: 'New', content: 'Manage your subscription plan, view invoices, and update your payment method.' },
    { id: 'tab3', title: 'Preferences', icon: 'pi pi-cog', content: 'Customize how the application looks and behaves to match your personal preferences.' }
];
 
export default function TemplateDemo() {
    const [preferences, setPreferences] = useState({
        darkMode: false,
        emailNotifications: false,
        desktopNotifications: false
    });
 
    return (
        <div className="card">
            <Tabs value="tab1" className="max-w-md mx-auto">
                <Tabs.List>
                    {tabs.map((tab) => (
                        <Tabs.Tab key={tab.id} value={tab.id} className="flex items-center gap-2">
                            <i className={tab.icon}></i>
                            {tab.title}
                            {tab.badge && <Badge size="small">{tab.badge}</Badge>}
                        </Tabs.Tab>
                    ))}
                    <Tabs.Indicator />
                </Tabs.List>
                <Tabs.Panels>
                    <Tabs.Panel value="tab1">
                        <div>
                            <p className="mt-2 mb-8 text-surface-500">Update your personal information such as name, email address, and profile picture.</p>
                            <form>
                                <div className="space-y-4">
                                    <div className="flex flex-col gap-1">
                                        <Label htmlFor="username">Username</Label>
                                        <InputText id="username" placeholder="john.doe" />
                                    </div>
                                    <div className="flex flex-col gap-1">
                                        <Label htmlFor="email">Email</Label>
                                        <InputText id="email" placeholder="[email protected]" />
                                    </div>
                                </div>
                                <Button className="mt-8 w-fit">Save Changes</Button>
                            </form>
                        </div>
                    </Tabs.Panel>
                    <Tabs.Panel value="tab2">
                        <div>
                            <p className="mt-2 mb-8 text-surface-500">Manage your subscription plan, view invoices, and update your payment method.</p>
                            <form>
                                <div className="space-y-4">
                                    <div className="flex flex-col gap-1">
                                        <Label htmlFor="cardName">Cardholder Name</Label>
                                        <InputText id="cardName" placeholder="John Doe" />
                                    </div>
                                    <div className="flex flex-col gap-1">
                                        <Label htmlFor="cardNumber">Card Number</Label>
                                        <InputText id="cardNumber" placeholder="0000 0000 0000 0000" />
                                    </div>
                                    <div className="flex flex-col gap-1">
                                        <Label htmlFor="expiryDate">Expiry Date</Label>
                                        <InputText id="expiryDate" placeholder="MM/YY" />
                                    </div>
                                </div>
                                <Button className="mt-8 w-fit">Update Payment</Button>
                            </form>
                        </div>
                    </Tabs.Panel>
                    <Tabs.Panel value="tab3">
                        <div>
                            <p className="mt-2 mb-8 text-surface-500">Customize how the application looks and behaves to match your personal preferences.</p>
                            <form>
                                <div className="space-y-4">
                                    <div className="flex items-center justify-between">
                                        <Label htmlFor="darkMode">Dark Mode</Label>
                                        <Switch inputId="darkMode">
                                            <Switch.Control>
                                                <Switch.Thumb />
                                            </Switch.Control>
                                        </Switch>
                                    </div>
                                    <div className="flex items-center justify-between">
                                        <Label htmlFor="emailNotifications">Email Notifications</Label>
                                        <Switch inputId="emailNotifications" defaultChecked>
                                            <Switch.Control>
                                                <Switch.Thumb />
                                            </Switch.Control>
                                        </Switch>
                                    </div>
                                    <div className="flex items-center justify-between">
                                        <Label htmlFor="desktopNotifications">Desktop Notifications</Label>
                                        <Switch inputId="desktopNotifications">
                                            <Switch.Control>
                                                <Switch.Thumb />
                                            </Switch.Control>
                                        </Switch>
                                    </div>
                                </div>
                                <Button className="w-fit mt-8 ml-auto mr-0">Save Preferences</Button>
                            </form>
                        </div>
                    </Tabs.Panel>
                </Tabs.Panels>
            </Tabs>
        </div>
    );
}

Accessibility#

Screen Reader#

The tabs container in TabList is defined with the tablist role, as any attribute is passed to the container element aria-labelledby can be optionally used to specify an element to describe the Tabs. Each Tab has a tab role along with aria-selected state attribute and aria-controls to refer to the corresponding TabPanel. TabPanel has tabpanel role, an id to match the aria-controls of Tab and aria-labelledby reference to Tab as the accessible name.

Tab Keyboard Support#

KeyFunction
tabMoves focus through the header.
enterActivates the focused tab header.
spaceActivates the focused tab header.
right arrowMoves focus to the next header. If focus is on the last header, moves focus to the first header.
left arrowMoves focus to the previous header. If focus is on the first header, moves focus to the last header.
homeMoves focus to the last header.
endMoves focus to the first header.
pageUpMoves scroll position to first header.
pageDownMoves scroll position to last header.