Skip to main content

Navigation

Menubar code

Copy the implementation or inspect every file that belongs to this component unit.

resources/views/components/ui/menubar.blade.php

@php
    /*
    | Application-style horizontal menu bar. Compose with <x-ui.menubar.menu>
    | children. Click a label to open its menu; while any menu is open, hovering
    | another label switches to it. Escape or an outside click closes.
    |
    | Usage:
    |   <x-ui.menubar>
    |       <x-ui.menubar.menu label="File">
    |           <x-ui.dropdown.item icon="file-plus">New file</x-ui.dropdown.item>
    |       </x-ui.menubar.menu>
    |       <x-ui.menubar.menu label="Edit">...</x-ui.menubar.menu>
    |   </x-ui.menubar>
    */
@endphp

<div
    x-data="{ active: null }"
    @click.outside="active = null"
    @keydown.escape.window="active = null"
    role="menubar"
    {{ $attributes->merge(['class' => 'inline-flex items-center gap-0.5 rounded-xl border border-gray-200 bg-white p-1 shadow-sm dark:border-gray-800 dark:bg-gray-900']) }}
>
    {{ $slot }}
</div>

resources/views/components/ui/menubar/menu.blade.php

@props([
    'label',
])

@php
    /*
    | A single menu inside <x-ui.menubar>. The label opens the panel; the
    | default slot takes <x-ui.dropdown.item> rows.
    */
@endphp

<div class="relative">
    <button
        type="button"
        @click="active = (active === @js($label)) ? null : @js($label)"
        @mouseenter="if (active !== null && active !== @js($label)) { active = @js($label); }"
        :class="active === @js($label)
            ? 'bg-gray-100 text-gray-900 dark:bg-gray-800 dark:text-white'
            : 'text-gray-600 hover:bg-gray-100 hover:text-gray-900 dark:text-gray-300 dark:hover:bg-gray-800 dark:hover:text-white'"
        :aria-expanded="(active === @js($label)).toString()"
        aria-haspopup="menu"
        class="rounded-lg px-3 py-1.5 text-sm font-medium transition cursor-pointer"
    >{{ $label }}</button>

    <div
        x-show="active === @js($label)" x-cloak
        x-transition:enter="transition ease-out duration-150"
        x-transition:enter-start="opacity-0 scale-95"
        x-transition:enter-end="opacity-100 scale-100"
        class="absolute start-0 top-full z-50 mt-1 w-56 rounded-xl border border-gray-200 bg-white p-1.5 shadow-lg ring-1 ring-black/5 dark:border-gray-800 dark:bg-gray-900"
        role="menu"
        @click="active = null"
    >
        {{ $slot }}
    </div>
</div>