Tabs
Three tags make up this family: <oblyx-tab-list> is the strip, each <oblyx-tab> is one tab inside it, and each <oblyx-tab-panel> is the content that tab controls. Unlike upstream Astryx, which only tracks which tab looks selected, Oblyx's tab list also owns real panels with role="tabpanel" and the full aria-controls/aria-labelledby wiring, because a server-rendered page needs somewhere for the tab content to actually live.
Basic tabs
<oblyx-tab-list id="fruit-tabs" value="apple">
<oblyx-tab value="apple">Apple</oblyx-tab>
<oblyx-tab value="banana">Banana</oblyx-tab>
<oblyx-tab value="cherry">Cherry</oblyx-tab>
</oblyx-tab-list>
<oblyx-tab-panel list="fruit-tabs" value="apple">Apples are crisp and sweet.</oblyx-tab-panel>
<oblyx-tab-panel list="fruit-tabs" value="banana">Bananas are soft and mild.</oblyx-tab-panel>
<oblyx-tab-panel list="fruit-tabs" value="cherry">Cherries are tart and small.</oblyx-tab-panel>oblyxTabList(value = "apple") {
attributes["id"] = "fruit-tabs"
oblyxTab(value = "apple") { +"Apple" }
oblyxTab(value = "banana") { +"Banana" }
oblyxTab(value = "cherry") { +"Cherry" }
}
oblyxTabPanel(list = "fruit-tabs", value = "apple") { +"Apples are crisp and sweet." }
oblyxTabPanel(list = "fruit-tabs", value = "banana") { +"Bananas are soft and mild." }
oblyxTabPanel(list = "fruit-tabs", value = "cherry") { +"Cherries are tart and small." }How a panel finds its list
A <oblyx-tab-panel> is a sibling of <oblyx-tab-list>, not a descendant of it: realistic markup puts the whole tab strip above the panels, the way the example above is written. Nothing in the tag names suggests that relationship, so it works the same way <label for> does: each panel's list attribute names the id of the tab list it belongs to, and the panel resolves that reference fresh every time the list's selection changes, never a cached reference. When list is omitted, a panel falls back to the page's first <oblyx-tab-list>, the zero-config path for the common case of one tab group per page. Every example on this page sets list explicitly: this docs site's own <Example> component renders its HTML/Kotlin source toggle using this same tab family, so a real page here always has more than one <oblyx-tab-list> on it, and the omitted-list fallback would resolve to the wrong one if we relied on it in a live demo.
Sizes
Tab sizes
<oblyx-tab-list id="size-tabs-sm" value="one" size="sm">
<oblyx-tab value="one">One</oblyx-tab>
<oblyx-tab value="two">Two</oblyx-tab>
</oblyx-tab-list>
<oblyx-tab-list id="size-tabs-md" value="one" size="md">
<oblyx-tab value="one">One</oblyx-tab>
<oblyx-tab value="two">Two</oblyx-tab>
</oblyx-tab-list>
<oblyx-tab-list id="size-tabs-lg" value="one" size="lg">
<oblyx-tab value="one">One</oblyx-tab>
<oblyx-tab value="two">Two</oblyx-tab>
</oblyx-tab-list>oblyxTabList(value = "one", size = OblyxTabListSize.SM) {
oblyxTab(value = "one") { +"One" }
oblyxTab(value = "two") { +"Two" }
}
oblyxTabList(value = "one", size = OblyxTabListSize.MD) {
oblyxTab(value = "one") { +"One" }
oblyxTab(value = "two") { +"Two" }
}
oblyxTabList(value = "one", size = OblyxTabListSize.LG) {
oblyxTab(value = "one") { +"One" }
oblyxTab(value = "two") { +"Two" }
}Layout
hug (the default) sizes each tab to its own content. fill stretches every tab to share the strip's width equally.
Fill layout
<oblyx-tab-list id="fill-tabs" value="one" layout="fill">
<oblyx-tab value="one">One</oblyx-tab>
<oblyx-tab value="two">Two</oblyx-tab>
<oblyx-tab value="three">Three</oblyx-tab>
</oblyx-tab-list>oblyxTabList(value = "one", layout = OblyxTabListLayout.FILL) {
oblyxTab(value = "one") { +"One" }
oblyxTab(value = "two") { +"Two" }
oblyxTab(value = "three") { +"Three" }
}Divider
has-divider adds a bottom divider under the whole strip, with the selected indicator dropped onto it.
Tab list with divider
<oblyx-tab-list id="divider-tabs" value="one" has-divider>
<oblyx-tab value="one">One</oblyx-tab>
<oblyx-tab value="two">Two</oblyx-tab>
</oblyx-tab-list>oblyxTabList(value = "one", hasDivider = true) {
oblyxTab(value = "one") { +"One" }
oblyxTab(value = "two") { +"Two" }
}Keyboard model
ArrowRight/ArrowDown and ArrowLeft/ArrowUp move focus one tab at a time and wrap at the ends; Home and End jump to the first and last tab. Only the selected tab is a Tab stop (roving tabindex); arrow keys move focus without a separate Tab press. Selection is automatic: moving focus with an arrow key selects that tab and shows its panel in the same keystroke, rather than requiring a follow-up Enter or Space. The panels here are cheap, already-rendered content with nothing to lazily load, so there is no cost to switching immediately.
Reference
<oblyx-tab-list>
| Attribute | Type | Default | Description |
|---|---|---|---|
value | string | undefined | – | The selected tab's value, the single source of truth for selection. Reflected so oblyx-tab-list[value="…"] is a CSS hook and so an author can pre-select a tab with a plain attribute. Starts undefined (no tab selected) until a tab-select event or a keyboard activation sets it. |
size | smmdlg | md | Element height for every tab in this strip. Pure CSS. |
layout | hugfill | hug | 'hug' sizes each tab to its own content; 'fill' stretches all tabs to share the strip's width equally. Pure CSS. |
has-divider | boolean | false | Bottom divider under the whole strip, with the selected indicator dropped onto it. Pure CSS. |
<oblyx-tab>
| Attribute | Type | Default | Description |
|---|---|---|---|
value | string | undefined | – | Matched against the tab-list's value to decide selection, and used to derive this tab's id and its aria-controls target ({listId}-panel-{value}). Required, like a native <option value>; missing it is a defect and is flagged loudly, the same convention oblyx-option.ts uses for its own required value. |
Events
| Event | Type | Description |
|---|---|---|
tab-select | CustomEvent |
<oblyx-tab-panel>
| Attribute | Type | Default | Description |
|---|---|---|---|
value | string | undefined | – | Matched against the resolved tab-list's value. Required, same convention as OblyxTab.value. |
list | string | undefined | – | Id of the <oblyx-tab-list> this panel belongs to. Optional; when unset, resolves to the single tab-list on the page. |