tabs — accessible tabs with deep links
Standard tabs with ARIA (role="tablist", role="tab", role="tabpanel", aria-selected, aria-controls), keyboard navigation (Arrow keys, Home, End), and deep linking — the active tab key syncs to the URL hash so users can share ?#specs and land on the right tab.
Use for product detail sections (description / specs / reviews), dashboard panels, settings categories.
Install
npx czg-ui add tabs
@import 'components/tabs'; to app.scss, import './components/tabs'; to app.js.
Requires base.
Parameters
| Param | Type | Default | Notes | |
|---|---|---|---|---|
id | string | — | Unique id (required for ARIA wiring + deep link) | |
items | array | — | [['key' => 'specs', 'label' => 'Parametry', 'body' => '<html>'], …] | |
active | string\ | null | first item's key | Initially active tab key |
Usage
{include /app/components/Tabs/tabs.latte,
id => 'product-info',
items => [
['key' => 'description', 'label' => 'Popis', 'body' => $product->description],
['key' => 'specs', 'label' => 'Parametry', 'body' => $product->specsHtml],
['key' => 'reviews', 'label' => 'Recenze', 'body' => $reviewsHtml],
]
}
Keyboard
←/→— move focus between tabsHome/End— jump to first / lastEnter/Space— activate focused tab- Tabbing into the panel works as expected (panel content is
keyboard-reachable in DOM order)
Deep linking
Activating a tab updates location.hash to #<key>. On page load with a matching hash, that tab is auto-activated. To opt out, override the component's JS — the rest of the API stays the same.
When NOT to use
- Single content area — tabs add UI weight for no reason
- Mobile flows where vertical scroll is natural — long scrollable
page with section headings is often friendlier on small screens than hidden tab content