Phara UI v2.x

Sidebar Layout

A responsive sidebar layout with desktop collapse and mobile toggle support.

Basic

A fixed sidebar on the left with a scrollable main content area.

App Name
Home
Analytics
Users
Settings
Page Title
Blade
<div>
    <!-- Sidebar -->
    <aside class="fixed top-0 left-0 h-screen w-64 flex flex-col
                  bg-white dark:bg-gray-900
                  border-r border-gray-200 dark:border-gray-800">

        <!-- Logo -->
        <div class="flex items-center gap-2 h-16 px-4 shrink-0
                    border-b border-gray-200 dark:border-gray-800">
            <x-ui::icon name="bolt" variant="solid" class="text-primary-500 size-5 shrink-0" />
            <span class="font-semibold text-gray-900 dark:text-white">App Name</span>
        </div>

        <!-- Nav -->
        <nav class="flex-1 overflow-y-auto p-3">
            <x-ui::navlist>
                <x-ui::navlist-item href="#" icon="home">Home</x-ui::navlist-item>
                <x-ui::navlist-item href="#" icon="chart-bar">Analytics</x-ui::navlist-item>
                <x-ui::navlist-item href="#" icon="users">Users</x-ui::navlist-item>
                <x-ui::navlist-item href="#" icon="cog-6-tooth">Settings</x-ui::navlist-item>
            </x-ui::navlist>
        </nav>
    </aside>

    <!-- Content -->
    <div class="lg:pl-64 min-h-screen">
        <header class="sticky top-0 z-40 flex items-center h-16 px-6
                       bg-white dark:bg-gray-900
                       border-b border-gray-200 dark:border-gray-800">
            <h1 class="font-semibold text-gray-900 dark:text-white">Page Title</h1>
        </header>
        <main class="p-6">
            {{ $slot }}
        </main>
    </div>
</div>
Collapsible

Add a toggle button at the bottom of the sidebar to collapse it to icon-only mode on desktop.

App Name
Home
Analytics
Users
Settings
Page Title
Click the arrow to toggle
Blade
<div x-data="{ collapsed: false }">

    <!-- Sidebar -->
    <aside
        class="fixed top-0 left-0 h-screen flex flex-col overflow-hidden
               bg-white dark:bg-gray-900
               border-r border-gray-200 dark:border-gray-800
               transition-all duration-300 ease-in-out"
        :class="collapsed ? 'w-16' : 'w-64'"
    >
        <!-- Logo -->
        <div class="flex items-center h-16 px-4 shrink-0
                    border-b border-gray-200 dark:border-gray-800 overflow-hidden">
            <x-ui::icon name="bolt" variant="solid" class="text-primary-500 size-5 shrink-0" />
            <span x-show="!collapsed" x-collapse.horizontal
                  class="ml-2 font-semibold text-gray-900 dark:text-white whitespace-nowrap">
                App Name
            </span>
        </div>

        <!-- Nav -->
        <nav class="flex-1 overflow-y-auto p-2">
            <x-ui::navlist>
                <x-ui::navlist-item href="#" icon="home">
                    <span x-show="!collapsed" x-transition:leave="transition-opacity duration-100"
                          x-transition:leave-end="opacity-0">Home</span>
                </x-ui::navlist-item>
                <x-ui::navlist-item href="#" icon="chart-bar">
                    <span x-show="!collapsed" x-transition:leave="transition-opacity duration-100"
                          x-transition:leave-end="opacity-0">Analytics</span>
                </x-ui::navlist-item>
                <x-ui::navlist-item href="#" icon="users">
                    <span x-show="!collapsed" x-transition:leave="transition-opacity duration-100"
                          x-transition:leave-end="opacity-0">Users</span>
                </x-ui::navlist-item>
                <x-ui::navlist-item href="#" icon="cog-6-tooth">
                    <span x-show="!collapsed" x-transition:leave="transition-opacity duration-100"
                          x-transition:leave-end="opacity-0">Settings</span>
                </x-ui::navlist-item>
            </x-ui::navlist>
        </nav>

        <!-- Collapse Toggle -->
        <button
            @click="collapsed = !collapsed"
            class="hidden lg:flex items-center justify-center h-12 shrink-0
                   border-t border-gray-200 dark:border-gray-800
                   text-gray-400 hover:text-gray-700 dark:hover:text-gray-200 transition-colors"
        >
            <x-ui::icon name="chevron-left" size="sm"
                class="transition-transform duration-300"
                :class="collapsed ? 'rotate-180' : ''" />
        </button>
    </aside>

    <!-- Content -->
    <div class="min-h-screen transition-all duration-300" :class="collapsed ? 'lg:pl-16' : 'lg:pl-64'">
        <header class="sticky top-0 z-40 flex items-center h-16 px-6
                       bg-white dark:bg-gray-900
                       border-b border-gray-200 dark:border-gray-800">
            <h1 class="font-semibold text-gray-900 dark:text-white">Page Title</h1>
        </header>
        <main class="p-6">{{ $slot }}</main>
    </div>
