Tabs
Splits content into tabs shown in the same area. It has two looks, underlined and pills; switching tabs does not reload the page.
Basic usage
Tabs are generated from the tabs array: the key is the tab's value and the value is its title. The value of each acun:tab-panel must match a key. The default look is underlined; tabs have role="tab" and panels role="tabpanel".
<acun:tabs :tabs="['general' => 'General', 'orders' => 'Orders', 'history' => 'History']">
<acun:tab-panel value="general"><p class="text-sm text-gray-600 dark:text-zinc-400">Premium member · Kadıköy, Istanbul</p></acun:tab-panel>
<acun:tab-panel value="orders"><p class="text-sm text-gray-600 dark:text-zinc-400">Last order: September 12, 2026</p></acun:tab-panel>
<acun:tab-panel value="history"><p class="text-sm text-gray-600 dark:text-zinc-400">9 orders and 1 return in 2026.</p></acun:tab-panel>
</acun:tabs>
| Prop | Values |
|---|---|
tabs | ['key' => 'Title', …] |
value (tab-panel) | Matching tab key |
Pills
variant="pills" shows the selected tab filled; tabs wrap to the next line when they do not fit. Suitable for light switches such as filters or view selection.
<acun:tabs variant="pills" :tabs="['all' => 'All', 'pending' => 'Pending', 'delivered' => 'Delivered']">
<acun:tab-panel value="all"><p class="text-sm text-gray-600 dark:text-zinc-400">148 orders</p></acun:tab-panel>
<acun:tab-panel value="pending"><p class="text-sm text-gray-600 dark:text-zinc-400">36 orders are waiting to ship.</p></acun:tab-panel>
<acun:tab-panel value="delivered"><p class="text-sm text-gray-600 dark:text-zinc-400">112 orders were delivered.</p></acun:tab-panel>
</acun:tabs>
| Prop | Values |
|---|---|
variant | underline | pills |
Initial tab
active sets the tab selected on load; without it, the first key is selected. Keys can also be numbers (e.g. years); because active and value are compared as strings, :active="2025" matches value="2025". Switching tabs happens only in the browser; no request is sent to the server.
<acun:tabs :active="2025" :tabs="[2026 => '2026', 2025 => '2025', 2024 => '2024']">
<acun:tab-panel value="2026"><p class="text-sm text-gray-600 dark:text-zinc-400">2026: 9 orders</p></acun:tab-panel>
<acun:tab-panel value="2025"><p class="text-sm text-gray-600 dark:text-zinc-400">2025: 12 orders, 1 return</p></acun:tab-panel>
<acun:tab-panel value="2024"><p class="text-sm text-gray-600 dark:text-zinc-400">2024: 11 orders</p></acun:tab-panel>
</acun:tabs>
| Prop | Values |
|---|---|
active | Tab key |
Inside a card
Shorten long pages by splitting record details into tabs inside a card. The class and other attributes given to acun:tabs are added to the root element, and those given to acun:tab-panel to the panel. Show an acun:empty-state in tabs that have no content.
<acun:card title="Customer card" subtitle="Ayşe Yılmaz · #04112">
<acun:tabs variant="pills" :tabs="['general' => 'General', 'orders' => 'Orders', 'invoices' => 'Invoices']">
<acun:tab-panel value="general"><p class="text-sm text-gray-600 dark:text-zinc-400">Premium member · Kadıköy, Istanbul</p></acun:tab-panel>
<acun:tab-panel value="orders"><p class="text-sm text-gray-600 dark:text-zinc-400">Last order: September 12, 2026</p></acun:tab-panel>
<acun:tab-panel value="invoices" class="py-2"><acun:empty-state title="No invoices" /></acun:tab-panel>
</acun:tabs>
</acun:card>
Composing from parts
Write the tabs with acun:tabs.trigger (value, badge, icon, disabled) inside acun:tabs.list, and their contents with acun:tabs.panel. wire:model binds the open tab two-way to a Livewire property (initialize the property with a value); without it, the first tab opens. You move between tabs with the left/right arrow, Home and End keys. size is sm · md · lg.
<acun:tabs wire:model="activeTab" variant="underline" size="md">
<acun:tabs.list aria-label="Store overview">
<acun:tabs.trigger value="overview">Overview</acun:tabs.trigger>
<acun:tabs.trigger value="orders" badge="8">Orders</acun:tabs.trigger>
<acun:tabs.trigger value="settings">Settings</acun:tabs.trigger>
</acun:tabs.list>
<acun:tabs.panel value="overview">
<div class="grid gap-4 sm:grid-cols-3">
<acun:stat-card label="Orders" value="142" icon="shopping-bag" />
<acun:stat-card label="Delivered" value="118" icon="check-circle" color="success" />
<acun:stat-card label="Pending" value="24" icon="clock" color="warning" />
</div>
</acun:tabs.panel>
<acun:tabs.panel value="orders">
<ul class="divide-y divide-gray-100 text-sm dark:divide-zinc-800">
<li class="flex items-center justify-between py-2.5">
<span class="text-gray-900 dark:text-zinc-100">Cumhuriyet Dist., 12th St. No. 4</span>
<acun:badge variant="success">Delivered</acun:badge>
</li>
<li class="flex items-center justify-between py-2.5">
<span class="text-gray-900 dark:text-zinc-100">Atatürk Ave. No. 87 Apt. 3</span>
<acun:badge variant="warning">On the way</acun:badge>
</li>
</ul>
</acun:tabs.panel>
<acun:tabs.panel value="settings">
<p class="text-sm text-gray-600 dark:text-zinc-400">Store manager: Mehmet Kaya. Shipping cutoff 15:00; orders placed after that ship the next business day.</p>
</acun:tabs.panel>
</acun:tabs>
| Prop | Values |
|---|---|
wire:model | Livewire property the open tab is bound to |
size | sm · md · lg |
acun:tabs.trigger | value, badge, icon, disabled |
acun:tabs.panel | value |
Pill tabs with icons
variant="pills" draws filled tabs and wraps them to the next line on narrow screens; a disabled tab cannot be selected and is skipped by the keyboard.
<acun:tabs variant="pills" active="team">
<acun:tabs.list aria-label="Support view">
<acun:tabs.trigger value="tickets" icon="inbox">Tickets</acun:tabs.trigger>
<acun:tabs.trigger value="team" icon="users" badge="6">Team members</acun:tabs.trigger>
<acun:tabs.trigger value="report" icon="chart-bar">Report</acun:tabs.trigger>
<acun:tabs.trigger value="archive" icon="archive-box" disabled>Archive</acun:tabs.trigger>
</acun:tabs.list>
<acun:tabs.panel value="tickets">
<p class="text-sm text-gray-600 dark:text-zinc-400">142 tickets were opened today; 4 of them are marked urgent.</p>
</acun:tabs.panel>
<acun:tabs.panel value="team">
<p class="text-sm text-gray-600 dark:text-zinc-400">6 team members are online: 5 are answering tickets and 1 is on a break.</p>
</acun:tabs.panel>
<acun:tabs.panel value="report">
<p class="text-sm text-gray-600 dark:text-zinc-400">September 2026: 3,106 tickets, 94% resolved on the first reply.</p>
</acun:tabs.panel>
<acun:tabs.panel value="archive">Archive</acun:tabs.panel>
</acun:tabs>
Props and slots
The values the component accepts.
| Prop | Default | Description |
|---|---|---|
tabs | [] | key => title; the key is a string or a number |
active | first key | Tab selected on load (compared as a string) |
variant | underline | underline · pills |
tab-panel: value | — | Required; matching tab key |
size | md | sm · md · lg |
wire:model · x-model | — | Binds the open tab two-way to a property |
tabs.trigger: value · badge · icon · disabled | — | value is required; badge is a number or short text, icon an icon name |
tabs.panel: value | — | Required; the matching tabs.trigger value |