Dropdown Component for main menu ~ Laravel/Breeze ~ Tailwind
Lavinia

Lavinia @laviku

About: I just love coding, Vegeta, and Juanes. Encuentra consejos y temas de programación y desarrollo en mi sitio web en español https://laviku.tech.

Location:
Nicaragua
Joined:
Nov 4, 2017

Dropdown Component for main menu ~ Laravel/Breeze ~ Tailwind

Publish Date: Jan 17 '21
25 3

Currently, I'm working on a project using Laravel, I haven't used Laravel since version 5, I think, also I stopped programming for about a year for different personal reasons.

The thing is that a lot of things have changed and one of them is that now Laravel has this package to manage the authentication process: Laravel/Breeze.

Puedes leer la versión en Español en mi blog.

I had some issues at the beginning because I didn't have the latest version of PHP, but after I solved them I was able to focus on the next steps. Tailwind is something really new for me and Laravel/Breeze is working with templates and styles using that library, but one thing that is missing is the "sub-menu" for the main links.

The menu has the option to have a drop-down for the user actions on the right side:
Laravel Breeze Menu

For the project I'm working on, I need to have a sub-menu for some of the main menu items:
Laravel Breeze with Menu and Sub Menu

Components

Following the same logic of the original components, I've created two components:

nav-link-parent.blade.php



@props(['active'])

@php
$classes = ($active ?? false)
            ? 'parent-nav inline-flex items-center px-1 pt-1 border-b-2 border-indigo-400 text-sm font-semibold leading-5 text-gray-900 focus:outline-none focus:border-indigo-700 transition duration-150 ease-in-out cursor-pointer relative'
            : 'parent-nav inline-flex items-center px-1 pt-1 border-b-2 border-transparent text-sm font-semibold leading-5 text-gray-500 hover:text-gray-700 hover:border-gray-300 focus:outline-none focus:text-gray-700 focus:border-gray-300 transition duration-150 ease-in-out cursor-pointer relative';
@endphp

<div x-data="{ open: false }" @click.away="open = false" @close.stop="open = false" @click="open = ! open" {{ $attributes->merge(['class' => $classes]) }} >
    <div>
        {{ $name }}

        <div class="ml-1 inline-block relative top-1">
            <svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
                <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd" />
            </svg>
        </div>
    </div>

    <div class="children border border-gray-300" 
    x-show="open"
    x-transition:enter="transition ease-out duration-200"
    x-transition:enter-start="transform opacity-0 scale-95"
    x-transition:enter-end="transform opacity-100 scale-100"
    x-transition:leave="transition ease-in duration-75"
    x-transition:leave-start="transform opacity-100 scale-100"
    x-transition:leave-end="transform opacity-0 scale-95">
        {{ $children }}
    </div>
</div>


Enter fullscreen mode Exit fullscreen mode

responsive-nav-link-parent.blade.php



@props(['active'])

@php
$classes = ($active ?? false)
? 'parent-nav inline-flex items-center px-1 pt-1 border-b-2 border-indigo-400 text-sm font-semibold leading-5 text-gray-900 focus:outline-none focus:border-indigo-700 transition duration-150 ease-in-out'
: 'parent-nav inline-flex items-center px-1 pt-1 border-b-2 border-transparent text-sm font-semibold leading-5 text-gray-500 hover:text-gray-700 hover:border-gray-300 focus:outline-none focus:text-gray-700 focus:border-gray-300 transition duration-150 ease-in-out';
@endphp

@props(['active'])

@php
$classes = ($active ?? false)
? 'parent-nav block pl-3 pr-4 py-2 border-l-4 border-indigo-400 text-base font-semibold text-indigo-700 bg-indigo-50 focus:outline-none focus:text-indigo-800 focus:bg-indigo-100 focus:border-indigo-700 transition duration-150 ease-in-out'
: 'parent-nav block pl-3 pr-4 py-2 border-l-4 border-transparent text-base font-semibold text-gray-600 hover:text-gray-800 hover:bg-gray-50 hover:border-gray-300 focus:outline-none focus:text-gray-800 focus:bg-gray-50 focus:border-gray-300 transition duration-150 ease-in-out';
@endphp

<div x-data="{ open: false }" @click.away="open = false" @close.stop="open = false" @click="open = ! open" {{ $attributes->merge(['class' => $classes]) }} >
<div>
{{ $name }}

    &lt;div class="ml-1 inline-block relative top-1"&gt;
        &lt;svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"&gt;
            &lt;path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd" /&gt;
        &lt;/svg&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;div class="children border border-gray-300 mt-3" 
x-show="open"
x-transition:enter="transition ease-out duration-200"
x-transition:enter-start="transform opacity-0 scale-95"
x-transition:enter-end="transform opacity-100 scale-100"
x-transition:leave="transition ease-in duration-75"
x-transition:leave-start="transform opacity-100 scale-100"
x-transition:leave-end="transform opacity-0 scale-95"&gt;
    {{ $children }}
&lt;/div&gt;
Enter fullscreen mode Exit fullscreen mode

</div>

Enter fullscreen mode Exit fullscreen mode




Style

Some CSS to set the right position for the elements.

app.css



.children {
background: #fff;
}

.children a,
.children .separator {
display: block;
margin: 5px 0px;
padding: 5px 10px;
}

.children .separator {
border-top-width: 2px;
}

.children a:hover {
color: #818cf8;
}

@media (min-width: 768px) {
.children {
position: absolute;
width: 155px;
top: 70px;
}
}

Enter fullscreen mode Exit fullscreen mode




Update the Navigation layout

And last I've updated the navigation layout and have added two slots: name and children

navigation.blade.php



...
<x-nav-link-parent :href="'#'" :active="request()->routeIs('padron.')">
<x-slot name="name">Option A</x-slot>
<x-slot name="children">
<a href="#">Item A</a>
<span class="separator"></span>
<a href="#">Item B</a>
<a href="#">Item C</a>
<span class="separator"></span>
<a href="#">Item D</a>
</x-slot>
</x-nav-link-parent>
...
<x-responsive-nav-link-parent :href="'#'" :active="request()->routeIs('padron.
')">
<x-slot name="name">Padrón</x-slot>
<x-slot name="children">
<a href="#">Buscador</a>
<span class="separator"></span>
<a href="#">Centros de votacion</a>
<a href="#">Juntas</a>
<span class="separator"></span>
<a href="#">Cartografia</a>
</x-slot>
</x-responsive-nav-link-parent>

Enter fullscreen mode Exit fullscreen mode




Final Result

Menu and Sub Menu

Menu and Sub Menu, Responsive version

Comments 3 total

  • Anthony Borrow, S.J.
    Anthony Borrow, S.J.Apr 10, 2021

    Thanks for sharing. I wanted to implement something like this using Jetstream. Currently, it appears the parent is not clickable as a link. I can see some advantages to this but also some limitations. Ideally, I would think that clicking on the arrow would allow the options to appear but clicking on the word would take you to the parent link.

  • Dio
    DioApr 14, 2021

    Thank for your sharing, helping me to learn tailwind

  • brodev23
    brodev23Oct 22, 2022

    Is tailwind working properly with laravel. terminology which i used Using Laravel Mix. some classes working but some are not. Tailwind is not working properly. Is all you faced the same problems.

    laravelTailwindissues #everyonefacing

Add comment