Component Library
Browse and explore components
Tabs
Tabs are a UI component that organizes content into separate views, allowing users to switch between them.
Component Code
Copy Code
import { Tab, TabGroup, TabList, TabPanel, TabPanels } from '@headlessui/react'
const categories = [
{
name: 'Recent',
posts: [
{
id: 1,
title: 'Does drinking coffee make you smarter?',
date: '5h ago',
commentCount: 5,
shareCount: 2,
},
{
id: 2,
title: "So you've bought coffee... now what?",
date: '2h ago',
commentCount: 3,
shareCount: 2,
},
],
},
{
name: 'Popular',
posts: [
{
id: 1,
title: 'Is tech making coffee better or worse?',
date: 'Jan 7',
commentCount: 29,
shareCount: 16,
},
{
id: 2,
title: 'The most innovative things happening in coffee',
date: 'Mar 19',
commentCount: 24,
shareCount: 12,
},
],
},
{
name: 'Trending',
posts: [
{
id: 1,
title: 'Ask Me Anything: 10 answers to your questions about coffee',
date: '2d ago',
commentCount: 9,
shareCount: 5,
},
{
id: 2,
title: "The worst advice we've ever heard about coffee",
date: '4d ago',
commentCount: 1,
shareCount: 2,
},
],
},
]
const BasicTabsCode = () => {
return (
<div>
<div className='w-full'>
<TabGroup>
<TabList className='flex gap-3'>
{categories.map(({ name }) => (
<Tab
key={name}
className='rounded-full py-2 px-4 text-sm font-semibold text-ld focus:outline-none data-[selected]:bg-primary data-[hover]:text-foreground data-[selected]:text-white data-[hover]:bg-lightprimary dark:data-[hover]:bg-darkprimary data-[selected]:data-[hover]:bg-primary data-[focus]:outline-1 data-[focus]:outline-primary hover:cursor-pointer'>
{name}
</Tab>
))}
</TabList>
<TabPanels className='mt-3'>
{categories.map(({ name, posts }) => (
<TabPanel
key={name}
className='rounded-xl bg-muted p-3'>
<ul>
{posts.map((post) => (
<li
key={post.id}
className='relative rounded-md p-3 text-sm transition hover:bg-lightprimary'>
<a href='#' className='font-semibold text-ld '>
<span className='absolute inset-0' />
{post.title}
</a>
<ul className='flex gap-2' aria-hidden='true'>
<li>{post.date}</li>
<li aria-hidden='true'>·</li>
<li>{post.commentCount} comments</li>
<li aria-hidden='true'>·</li>
<li>{post.shareCount} shares</li>
</ul>
</li>
))}
</ul>
</TabPanel>
))}
</TabPanels>
</TabGroup>
</div>
</div>
)
}
export default BasicTabsCode
Component Code
Copy Code
import { Tab, TabGroup, TabList, TabPanel, TabPanels } from '@headlessui/react'
const categories = [
{
name: 'Recent',
posts: [
{
id: 1,
title: 'Does drinking coffee make you smarter?',
date: '5h ago',
commentCount: 5,
shareCount: 2,
},
{
id: 2,
title: "So you've bought coffee... now what?",
date: '2h ago',
commentCount: 3,
shareCount: 2,
},
],
},
{
name: 'Popular',
posts: [
{
id: 1,
title: 'Is tech making coffee better or worse?',
date: 'Jan 7',
commentCount: 29,
shareCount: 16,
},
{
id: 2,
title: 'The most innovative things happening in coffee',
date: 'Mar 19',
commentCount: 24,
shareCount: 12,
},
],
},
{
name: 'Trending',
posts: [
{
id: 1,
title: 'Ask Me Anything: 10 answers to your questions about coffee',
date: '2d ago',
commentCount: 9,
shareCount: 5,
},
{
id: 2,
title: "The worst advice we've ever heard about coffee",
date: '4d ago',
commentCount: 1,
shareCount: 2,
},
],
},
{
name: 'Extreme',
posts: [
{
id: 1,
title: 'Ask Me Anything: 10 answers to your questions about coffee',
date: '2d ago',
commentCount: 9,
shareCount: 5,
},
{
id: 2,
title: "The worst advice we've ever heard about coffee",
date: '4d ago',
commentCount: 1,
shareCount: 2,
},
],
},
]
const VerticalTabsCode = () => {
return (
<div>
<div className='w-full pb-5'>
<TabGroup vertical className='flex gap-3 '>
<TabList className='flex flex-col gap-3'>
{categories.map(({ name }) => (
<Tab
key={name}
className='rounded-full py-2 px-4 text-sm font-semibold text-ld focus:outline-none data-[selected]:bg-primary data-[hover]:text-foreground data-[selected]:text-white data-[hover]:bg-lightprimary dark:data-[hover]:bg-darkprimary data-[selected]:data-[hover]:bg-primary data-[focus]:outline-1 data-[focus]:outline-primary hover:cursor-pointer'>
{name}
</Tab>
))}
</TabList>
<TabPanels className='w-full'>
{categories.map(({ name, posts }) => (
<TabPanel
key={name}
className='rounded-xl bg-muted p-3'>
<ul>
{posts.map((post) => (
<li
key={post.id}
className='relative rounded-md p-3 text-sm transition hover:bg-lightprimary'>
<a href='#' className='font-semibold text-ld '>
<span className='absolute inset-0' />
{post.title}
</a>
<ul className='flex gap-2' aria-hidden='true'>
<li>{post.date}</li>
<li aria-hidden='true'>·</li>
<li>{post.commentCount} comments</li>
<li aria-hidden='true'>·</li>
<li>{post.shareCount} shares</li>
</ul>
</li>
))}
</ul>
</TabPanel>
))}
</TabPanels>
</TabGroup>
</div>
</div>
)
}
export default VerticalTabsCode
Disable Tab
One Lorem ipsum dolor sit amet, consectetur adipisici elit…’ (complete text) is dummy text that is not meant to mean anything. It is used as a placeholder in magazine layouts, for example, in order to give an impression of the finished document.
Component Code
Copy Code
import { Tab, TabGroup, TabList, TabPanel, TabPanels } from '@headlessui/react'
const DisableTabCode = () => {
return (
<div>
<TabGroup>
<TabList className='flex gap-3'>
<Tab className='rounded-full py-2 px-4 text-sm font-semibold text-ld focus:outline-none data-[selected]:bg-primary data-[hover]:text-foreground data-[selected]:text-white data-[hover]:bg-lightprimary dark:data-[hover]:bg-darkprimary data-[selected]:data-[hover]:bg-primary data-[focus]:outline-1 data-[focus]:outline-primary hover:cursor-pointer'>
Tab 1
</Tab>
<Tab
disabled
className='rounded-full py-2 px-4 text-sm font-semibold text-ld focus:outline-none data-[selected]:bg-primary data-[hover]:text-white data-[selected]:text-white data-[hover]:bg-primary data-[selected]:data-[hover]:bg-primary data-[focus]:outline-1 data-[focus]:outline-primary disabled:opacity-50'>
Tab 2
</Tab>
<Tab className='rounded-full py-2 px-4 text-sm font-semibold text-ld focus:outline-none data-[selected]:bg-primary data-[hover]:text-foreground data-[selected]:text-white data-[hover]:bg-lightprimary dark:data-[hover]:bg-darkprimary data-[selected]:data-[hover]:bg-primary data-[focus]:outline-1 data-[focus]:outline-primary hover:cursor-pointer'>
Tab 3
</Tab>
</TabList>
<TabPanels className='rounded-xl bg-muted p-3 mt-3'>
<TabPanel>
One Lorem ipsum dolor sit amet, consectetur adipisici elit…’
(complete text) is dummy text that is not meant to mean anything. It
is used as a placeholder in magazine layouts, for example, in order
to give an impression of the finished document.
</TabPanel>
<TabPanel>
Two Lorem ipsum dolor sit amet, consectetur adipisici elit…’
(complete text) is dummy text that is not meant to mean anything. It
is used as a placeholder in magazine layouts, for example, in order
to give an impression of the finished document.
</TabPanel>
<TabPanel>
Three Lorem ipsum dolor sit amet, consectetur adipisici elit…’
(complete text) is dummy text that is not meant to mean anything. It
is used as a placeholder in magazine layouts, for example, in order
to give an impression of the finished document.
</TabPanel>
</TabPanels>
</TabGroup>
</div>
)
}
export default DisableTabCode
Manually Active Tab
One Lorem ipsum dolor sit amet, consectetur adipisici elit…’ (complete text) is dummy text that is not meant to mean anything. It is used as a placeholder in magazine layouts, for example, in order to give an impression of the finished document.
Component Code
Copy Code
import { TabGroup, TabList, Tab, TabPanels, TabPanel } from '@headlessui/react'
const ManuallActiveTabCodes = () => {
return (
<div>
<TabGroup manual>
<TabList className='flex gap-3'>
<Tab className='rounded-full py-2 px-4 text-sm font-semibold text-ld focus:outline-none data-[selected]:bg-primary data-[hover]:text-foreground data-[selected]:text-white data-[hover]:bg-lightprimary dark:data-[hover]:bg-darkprimary data-[selected]:data-[hover]:bg-primary data-[focus]:outline-1 data-[focus]:outline-primary hover:cursor-pointer'>
Tab 1
</Tab>
<Tab className='rounded-full py-2 px-4 text-sm font-semibold text-ld focus:outline-none data-[selected]:bg-primary data-[hover]:text-foreground data-[selected]:text-white data-[hover]:bg-lightprimary dark:data-[hover]:bg-darkprimary data-[selected]:data-[hover]:bg-primary data-[focus]:outline-1 data-[focus]:outline-primary hover:cursor-pointer'>
Tab 2
</Tab>
<Tab className='rounded-full py-2 px-4 text-sm font-semibold text-ld focus:outline-none data-[selected]:bg-primary data-[hover]:text-foreground data-[selected]:text-white data-[hover]:bg-lightprimary dark:data-[hover]:bg-darkprimary data-[selected]:data-[hover]:bg-primary data-[focus]:outline-1 data-[focus]:outline-primary hover:cursor-pointer'>
Tab 3
</Tab>
</TabList>
<TabPanels className='rounded-xl bg-muted p-3 mt-3'>
<TabPanel>
One Lorem ipsum dolor sit amet, consectetur adipisici elit…’
(complete text) is dummy text that is not meant to mean anything. It
is used as a placeholder in magazine layouts, for example, in order
to give an impression of the finished document.
</TabPanel>
<TabPanel>
Two Lorem ipsum dolor sit amet, consectetur adipisici elit…’
(complete text) is dummy text that is not meant to mean anything. It
is used as a placeholder in magazine layouts, for example, in order
to give an impression of the finished document.
</TabPanel>
<TabPanel>
Three Lorem ipsum dolor sit amet, consectetur adipisici elit…’
(complete text) is dummy text that is not meant to mean anything. It
is used as a placeholder in magazine layouts, for example, in order
to give an impression of the finished document.
</TabPanel>
</TabPanels>
</TabGroup>
</div>
)
}
export default ManuallActiveTabCodes
Specifying The Default Tab
Two Lorem ipsum dolor sit amet, consectetur adipisici elit…’ (complete text) is dummy text that is not meant to mean anything. It is used as a placeholder in magazine layouts, for example, in order to give an impression of the finished document.
Component Code
Copy Code
import { TabGroup, TabList, Tab, TabPanels, TabPanel } from '@headlessui/react'
const SpecifiedDefaultCode = () => {
return (
<div>
<TabGroup defaultIndex={1}>
<TabList className='flex gap-3'>
<Tab className='rounded-full py-2 px-4 text-sm font-semibold text-ld focus:outline-none data-[selected]:bg-primary data-[hover]:text-foreground data-[selected]:text-white data-[hover]:bg-lightprimary dark:data-[hover]:bg-darkprimary data-[selected]:data-[hover]:bg-primary data-[focus]:outline-1 data-[focus]:outline-primary hover:cursor-pointer'>
Tab 1
</Tab>
<Tab className='rounded-full py-2 px-4 text-sm font-semibold text-ld focus:outline-none data-[selected]:bg-primary data-[hover]:text-foreground data-[selected]:text-white data-[hover]:bg-lightprimary dark:data-[hover]:bg-darkprimary data-[selected]:data-[hover]:bg-primary data-[focus]:outline-1 data-[focus]:outline-primary hover:cursor-pointer'>
Tab 2
</Tab>
<Tab className='rounded-full py-2 px-4 text-sm font-semibold text-ld focus:outline-none data-[selected]:bg-primary data-[hover]:text-foreground data-[selected]:text-white data-[hover]:bg-lightprimary dark:data-[hover]:bg-darkprimary data-[selected]:data-[hover]:bg-primary data-[focus]:outline-1 data-[focus]:outline-primary hover:cursor-pointer'>
Tab 3
</Tab>
</TabList>
<TabPanels className='rounded-xl bg-muted p-3 mt-3'>
<TabPanel>
One Lorem ipsum dolor sit amet, consectetur adipisici elit…’
(complete text) is dummy text that is not meant to mean anything. It
is used as a placeholder in magazine layouts, for example, in order
to give an impression of the finished document.
</TabPanel>
<TabPanel>
Two Lorem ipsum dolor sit amet, consectetur adipisici elit…’
(complete text) is dummy text that is not meant to mean anything. It
is used as a placeholder in magazine layouts, for example, in order
to give an impression of the finished document.
</TabPanel>
<TabPanel>
Three Lorem ipsum dolor sit amet, consectetur adipisici elit…’
(complete text) is dummy text that is not meant to mean anything. It
is used as a placeholder in magazine layouts, for example, in order
to give an impression of the finished document.
</TabPanel>
</TabPanels>
</TabGroup>
</div>
)
}
export default SpecifiedDefaultCode
Listening For Changes Tab
One Lorem ipsum dolor sit amet, consectetur adipisici elit…’ (complete text) is dummy text that is not meant to mean anything. It is used as a placeholder in magazine layouts, for example, in order to give an impression of the finished document.
Component Code
Copy Code
import { TabGroup, TabList, Tab, TabPanels, TabPanel } from '@headlessui/react'
const ListingTabChangeCode = () => {
return (
<div>
<TabGroup>
<TabList className='flex gap-3'>
<Tab className='rounded-full py-2 px-4 text-sm font-semibold text-ld focus:outline-none data-[selected]:bg-primary data-[hover]:text-foreground data-[selected]:text-white data-[hover]:bg-lightprimary dark:data-[hover]:bg-darkprimary data-[selected]:data-[hover]:bg-primary data-[focus]:outline-1 data-[focus]:outline-primary hover:cursor-pointer'>
Tab 1
</Tab>
<Tab className='rounded-full py-2 px-4 text-sm font-semibold text-ld focus:outline-none data-[selected]:bg-primary data-[hover]:text-foreground data-[selected]:text-white data-[hover]:bg-lightprimary dark:data-[hover]:bg-darkprimary data-[selected]:data-[hover]:bg-primary data-[focus]:outline-1 data-[focus]:outline-primary hover:cursor-pointer'>
Tab 2
</Tab>
<Tab className='rounded-full py-2 px-4 text-sm font-semibold text-ld focus:outline-none data-[selected]:bg-primary data-[hover]:text-foreground data-[selected]:text-white data-[hover]:bg-lightprimary dark:data-[hover]:bg-darkprimary data-[selected]:data-[hover]:bg-primary data-[focus]:outline-1 data-[focus]:outline-primary hover:cursor-pointer'>
Tab 3
</Tab>
</TabList>
<TabPanels className='rounded-xl bg-muted p-3 mt-3'>
<TabPanel>
One Lorem ipsum dolor sit amet, consectetur adipisici elit…’
(complete text) is dummy text that is not meant to mean anything. It
is used as a placeholder in magazine layouts, for example, in order
to give an impression of the finished document.
</TabPanel>
<TabPanel>
Two Lorem ipsum dolor sit amet, consectetur adipisici elit…’
(complete text) is dummy text that is not meant to mean anything. It
is used as a placeholder in magazine layouts, for example, in order
to give an impression of the finished document.
</TabPanel>
<TabPanel>
Three Lorem ipsum dolor sit amet, consectetur adipisici elit…’
(complete text) is dummy text that is not meant to mean anything. It
is used as a placeholder in magazine layouts, for example, in order
to give an impression of the finished document.
</TabPanel>
</TabPanels>
</TabGroup>
</div>
)
}
export default ListingTabChangeCode
Controlling Selected Tab
One Lorem ipsum dolor sit amet, consectetur adipisici elit…’ (complete text) is dummy text that is not meant to mean anything. It is used as a placeholder in magazine layouts, for example, in order to give an impression of the finished document.
Component Code
Copy Code
'use client'
import { useState } from 'react'
import { TabGroup, TabList, Tab, TabPanels, TabPanel } from '@headlessui/react'
const ControllTabSelectCode = () => {
const [selectedIndex, setSelectedIndex] = useState(0)
return (
<>
<TabGroup selectedIndex={selectedIndex} onChange={setSelectedIndex}>
<TabList className='flex gap-3'>
<Tab className='rounded-full py-2 px-4 text-sm font-semibold text-ld focus:outline-none data-[selected]:bg-primary data-[hover]:text-foreground data-[selected]:text-white data-[hover]:bg-lightprimary dark:data-[hover]:bg-darkprimary data-[selected]:data-[hover]:bg-primary data-[focus]:outline-1 data-[focus]:outline-primary hover:cursor-pointer'>
Tab 1
</Tab>
<Tab className='rounded-full py-2 px-4 text-sm font-semibold text-ld focus:outline-none data-[selected]:bg-primary data-[hover]:text-foreground data-[selected]:text-white data-[hover]:bg-lightprimary dark:data-[hover]:bg-darkprimary data-[selected]:data-[hover]:bg-primary data-[focus]:outline-1 data-[focus]:outline-primary hover:cursor-pointer'>
Tab 2
</Tab>
<Tab className='rounded-full py-2 px-4 text-sm font-semibold text-ld focus:outline-none data-[selected]:bg-primary data-[hover]:text-foreground data-[selected]:text-white data-[hover]:bg-lightprimary dark:data-[hover]:bg-darkprimary data-[selected]:data-[hover]:bg-primary data-[focus]:outline-1 data-[focus]:outline-primary hover:cursor-pointer'>
Tab 3
</Tab>
</TabList>
<TabPanels className='rounded-xl bg-muted p-3 mt-3'>
<TabPanel>
One Lorem ipsum dolor sit amet, consectetur adipisici elit…’
(complete text) is dummy text that is not meant to mean anything. It
is used as a placeholder in magazine layouts, for example, in order
to give an impression of the finished document.
</TabPanel>
<TabPanel>
Two Lorem ipsum dolor sit amet, consectetur adipisici elit…’
(complete text) is dummy text that is not meant to mean anything. It
is used as a placeholder in magazine layouts, for example, in order
to give an impression of the finished document.
</TabPanel>
<TabPanel>
Three Lorem ipsum dolor sit amet, consectetur adipisici elit…’
(complete text) is dummy text that is not meant to mean anything. It
is used as a placeholder in magazine layouts, for example, in order
to give an impression of the finished document.
</TabPanel>
</TabPanels>
</TabGroup>
</>
)
}
export default ControllTabSelectCode
Rendering As Different Elements
One Lorem ipsum dolor sit amet, consectetur adipisici elit…’ (complete text) is dummy text that is not meant to mean anything. It is used as a placeholder in magazine layouts, for example, in order to give an impression of the finished document.
Component Code
Copy Code
'use client'
import { Tab, TabGroup, TabList, TabPanel, TabPanels } from '@headlessui/react'
const RenderAsElementTabCode = () => {
return (
<>
<TabGroup manual>
<TabList className='flex gap-3' as='aside'>
<Tab className='rounded-full py-2 px-4 text-sm font-semibold text-ld focus:outline-none data-[selected]:bg-primary data-[hover]:text-foreground data-[selected]:text-white data-[hover]:bg-lightprimary dark:data-[hover]:bg-darkprimary data-[selected]:data-[hover]:bg-primary data-[focus]:outline-1 data-[focus]:outline-primary hover:cursor-pointer'>
Tab 1
</Tab>
<Tab className='rounded-full py-2 px-4 text-sm font-semibold text-ld focus:outline-none data-[selected]:bg-primary data-[hover]:text-foreground data-[selected]:text-white data-[hover]:bg-lightprimary dark:data-[hover]:bg-darkprimary data-[selected]:data-[hover]:bg-primary data-[focus]:outline-1 data-[focus]:outline-primary hover:cursor-pointer'>
Tab 2
</Tab>
<Tab className='rounded-full py-2 px-4 text-sm font-semibold text-ld focus:outline-none data-[selected]:bg-primary data-[hover]:text-foreground data-[selected]:text-white data-[hover]:bg-lightprimary dark:data-[hover]:bg-darkprimary data-[selected]:data-[hover]:bg-primary data-[focus]:outline-1 data-[focus]:outline-primary hover:cursor-pointer'>
Tab 3
</Tab>
</TabList>
<TabPanels
className='rounded-xl bg-muted p-3 mt-3'
as='section'>
<TabPanel>
One Lorem ipsum dolor sit amet, consectetur adipisici elit…’
(complete text) is dummy text that is not meant to mean anything. It
is used as a placeholder in magazine layouts, for example, in order
to give an impression of the finished document.
</TabPanel>
<TabPanel>
Two Lorem ipsum dolor sit amet, consectetur adipisici elit…’
(complete text) is dummy text that is not meant to mean anything. It
is used as a placeholder in magazine layouts, for example, in order
to give an impression of the finished document.
</TabPanel>
<TabPanel>
Three Lorem ipsum dolor sit amet, consectetur adipisici elit…’
(complete text) is dummy text that is not meant to mean anything. It
is used as a placeholder in magazine layouts, for example, in order
to give an impression of the finished document.
</TabPanel>
</TabPanels>
</TabGroup>
</>
)
}
export default RenderAsElementTabCode