Unified UI

Tabs

A tabbed interface component for organizing content into switchable panels within your Laravel Blade views.

Overview

The Tabs component provides a tabbed navigation interface for organizing related content into switchable panels. Built as a Blade component with Alpine.js for interactivity, it supports horizontal and vertical orientations, variants, and keyboard navigation.

Installation

php artisan vendor:publish --tag=unified-ui-tabs

Copy the Blade component files into your project:

resources/views/components/ui/tabs.blade.php
resources/views/components/ui/tabs-list.blade.php
resources/views/components/ui/tabs-trigger.blade.php
resources/views/components/ui/tabs-content.blade.php

Basic Usage

<x-ui.tabs default="account">
    <x-ui.tabs-list>
        <x-ui.tabs-trigger value="account">Account</x-ui.tabs-trigger>
        <x-ui.tabs-trigger value="password">Password</x-ui.tabs-trigger>
        <x-ui.tabs-trigger value="notifications">Notifications</x-ui.tabs-trigger>
    </x-ui.tabs-list>

    <x-ui.tabs-content value="account">
        <p>Manage your account settings and preferences.</p>
    </x-ui.tabs-content>

    <x-ui.tabs-content value="password">
        <p>Change your password and security settings.</p>
    </x-ui.tabs-content>

    <x-ui.tabs-content value="notifications">
        <p>Configure your notification preferences.</p>
    </x-ui.tabs-content>
</x-ui.tabs>

Variants

Underline (default)

<x-ui.tabs default="tab1" variant="underline">
    <x-ui.tabs-list>
        <x-ui.tabs-trigger value="tab1">Tab 1</x-ui.tabs-trigger>
        <x-ui.tabs-trigger value="tab2">Tab 2</x-ui.tabs-trigger>
    </x-ui.tabs-list>

    <x-ui.tabs-content value="tab1">Content for tab 1</x-ui.tabs-content>
    <x-ui.tabs-content value="tab2">Content for tab 2</x-ui.tabs-content>
</x-ui.tabs>

Solid

<x-ui.tabs default="tab1" variant="solid">
    <x-ui.tabs-list>
        <x-ui.tabs-trigger value="tab1">Tab 1</x-ui.tabs-trigger>
        <x-ui.tabs-trigger value="tab2">Tab 2</x-ui.tabs-trigger>
    </x-ui.tabs-list>

    <x-ui.tabs-content value="tab1">Content for tab 1</x-ui.tabs-content>
    <x-ui.tabs-content value="tab2">Content for tab 2</x-ui.tabs-content>
</x-ui.tabs>

Pill

<x-ui.tabs default="tab1" variant="pill">
    <x-ui.tabs-list>
        <x-ui.tabs-trigger value="tab1">Tab 1</x-ui.tabs-trigger>
        <x-ui.tabs-trigger value="tab2">Tab 2</x-ui.tabs-trigger>
    </x-ui.tabs-list>

    <x-ui.tabs-content value="tab1">Content for tab 1</x-ui.tabs-content>
    <x-ui.tabs-content value="tab2">Content for tab 2</x-ui.tabs-content>
</x-ui.tabs>

Sizes

The Tabs component supports sm, md (default), and lg sizes:

<x-ui.tabs default="tab1" size="sm">...</x-ui.tabs>
<x-ui.tabs default="tab1" size="md">...</x-ui.tabs>
<x-ui.tabs default="tab1" size="lg">...</x-ui.tabs>

Vertical Orientation

<x-ui.tabs default="tab1" orientation="vertical">
    <div class="flex gap-4">
        <x-ui.tabs-list>
            <x-ui.tabs-trigger value="tab1">General</x-ui.tabs-trigger>
            <x-ui.tabs-trigger value="tab2">Security</x-ui.tabs-trigger>
            <x-ui.tabs-trigger value="tab3">Billing</x-ui.tabs-trigger>
        </x-ui.tabs-list>

        <div class="flex-1">
            <x-ui.tabs-content value="tab1">General settings content</x-ui.tabs-content>
            <x-ui.tabs-content value="tab2">Security settings content</x-ui.tabs-content>
            <x-ui.tabs-content value="tab3">Billing settings content</x-ui.tabs-content>
        </div>
    </div>