</div>
Mobile Toggle

On mobile, the sidebar is hidden off-screen and revealed by a hamburger button. A dimmed overlay closes it on tap.

Page Title
App Name
Home
Analytics
Users
Settings
Click ☰ to open sidebar
Blade
<div x-data="{ sidebarOpen: false }">

    <!-- Mobile Overlay -->
    <div
        x-show="sidebarOpen"
        x-transition.opacity
        class="fixed inset-0 bg-black/30 z-40 lg:hidden"
        @click="sidebarOpen = false"
    ></div>

    <!-- Sidebar -->
    <aside
        class="fixed z-50 top-0 left-0 h-screen w-64 flex flex-col
               bg-white dark:bg-gray-900
               border-r border-gray-200 dark:border-gray-800
               transition-transform duration-200 ease-in-out
               lg:translate-x-0"
        :class="sidebarOpen ? 'translate-x-0' : '-translate-x-full'"
    >
        <!-- Logo + Close (mobile) -->
        <div class="flex items-center justify-between h-16 px-4 shrink-0
                    border-b border-gray-200 dark:border-gray-800">
            <div class="flex items-center gap-2">
                <x-ui::icon name="bolt" variant="solid" class="text-primary-500 size-5" />
                <span class="font-semibold text-gray-900 dark:text-white">App Name</span>
            </div>
            <button @click="sidebarOpen = false"
                    class="lg:hidden p-1 rounded text-gray-400 hover:text-gray-600 dark:hover:text-gray-200">
                <x-ui::icon name="x-mark" size="sm" />
            </button>
        </div>

        <!-- Nav -->
        <nav class="flex-1 overflow-y-auto p-3">
            <x-ui::navlist>
                <x-ui::navlist-item href="#" icon="home">Home</x-ui::navlist-item>
                <x-ui::navlist-item href="#" icon="chart-bar">Analytics</x-ui::navlist-item>
                <x-ui::navlist-item href="#" icon="users">Users</x-ui::navlist-item>
                <x-ui::navlist-item href="#" icon="cog-6-tooth">Settings</x-ui::navlist-item>
            </x-ui::navlist>
        </nav>
    </aside>

    <!-- Content -->
    <div class="lg:pl-64 min-h-screen">
        <header class="sticky top-0 z-40 flex items-center gap-3 h-16 px-4
                       bg-white dark:bg-gray-900
                       border-b border-gray-200 dark:border-gray-800">
            <!-- Hamburger (mobile only) -->
            <button @click="sidebarOpen = true"
                    class="lg:hidden p-1.5 rounded-md text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-800">
                <x-ui::icon name="bars-3" />
            </button>
            <h1 class="font-semibold text-gray-900 dark:text-white">Page Title</h1>
        </header>
        <main class="p-6">{{ $slot }}</main>
    </div>
</div>
Full Layout

Complete ready-to-use sidebar layout combining collapse on desktop and hamburger toggle on mobile.

