Skip to content

Source code

Tabs

Switch between related panels while keeping keyboard focus and selection synchronized.

Start with your first page. Shared ui* providers are registered by createAdmin. Examples belong inside a route template, not the root HTML document. The page and its optional controller load through Atrium’s lazy route registry.

Minimal example

<div x-data="uiTabs(['one', 'two'])" x-id="['tabs']">
<div class="nav nav-tabs" role="tablist" aria-label="Record views" @keydown="navigate">
<template x-for="tab in ['one', 'two']" :key="tab">
<button role="tab" class="nav-link" :id="$id('tabs') + tab" :aria-controls="$id('tabs') + '-panel-' + tab" :aria-selected="active === tab" :tabindex="active === tab ? 0 : -1" @click="select(tab)" x-text="tab"></button>
</template>
</div>
<template x-for="tab in ['one', 'two']" :key="tab">
<div role="tabpanel" tabindex="0" :id="$id('tabs') + '-panel-' + tab" :aria-labelledby="$id('tabs') + tab" x-show="active === tab" x-text="tab"></div>
</template>
</div>

Settings and behavior

  • Pass a nonempty ordered array of unique panel IDs.
  • The first panel is selected initially.
  • Use active and select(id) for state and navigate(event) for arrow, Home, and End support.
  • x-id keeps multiple tab groups independent.

Integration notes

Use theme tokens instead of fixed colors. Keep accessible labels on controls. Test with keyboard navigation, both themes, and a narrow RTL viewport.

Working reference

See the production example. Return to the component index.

Author

Laurent Declercq l.declercq@agon-innovation.ch

License

Unless otherwise stated all source code is licensed under LGPL 2.1 and has the following copyright:

© 2026, Agon Partners Innovation AG, All rights reserved.

The design material and the “Agon Ātrium” trademark is the property of their authors. Reuse of them without prior consent of their respective authors is strictly prohibited.

Version

Version: 20260921