Tabs
Tabbed interface with placements, closable tabs, and htmx lazy loading.
<rhx-tab-group>
Examples
Basic Tabs
General account settings. Configure your display name, email, and language preferences.
Profile settings. Update your bio, avatar, and social links.
Notification preferences. Choose which emails and alerts you want to receive.
<rhx-tab-group aria-label="Account settings">
<rhx-tab rhx-panel="general" rhx-active="true">General</rhx-tab>
<rhx-tab rhx-panel="profile">Profile</rhx-tab>
<rhx-tab rhx-panel="notifications">Notifications</rhx-tab>
<rhx-tab-panel rhx-name="general" rhx-active="true">
<p>General account settings.</p>
</rhx-tab-panel>
<rhx-tab-panel rhx-name="profile">
<p>Profile settings.</p>
</rhx-tab-panel>
<rhx-tab-panel rhx-name="notifications">
<p>Notification preferences.</p>
</rhx-tab-panel>
</rhx-tab-group>
Placements
Bottom
Content for tab one (bottom placement).
Content for tab two (bottom placement).
Start (vertical)
Dashboard overview with key metrics and quick actions.
Analytics panel with charts and data visualizations.
Reports section for generating and downloading reports.
End (vertical)
Info panel content (end placement).
Details panel content (end placement).
<!-- Bottom -->
<rhx-tab-group rhx-placement="bottom">
<rhx-tab rhx-panel="b-one" rhx-active="true">Tab One</rhx-tab>
<rhx-tab rhx-panel="b-two">Tab Two</rhx-tab>
<rhx-tab-panel rhx-name="b-one" rhx-active="true">
<p>Bottom placement content.</p>
</rhx-tab-panel>
<rhx-tab-panel rhx-name="b-two">
<p>Tab two content.</p>
</rhx-tab-panel>
</rhx-tab-group>
<!-- Start (vertical) -->
<rhx-tab-group rhx-placement="start">
<rhx-tab rhx-panel="s-one" rhx-active="true">Dashboard</rhx-tab>
<rhx-tab rhx-panel="s-two">Analytics</rhx-tab>
<rhx-tab rhx-panel="s-three">Reports</rhx-tab>
<rhx-tab-panel rhx-name="s-one" rhx-active="true">
<p>Dashboard overview.</p>
</rhx-tab-panel>
<rhx-tab-panel rhx-name="s-two">
<p>Analytics panel.</p>
</rhx-tab-panel>
<rhx-tab-panel rhx-name="s-three">
<p>Reports section.</p>
</rhx-tab-panel>
</rhx-tab-group>
<!-- End (vertical) -->
<rhx-tab-group rhx-placement="end">
<rhx-tab rhx-panel="e-one" rhx-active="true">Info</rhx-tab>
<rhx-tab rhx-panel="e-two">Details</rhx-tab>
<rhx-tab-panel rhx-name="e-one" rhx-active="true">
<p>Info panel content.</p>
</rhx-tab-panel>
<rhx-tab-panel rhx-name="e-two">
<p>Details panel content.</p>
</rhx-tab-panel>
</rhx-tab-group>
Manual Activation
First tab content. Use arrow keys to move focus, then Enter/Space to select.
Second tab content.
Third tab content.
<rhx-tab-group rhx-activation="manual">
<rhx-tab rhx-panel="m-one" rhx-active="true">First</rhx-tab>
<rhx-tab rhx-panel="m-two">Second</rhx-tab>
<rhx-tab rhx-panel="m-three">Third</rhx-tab>
<rhx-tab-panel rhx-name="m-one" rhx-active="true">
<p>Use arrow keys to move focus, then Enter/Space to select.</p>
</rhx-tab-panel>
<rhx-tab-panel rhx-name="m-two">
<p>Second tab content.</p>
</rhx-tab-panel>
<rhx-tab-panel rhx-name="m-three">
<p>Third tab content.</p>
</rhx-tab-panel>
</rhx-tab-group>
Closable Tabs
Document 1 content. Close this tab to see the next one activate.
Document 2 content.
Document 3 content.
<rhx-tab-group>
<rhx-tab rhx-panel="c-one" rhx-active="true" rhx-closable="true">Document 1</rhx-tab>
<rhx-tab rhx-panel="c-two" rhx-closable="true">Document 2</rhx-tab>
<rhx-tab rhx-panel="c-three" rhx-closable="true">Document 3</rhx-tab>
<rhx-tab-panel rhx-name="c-one" rhx-active="true">
<p>Document 1 content. Close this tab to see the next one activate.</p>
</rhx-tab-panel>
<rhx-tab-panel rhx-name="c-two">
<p>Document 2 content.</p>
</rhx-tab-panel>
<rhx-tab-panel rhx-name="c-three">
<p>Document 3 content.</p>
</rhx-tab-panel>
</rhx-tab-group>
Disabled Tab
This tab is active. The "Disabled" tab cannot be clicked or focused via keyboard.
This content is unreachable via the disabled tab.
Available tab content.
<rhx-tab-group>
<rhx-tab rhx-panel="d-one" rhx-active="true">Active</rhx-tab>
<rhx-tab rhx-panel="d-two" rhx-disabled="true">Disabled</rhx-tab>
<rhx-tab rhx-panel="d-three">Available</rhx-tab>
<rhx-tab-panel rhx-name="d-one" rhx-active="true">
<p>The "Disabled" tab cannot be clicked or focused via keyboard.</p>
</rhx-tab-panel>
<rhx-tab-panel rhx-name="d-two">
<p>This content is unreachable via the disabled tab.</p>
</rhx-tab-panel>
<rhx-tab-panel rhx-name="d-three">
<p>Available tab content.</p>
</rhx-tab-panel>
</rhx-tab-group>
htmx Lazy Loading
This panel was rendered with the page. The other tabs will load content via htmx when first clicked.
<rhx-tab-group>
<rhx-tab rhx-panel="lazy-pre" rhx-active="true">Pre-rendered</rhx-tab>
<rhx-tab rhx-panel="lazy-one"
hx-get="/Docs/Components/Tabs?handler=LazyContent&tab=one"
hx-target="#panel-lazy-one"
hx-swap="innerHTML"
hx-trigger="click once">Lazy Tab 1</rhx-tab>
<rhx-tab rhx-panel="lazy-two"
hx-get="/Docs/Components/Tabs?handler=LazyContent&tab=two"
hx-target="#panel-lazy-two"
hx-swap="innerHTML"
hx-trigger="click once">Lazy Tab 2</rhx-tab>
<rhx-tab-panel rhx-name="lazy-pre" rhx-active="true">
<p>This panel was rendered with the page.</p>
</rhx-tab-panel>
<rhx-tab-panel rhx-name="lazy-one">
<rhx-spinner rhx-size="small" /> Loading...
</rhx-tab-panel>
<rhx-tab-panel rhx-name="lazy-two">
<rhx-spinner rhx-size="small" /> Loading...
</rhx-tab-panel>
</rhx-tab-group>
Properties
| Property | Type | Default | Description |
|---|---|---|---|
rhx-placement |
string |
top |
Tab bar position: top, bottom, start, end |
rhx-activation |
string |
auto |
Activation mode: auto (arrow keys activate), manual (Enter/Space to activate) |
aria-label |
string |
- |
Accessible label for the tab group |
Tab Properties
Properties for <rhx-tab> elements.
Properties
| Property | Type | Default | Description |
|---|---|---|---|
rhx-panel |
string |
- |
Name of the associated tab panel |
rhx-active |
bool |
false |
Whether this tab is initially active |
rhx-closable |
bool |
false |
Shows a close button on the tab |
rhx-disabled |
bool |
false |
Disables the tab |
Panel Properties
Properties for <rhx-tab-panel> elements.
Properties
| Property | Type | Default | Description |
|---|---|---|---|
rhx-name |
string |
- |
Panel name matching the tab's rhx-panel value |
rhx-active |
bool |
false |
Whether this panel is initially visible |
Accessibility
- Uses
role="tablist"on the tab bar withrole="tab"on each tab androle="tabpanel"on each panel. - Active tab receives
aria-selected="true"; panels are linked viaaria-controlsandaria-labelledby. - Arrow keys navigate between tabs; Home and End jump to the first and last tab.
- In manual activation mode, arrow keys move focus only; Enter or Space activates the focused tab.
- Disabled tabs receive
aria-disabled="true"and are skipped during keyboard navigation. - Vertical placements (
start,end) setaria-orientation="vertical"and use up/down arrow keys.