Dropdown Component for main menu ~ Laravel/Breeze ~ Tailwind
Tags: laravel, breeze, tailwindcss
Published: 2021-01-17 03:41:59

---
title: Dropdown Component for main menu ~ Laravel/Breeze ~ Tailwind
published: true
description: When using Laravel/Breeze the template for the navigation does not have the option for a sub-menu for the main links. 
tags: laravel, breeze, tailwind
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/vz9zz5ku3mxlg5ze6ooz.png
---

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](https://laravel.com/docs/8.x/starter-kits#laravel-breeze). 

> Puedes leer la versión en Español en mi [blog](https://laviku.tech/componente-para-sub-menu-laravel-breeze-tailwind/). 

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](https://dev-to-uploads.s3.amazonaws.com/i/937h7timucgpkaz1wn5a.jpg)

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](https://dev-to-uploads.s3.amazonaws.com/i/841hsh7n8xjg9vjdgitn.jpg)

### 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>
```

**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 }}

        <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 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">
        {{ $children }}
    </div>
</div>
```

### 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;
    }
}
```

### 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>
```

### Final Result

![Menu and Sub Menu](https://dev-to-uploads.s3.amazonaws.com/i/mpk33ddaj65xzko2tmu7.jpg)

![Menu and Sub Menu, Responsive version](https://dev-to-uploads.s3.amazonaws.com/i/glyvwh0da1m9o3hn5tzk.jpg)