Tabs
Links that swap a panel loaded from the server.
Each tab is a real link to a page URL that shows that tab. With HTMX the panel loads from {href}:{block} and the URL is pushed, and without JavaScript the link is a plain navigation. The server decides which tab is active, so the page wraps the component in a {fragment} that swaps the whole thing.
{fragment 'tabs', swap: 'outerHTML'}
{component tabs, items: $items}
{$panel}
{/component}
{/fragment}
An item is ['title' => 'Plan', 'href' => '/account/plan', 'active' => true]. A tab whose URL has a query string adds hx, the fragment URL, because the block name goes before the query: /account:tabs?tab=plan. An item can also be a page, which becomes its title, URL and active state. This page does that below, and swaps its own docs fragment.
{var $url = $page->url()}
{var $tab = $request->query('tab') ?? 'overview'}
{component tabs,
block: 'docs',
id: 'tabs-demo',
items: [
[
'title' => 'Overview',
'href' => "{$url}?tab=overview",
'hx' => "{$url}:docs?tab=overview",
'active' => $tab === 'overview'
],
[
'title' => 'Usage',
'href' => "{$url}?tab=usage",
'hx' => "{$url}:docs?tab=usage",
'active' => $tab === 'usage'
],
],
}
{if $tab === 'usage'}
Each tab is a link, so the panel also loads without JavaScript.
{else}
Pick a tab to load its panel from the server.
{/if}
{/component}
Params
| Param | Default | Description |
|---|---|---|
| items | [] | the tabs: pages or arrays like ['title' => 'Plan', 'href' => '/account/plan', 'active' => true]; an array's hx overrides the fragment URL |
| block | 'tabs' | the page's {fragment} the tabs load |
| id | null | the root's id, the block name when null, so a fragment swapping outerHTML can target it |
| body | null | the active panel as a string, or the tag's content |
| class | '' | added to tabs |
| attrs | [] | any other attributes, e.g. ['data-x' => 'y'] |