App Name
Home
Analytics
Users
Settings
Page Title
Arrow collapses · ☰ opens on mobile
Blade
<div x-data="{ sidebarOpen: false, collapsed: false }">

    <!-- Mobile Overlay -->
    <div
        x-show="sidebarOpen"
        x-transition.opacity
        class="fixed inset-0 bg-black/30 z-40 lg:hidden"
        @click="sidebarOpen = false"
    ></div>

    <!-- Sidebar -->
    <aside
        class="fixed z-50 top-0 left-0 h-screen flex flex-col overflow-hidden
               bg-white dark:bg-gray-900
               border-r border-gray-200 dark:border-gray-800
               transition-all duration-300 ease-in-out
               lg:translate-x-0"
        :class="[
            collapsed ? 'w-16' : 'w-64',
            sidebarOpen ? 'translate-x-0' : '-translate-x-full',
        ]"
    >
        <!-- Logo -->
        <div class="flex items-center h-16 px-4 shrink-0
                    border-b border-gray-200 dark:border-gray-800 overflow-hidden">
            <x-ui::icon name="bolt" variant="solid" class="text-primary-500 size-5 shrink-0" />
            <span x-show="!collapsed" x-collapse.horizontal
                  class="ml-2 font-semibold text-gray-900 dark:text-white whitespace-nowrap">
                App Name
            </span>
            <button @click="sidebarOpen = false"
                    class="lg:hidden ml-auto p-1 rounded text-gray-400 hover:text-gray-600 dark:hover:text-gray-200">
                <x-ui::icon name="x-mark" size="sm" />
            </button>
        </div>

        <!-- Nav -->
        <nav class="flex-1 overflow-y-auto p-2">
            <x-ui::navlist>
                <x-ui::navlist-item href="#" icon="home">
                    <span x-show="!collapsed" x-transition:leave="transition-opacity duration-100"
                          x-transition:leave-end="opacity-0">Home</span>
                </x-ui::navlist-item>
                <x-ui::navlist-item href="#" icon="chart-bar">
                    <span x-show="!collapsed" x-transition:leave="transition-opacity duration-100"
                          x-transition:leave-end="opacity-0">Analytics</span>
                </x-ui::navlist-item>
                <x-ui::navlist-item href="#" icon="users">
                    <span x-show="!collapsed" x-transition:leave="transition-opacity duration-100"
                          x-transition:leave-end="opacity-0">Users</span>
                </x-ui::navlist-item>
                <x-ui::navlist-item href="#" icon="cog-6-tooth">
                    <span x-show="!collapsed" x-transition:leave="transition-opacity duration-100"
                          x-transition:leave-end="opacity-0">Settings</span>
                </x-ui::navlist-item>
            </x-ui::navlist>
        </nav>

        <!-- Collapse Toggle (desktop only) -->
        <button
            @click="collapsed = !collapsed"
            class="hidden lg:flex items-center justify-center h-12 shrink-0
                   border-t border-gray-200 dark:border-gray-800
                   text-gray-400 hover:text-gray-700 dark:hover:text-gray-200 transition-colors"
        >
            <x-ui::icon name="chevron-left" size="sm"
                class="transition-transform duration-300"
                :class="collapsed ? 'rotate-180' : ''" />
        </button>
    </aside>

    <!-- Content Wrapper -->
    <div class="min-h-screen transition-all duration-300"
         :class="collapsed ? 'lg:pl-16' : 'lg:pl-64'">

        <!-- Header -->
        <header class="sticky top-0 z-40 flex items-center gap-3 h-16 px-4
                       bg-white dark:bg-gray-900
                       border-b border-gray-200 dark:border-gray-800">
            <!-- Hamburger (mobile only) -->
            <button
                @click="sidebarOpen = true"
                class="lg:hidden p-1.5 rounded-md text-gray-500
                       hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
            >
                <x-ui::icon name="bars-3" />
            </button>
            <h1 class="font-semibold text-gray-900 dark:text-white">Page Title</h1>
        </header>

        <!-- Page Content -->
        <main class="p-6">
            {{ $slot }}
        </main>
    </div>
</div>

collapsed shrinks the sidebar to w-16 on desktop. Nav labels fade out via x-show + x-transition and the icon remains visible.

sidebarOpen slides the sidebar in on mobile via -translate-x-full / translate-x-0. The overlay closes it on tap.

lg:translate-x-0 keeps the sidebar permanently visible on large screens regardless of sidebarOpen.