</x-ui.tabs>

With Icons

<x-ui.tabs default="account">
    <x-ui.tabs-list>
        <x-ui.tabs-trigger value="account">
            <x-icon name="user" class="size-4 mr-2" />
            Account
        </x-ui.tabs-trigger>
        <x-ui.tabs-trigger value="settings">
            <x-icon name="settings" class="size-4 mr-2" />
            Settings
        </x-ui.tabs-trigger>
    </x-ui.tabs-list>

    <x-ui.tabs-content value="account">Account content</x-ui.tabs-content>
    <x-ui.tabs-content value="settings">Settings content</x-ui.tabs-content>
</x-ui.tabs>

Disabled Tab

<x-ui.tabs default="tab1">
    <x-ui.tabs-list>
        <x-ui.tabs-trigger value="tab1">Active</x-ui.tabs-trigger>
        <x-ui.tabs-trigger value="tab2" disabled>Disabled</x-ui.tabs-trigger>
        <x-ui.tabs-trigger value="tab3">Another Tab</x-ui.tabs-trigger>
    </x-ui.tabs-list>

    <x-ui.tabs-content value="tab1">Active content</x-ui.tabs-content>
    <x-ui.tabs-content value="tab3">Another tab content</x-ui.tabs-content>
</x-ui.tabs>

With Livewire

You can integrate Tabs with Livewire for server-side tab state management:

<x-ui.tabs
    default="{{ $activeTab }}"
    x-on:tab-change="$wire.set('activeTab', $event.detail.value)"
>
    <x-ui.tabs-list>
        <x-ui.tabs-trigger value="overview">Overview</x-ui.tabs-trigger>
        <x-ui.tabs-trigger value="analytics">Analytics</x-ui.tabs-trigger>
        <x-ui.tabs-trigger value="reports">Reports</x-ui.tabs-trigger>
    </x-ui.tabs-list>

    <x-ui.tabs-content value="overview">
        @livewire('dashboard.overview')
    </x-ui.tabs-content>

    <x-ui.tabs-content value="analytics">
        @livewire('dashboard.analytics')
    </x-ui.tabs-content>

    <x-ui.tabs-content value="reports">
        @livewire('dashboard.reports')
    </x-ui.tabs-content>
</x-ui.tabs>

Blade Component Reference

<x-ui.tabs>

PropTypeDefaultDescription
defaultstringRequired. The value of the tab to show by default.
variant'underline' | 'solid' | 'pill''underline'Visual style of the tab triggers.
size'sm' | 'md' | 'lg''md'Size of the tab triggers.
orientation'horizontal' | 'vertical''horizontal'Orientation of the tab list.

<x-ui.tabs-list>

PropTypeDefaultDescription
classstring''Additional CSS classes for the tab list container.

<x-ui.tabs-trigger>

PropTypeDefaultDescription
valuestringRequired. Unique identifier for this tab.
disabledboolfalseWhether the trigger is disabled.
classstring''Additional CSS classes.

<x-ui.tabs-content>

PropTypeDefaultDescription
valuestringRequired. Must match a trigger's value to associate the panel.
classstring''Additional CSS classes.

Events

EventDetailDescription
tab-change{ value: string }Dispatched on the root element when the active tab changes.

Keyboard Navigation

KeyAction
ArrowLeft / ArrowRightMove focus between tabs (horizontal).
ArrowUp / ArrowDownMove focus between tabs (vertical).
HomeMove focus to the first tab.
EndMove focus to the last tab.
Enter / SpaceActivate the focused tab.

Accessibility

  • The component uses role="tablist", role="tab", and role="tabpanel" for proper ARIA semantics.
  • Each trigger is linked to its panel via aria-controls and aria-selected.
  • Disabled tabs receive aria-disabled="true" and are excluded from keyboard navigation.

The Tabs component relies on Alpine.js for client-side interactivity. Make sure Alpine.js is loaded in your application before using this component.

On this page