Tabs
HeroUISections of content, one shown at a time, chosen from a list of tabs.
Solidtype_heroui.Tabs is Kobalte’s tabs with the classes HeroUI’s own
tabsVariants gives: a list of tabs, and a panel for each, shown while its
tab, of the same id, is selected. The arrows of its orientation move
between the tabs, round from the last to the first, and Home and End to
either end, skipping a disabled tab; focus selects the tab it reaches, or
Enter and Space do with keyboard_activation=`manual.
The selected tab’s indicator slides from the tab selected before, as HeroUI’s
styles animate it. A tab and its panel are named by their id, which each
takes; HeroUI’s take one too, without which a panel has no tab.
HeroUI’s examples.
module Tabs = Solidtype_heroui.Tabs
let make () = <Tabs class_="w-full max-w-md"> <Tabs.List_container> <Tabs.List aria_label="Options"> <Tabs.Tab id="overview">"Overview" <Tabs.Indicator /></Tabs.Tab> <Tabs.Tab id="analytics">"Analytics" <Tabs.Indicator /></Tabs.Tab> <Tabs.Tab id="reports">"Reports" <Tabs.Indicator /></Tabs.Tab> </Tabs.List> </Tabs.List_container> <Tabs.Panel class_="pt-4" id="overview"> <p>"View your project overview and recent activity."</p> </Tabs.Panel> <Tabs.Panel class_="pt-4" id="analytics"> <p>"Track your metrics and analyze performance data."</p> </Tabs.Panel> <Tabs.Panel class_="pt-4" id="reports"> <p>"Generate and download detailed reports."</p> </Tabs.Panel> </Tabs>Anatomy
Section titled “Anatomy”<Tabs> <Tabs.List_container> <Tabs.List aria_label="Options"> <Tabs.Tab id="..."> <Tabs.Separator /> (* optional *) <Tabs.Indicator /> </Tabs.Tab> </Tabs.List> </Tabs.List_container> <Tabs.Panel id="..." /></Tabs>Examples
Section titled “Examples”Vertical
Section titled “Vertical”module Tabs = Solidtype_heroui.Tabs
let make () = <Tabs class_="w-full max-w-lg" orientation=`vertical> <Tabs.List_container> <Tabs.List aria_label="Vertical tabs"> <Tabs.Tab id="account">"Account" <Tabs.Indicator /></Tabs.Tab> <Tabs.Tab id="security">"Security" <Tabs.Indicator /></Tabs.Tab> <Tabs.Tab id="notifications"> "Notifications" <Tabs.Indicator /> </Tabs.Tab> <Tabs.Tab id="billing">"Billing" <Tabs.Indicator /></Tabs.Tab> </Tabs.List> </Tabs.List_container> <Tabs.Panel class_="px-4" id="account"> <h3 class_="mb-2 font-semibold">"Account Settings"</h3> <p class_="text-sm text-muted"> "Manage your account information and preferences." </p> </Tabs.Panel> <Tabs.Panel class_="px-4" id="security"> <h3 class_="mb-2 font-semibold">"Security Settings"</h3> <p class_="text-sm text-muted"> "Configure two-factor authentication and password settings." </p> </Tabs.Panel> <Tabs.Panel class_="px-4" id="notifications"> <h3 class_="mb-2 font-semibold">"Notification Preferences"</h3> <p class_="text-sm text-muted"> "Choose how and when you want to receive notifications." </p> </Tabs.Panel> <Tabs.Panel class_="px-4" id="billing"> <h3 class_="mb-2 font-semibold">"Billing Information"</h3> <p class_="text-sm text-muted"> "View and manage your subscription and payment methods." </p> </Tabs.Panel> </Tabs>Overflow
Section titled “Overflow”When the tabs are more than their container holds, Tabs.List_container
scrolls them, fades the edge they are hidden past, and shows a chevron at that
end which scrolls on by most of a view, in either orientation.
module Tabs = Solidtype_heroui.Tabs
let items = [| ("overview", "Overview"); ("analytics", "Analytics"); ("reports", "Reports"); ("performance", "Performance"); ("engagement", "Engagement"); ("audience", "Audience"); ("acquisition", "Acquisition"); ("retention", "Retention"); ("settings", "Settings"); |]
let make () = <div class_="w-[400px]"> <Tabs> <Tabs.List_container> <Tabs.List aria_label="Overflow options"> <Solidtype.For each=(fun () -> items)> (fun (id, label) _ -> <Tabs.Tab id=(fun () -> id)> (fun () -> Solidtype.Jsx.string label) <Tabs.Indicator /> </Tabs.Tab>) </Solidtype.For> </Tabs.List> </Tabs.List_container> <Solidtype.For each=(fun () -> items)> (fun (id, label) _ -> <Tabs.Panel class_="pt-4" id=(fun () -> id)> <p>(fun () -> Solidtype.Jsx.string (label ^ " panel content."))</p> </Tabs.Panel>) </Solidtype.For> </Tabs> </div>Disabled Tab
Section titled “Disabled Tab”A tab is disabled while it or the tabs are; the arrows pass over it.
module Tabs = Solidtype_heroui.Tabs
let make () = <Tabs class_="w-full max-w-md"> <Tabs.List_container> <Tabs.List aria_label="Tabs with disabled"> <Tabs.Tab id="active">"Active" <Tabs.Indicator /></Tabs.Tab> <Tabs.Tab is_disabled=true id="disabled"> "Disabled" <Tabs.Indicator /> </Tabs.Tab> <Tabs.Tab id="available">"Available" <Tabs.Indicator /></Tabs.Tab> </Tabs.List> </Tabs.List_container> <Tabs.Panel class_="pt-4" id="active"> <p>"This tab is active and can be selected."</p> </Tabs.Panel> <Tabs.Panel class_="pt-4" id="disabled"> <p>"This content cannot be accessed."</p> </Tabs.Panel> <Tabs.Panel class_="pt-4" id="available"> <p>"This tab is also available for selection."</p> </Tabs.Panel> </Tabs>With Separator
Section titled “With Separator”Tabs.Separator inside each tab but the first draws a line between tabs,
hidden beside the selected one.
module Tabs = Solidtype_heroui.Tabs
let make () = <Tabs class_="w-full max-w-md"> <Tabs.List_container> <Tabs.List aria_label="Options"> <Tabs.Tab id="overview">"Overview" <Tabs.Indicator /></Tabs.Tab> <Tabs.Tab id="analytics"> <Tabs.Separator /> "Analytics" <Tabs.Indicator /> </Tabs.Tab> <Tabs.Tab id="reports"> <Tabs.Separator /> "Reports" <Tabs.Indicator /> </Tabs.Tab> </Tabs.List> </Tabs.List_container> <Tabs.Panel class_="pt-4" id="overview"> <p>"View your project overview and recent activity."</p> </Tabs.Panel> <Tabs.Panel class_="pt-4" id="analytics"> <p>"Track your metrics and analyze performance data."</p> </Tabs.Panel> <Tabs.Panel class_="pt-4" id="reports"> <p>"Generate and download detailed reports."</p> </Tabs.Panel> </Tabs>Secondary Variant
Section titled “Secondary Variant”module Tabs = Solidtype_heroui.Tabs
let make () = <Tabs class_="w-full max-w-md" variant=`secondary> <Tabs.List_container> <Tabs.List aria_label="Options"> <Tabs.Tab id="overview">"Overview" <Tabs.Indicator /></Tabs.Tab> <Tabs.Tab id="analytics">"Analytics" <Tabs.Indicator /></Tabs.Tab> <Tabs.Tab id="reports">"Reports" <Tabs.Indicator /></Tabs.Tab> </Tabs.List> </Tabs.List_container> <Tabs.Panel class_="pt-4" id="overview"> <p>"View your project overview and recent activity."</p> </Tabs.Panel> <Tabs.Panel class_="pt-4" id="analytics"> <p>"Track your metrics and analyze performance data."</p> </Tabs.Panel> <Tabs.Panel class_="pt-4" id="reports"> <p>"Generate and download detailed reports."</p> </Tabs.Panel> </Tabs>Secondary Variant Vertical
Section titled “Secondary Variant Vertical”module Tabs = Solidtype_heroui.Tabs
let make () = <Tabs class_="w-full max-w-lg" orientation=`vertical variant=`secondary> <Tabs.List_container> <Tabs.List aria_label="Vertical tabs"> <Tabs.Tab id="account">"Account" <Tabs.Indicator /></Tabs.Tab> <Tabs.Tab id="security">"Security" <Tabs.Indicator /></Tabs.Tab> <Tabs.Tab id="notifications"> "Notifications" <Tabs.Indicator /> </Tabs.Tab> <Tabs.Tab id="billing">"Billing" <Tabs.Indicator /></Tabs.Tab> </Tabs.List> </Tabs.List_container> <Tabs.Panel class_="px-4" id="account"> <h3 class_="mb-2 font-semibold">"Account Settings"</h3> <p class_="text-sm text-muted"> "Manage your account information and preferences." </p> </Tabs.Panel> <Tabs.Panel class_="px-4" id="security"> <h3 class_="mb-2 font-semibold">"Security Settings"</h3> <p class_="text-sm text-muted"> "Configure two-factor authentication and password settings." </p> </Tabs.Panel> <Tabs.Panel class_="px-4" id="notifications"> <h3 class_="mb-2 font-semibold">"Notification Preferences"</h3> <p class_="text-sm text-muted"> "Choose how and when you want to receive notifications." </p> </Tabs.Panel> <Tabs.Panel class_="px-4" id="billing"> <h3 class_="mb-2 font-semibold">"Billing Information"</h3> <p class_="text-sm text-muted"> "View and manage your subscription and payment methods." </p> </Tabs.Panel> </Tabs>Alignment
Section titled “Alignment”A tab’s content is centred, or set to the start or the end by align.
module Tabs = Solidtype_heroui.Tabs
let make () = <Tabs align=`start class_="w-full max-w-lg" orientation=`vertical variant=`secondary> <Tabs.List_container> <Tabs.List aria_label="Settings"> <Tabs.Tab id="general">"General" <Tabs.Indicator /></Tabs.Tab> <Tabs.Tab id="billing"> "Subscription & Billing" <Tabs.Indicator /> </Tabs.Tab> <Tabs.Tab id="appearance">"Appearance" <Tabs.Indicator /></Tabs.Tab> <Tabs.Tab id="notifications"> "Notifications" <Tabs.Indicator /> </Tabs.Tab> <Tabs.Tab id="privacy">"Privacy" <Tabs.Indicator /></Tabs.Tab> </Tabs.List> </Tabs.List_container> <Tabs.Panel class_="px-4" id="general"> <h3 class_="mb-2 font-semibold">"General"</h3> <p class_="text-sm text-muted"> "Manage your account information and preferences." </p> </Tabs.Panel> <Tabs.Panel class_="px-4" id="billing"> <h3 class_="mb-2 font-semibold">"Subscription & Billing"</h3> <p class_="text-sm text-muted"> "View and manage your plan and payment methods." </p> </Tabs.Panel> <Tabs.Panel class_="px-4" id="appearance"> <h3 class_="mb-2 font-semibold">"Appearance"</h3> <p class_="text-sm text-muted"> "Choose a theme and adjust the interface density." </p> </Tabs.Panel> <Tabs.Panel class_="px-4" id="notifications"> <h3 class_="mb-2 font-semibold">"Notifications"</h3> <p class_="text-sm text-muted"> "Choose how and when you want to receive notifications." </p> </Tabs.Panel> <Tabs.Panel class_="px-4" id="privacy"> <h3 class_="mb-2 font-semibold">"Privacy"</h3> <p class_="text-sm text-muted"> "Control what you share and who can see your activity." </p> </Tabs.Panel> </Tabs>Customization
Section titled “Customization”Tailwind CSS
Section titled “Tailwind CSS”class_ is added after HeroUI’s classes, on every part.
module Tabs = Solidtype_heroui.Tabs
let list_class = String.concat " " [ "rounded-xl border border-accent/10 bg-accent-soft/30 p-1"; "**:data-[slot=tabs-tab]:rounded-lg"; "**:data-[slot=tabs-tab]:bg-transparent"; "**:data-[slot=tabs-tab]:text-muted"; "**:data-[slot=tabs-tab]:opacity-100"; "**:data-[slot=tabs-tab]:transition-colors"; "**:data-[slot=tabs-tab]:data-[hovered=true]:not-data-[selected=true]:bg-accent-soft"; "**:data-[slot=tabs-tab]:data-[hovered=true]:not-data-[selected=true]:text-accent-soft-foreground"; "**:data-[slot=tabs-tab]:data-[pressed=true]:not-data-[selected=true]:bg-accent-soft-hover"; "**:data-[slot=tabs-tab]:data-[focus-visible=true]:ring-2"; "**:data-[slot=tabs-tab]:data-[focus-visible=true]:ring-accent/15"; "**:data-[slot=tabs-tab]:data-[selected=true]:font-medium"; "**:data-[slot=tabs-tab]:data-[selected=true]:text-accent-foreground"; "**:data-[slot=tabs-tab]:shadow-none"; "**:data-[slot=tabs-indicator]:rounded-lg"; "**:data-[slot=tabs-indicator]:bg-accent"; "**:data-[slot=tabs-indicator]:shadow-none"; ]
let make () = <Tabs class_="w-full max-w-sm"> <Tabs.List_container class_="rounded-none bg-transparent"> <Tabs.List aria_label="Billing cycle" class_=(fun () -> list_class)> <Tabs.Tab id="monthly">"Monthly" <Tabs.Indicator /></Tabs.Tab> <Tabs.Tab id="yearly">"Yearly" <Tabs.Indicator /></Tabs.Tab> </Tabs.List> </Tabs.List_container> <Tabs.Panel class_="pt-3 text-sm text-muted" id="monthly"> "Billed monthly, cancel anytime." </Tabs.Panel> <Tabs.Panel class_="pt-3 text-sm text-muted" id="yearly"> "Save 20% with annual billing." </Tabs.Panel> </Tabs>Global CSS
Section titled “Global CSS”HeroUI’s classes are global, so a stylesheet restyles every tabs, as with HeroUI in React:
@layer components { .tabs__list { @apply rounded-xl border border-border bg-surface p-1; }
.tabs__indicator { @apply rounded-lg bg-foreground shadow-sm; }}Styling Reference
Section titled “Styling Reference”CSS Classes
Section titled “CSS Classes”.tabs, the root, and.tabs--secondary,.tabs--align-startand.tabs--align-end.tabs__list-container, and inside it.tabs__list-container__scroller,.tabs__list-container__scroll-prevand.tabs__list-container__scroll-next.tabs__list,.tabs__tab,.tabs__indicator,.tabs__separator.tabs__panel
Interactive States
Section titled “Interactive States”- Selected:
[aria-selected="true"]and[data-selected="true"]on the tab - Hover:
:hoveror[data-hovered="true"]on the tab - Focus:
:focus-visibleor[data-focus-visible="true"]on the tab - Disabled:
[aria-disabled="true"]and[data-disabled="true"]on the tab - Orientation:
[data-orientation]on the root, the list and the panel
API Reference
Section titled “API Reference”Each prop beside the name HeroUI’s React component gives it.
| React | solidtype | Type | Default | Description |
|---|---|---|---|---|
selectedKey |
selected_key |
string |
The selected tab’s id, while given | |
defaultSelectedKey |
default_selected_key |
string |
the first not disabled | The one selected at first |
onSelectionChange |
on_selection_change |
string -> unit |
Called with the id of the tab selected | |
orientation |
orientation |
[ `horizontal | `vertical ] |
`horizontal |
How the tabs lie |
variant |
variant |
[ `primary | `secondary ] |
`primary |
Its look |
align |
align |
[ `start | `center | `end_ ] |
`center |
Where a tab’s content sits |
keyboardActivation |
keyboard_activation |
[ `automatic | `manual ] |
`automatic |
Whether focus selects, or Enter and Space do |
isDisabled |
is_disabled |
bool |
false |
Whether every tab is disabled |
className |
class_ |
string |
Added after HeroUI’s classes | |
render |
— | Not yet |
Tabs.List
Section titled “Tabs.List”| React | solidtype | Type | Description |
|---|---|---|---|
aria-label |
aria_label |
string |
What the tabs are, for a reader |
className |
class_ |
string |
Added after HeroUI’s classes |
Tabs.Tab
Section titled “Tabs.Tab”| React | solidtype | Type | Default | Description |
|---|---|---|---|---|
id |
id |
string |
Its key, and its panel’s; required | |
isDisabled |
is_disabled |
bool |
false |
Whether it is disabled |
className |
class_ |
string |
Added after HeroUI’s classes | |
href, render |
— | Not yet |
Tabs.Panel
Section titled “Tabs.Panel”| React | solidtype | Type | Description |
|---|---|---|---|
id |
id |
string |
Its tab’s id; required |
className |
class_ |
string |
Added after HeroUI’s classes |
Tabs.List_container, Tabs.Indicator, Tabs.Separator
Section titled “Tabs.List_container, Tabs.Indicator, Tabs.Separator”| React | solidtype | Type | Description |
|---|---|---|---|
className |
class_ |
string |
Added after HeroUI’s classes |
Beside React
Section titled “Beside React”Original HeroUI documentation: Tabs.
The same HeroUI Tabs twice, under the same props: in solidtype on the left, in React on the right. Below them, every attribute of the two roots: a marked row is one they disagree on, and a dimmed row is a framework’s own, which no style reads.
A tab is Kobalte’s button where React Aria’s is a div, each of role tab.
A panel names no orientation, as React Aria’s names none, so the spacing
HeroUI’s styles would give it by its orientation reaches neither, and a panel
sits as close to its list as on heroui.com. React Aria marks its root focused while a tab is,
which no style reads and the port does not.
| attribute | solidtype | React |
|---|
