47. Cómo crear un menú responsivo con Tailwid y Alpine

En este capítulo, aprenderás cómo crear un menú responsivo para tu blog utilizando las herramientas de Tailwind y Alpine. Tailwind es un framework de CSS que te permite crear estilos personalizados de manera rápida y eficiente, mientras que Alpine es un framework de JavaScript que te permite agregar interacciones dinámicas a tu sitio web. Comenzaremos por comprender los conceptos fundamentales de Tailwind y Alpine, incluyendo cómo instalarlos y configurarlos en tu proyecto Laravel. Luego, te guiaremos a través del proceso de diseño y construcción de un menú responsivo utilizando clases de Tailwind y funciones de Alpine para proporcionar una experiencia de usuario fluida y agradable en cualquier dispositivo. También te mostraremos cómo personalizar el diseño y el comportamiento del menú para adaptarlo a tus necesidades específicas. ¡Aprovecha este capítulo para aprender cómo crear un menú responsivo impresionante para tu blog con Tailwind y Alpine!


6 comentarios

Inicia sesión para comentar

Comentarios:

  • Pablo Mendez

    Pablo Mendez hace 2 semanas

    Hola a todos para los que estamos siguiendo el curso con laravel 11 y el menu no es responsivo es por la directiva de livewire, la solucion que encontre es.

    php artisan vendor:publish --force --tag=livewire:assets

    guardamos cambios, corremos el comando en la terminal npm run dev

    y refrescamos la pagina y listo espero les sea de ayuda.

     

     

  • Alejandro Martinez

    Alejandro Martinez hace 9 meses

    Seguí este tutorial pero me pasa que cuando refresco la pagina aparece por unos segundos el menu del perfil, luego se oculta y funciona bien, pero en el video veo que eso no ocurre. lo mismo pasa con el menu mobile

  • Walter

    Walter hace 1 año

    ? 4° Damos funcionalidad al menú en la vista mobile

     

    Agregamos la propiedad x-data al nav:

     

    <nav class="bg-gray-800" x-data="{ open: false }">

     

    Agregamos la propiedad x-show al div del menú mobile:

     

    <!-- Mobile menu, show/hide based on menu state. -->
    <div class="sm:hidden" x-show="open">

     

    Agregamos la propiedad x-on al button del siguiente div:

     

    <!-- Mobile menu button-->
    <div class="absolute inset-y-0 left-0 flex items-center sm:hidden">
    	<button x-on:click="open = true" ...>

     

    Y agregamos la propiedad x-on al div del menú mobile:

     

    <!-- Mobile menu, show/hide based on menu state. -->
    <div class="sm:hidden" x-show="open" x-on:click.away="open = false">

     

  • Walter

    Walter hace 1 año

    ? 3° Damos funcionalidad a la barra de menú con Alpine

    Empezamos ocultando el menú de usuario cuando hacemos click en la foto de perfil.

    La forma en la que trabaja Alpine nos dice que primero debemos identificar la sección a la cual le queremos dar funcionalidad. Ubicamos el div padre y le agregamos la propiedad x-data para que Alpine lo considere un componente. En esta propiedad definimos variables en forma de objeto:

     

    <!-- Profile dropdown -->
    <div class="ml-3 relative" x-data="{ open: false }"> ...
    </div>

     

    Le pasamos el valor de la variable open al div que queremos ocultar con la propiedad x-show:

    <div x-show="open" class="..."> ...
    </div>

     

    Pasamos el evento click al botón con la imagen de perfil:

    <!-- Profile dropdown -->
    <div class="ml-3 relative" x-data="{ open: false }">
    	<div>
    		<button x-on:click="open = true" class="...">
    			<span class="sr-only">Open user menu</span>
    			<img class="h-8 w-8 rounded-full" src="...">
    		</button>
    	</div>
    </div>

     

  • Walter

    Walter hace 1 año

    ? 2° Aplicamos el código de tailwindui.com a la vista navigation.blade.php

     

    <nav class="bg-gray-800">
      <div class="mx-auto max-w-7xl px-2 sm:px-6 lg:px-8">
        <div class="relative flex h-16 items-center justify-between">
          <!-- Mobile menu button-->
          <div class="absolute inset-y-0 left-0 flex items-center sm:hidden">
            <button
              type="button"
              class="inline-flex items-center justify-center rounded-md p-2 text-gray-400 hover:bg-gray-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white"
              aria-controls="mobile-menu"
              aria-expanded="false">
              <span class="sr-only">Open main menu</span>
              <!--
              Icon when menu is closed.
              Heroicon name: outline/bars-3
              Menu open: "hidden", Menu closed: "block"
              -->
              <svg
                class="block h-6 w-6"
                xmlns="http://www.w3.org/2000/svg"
                fill="none"
                viewBox="0 0 24 24"
                stroke-width="1.5"
                stroke="currentColor"
                aria-hidden="true">
                <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
              </svg>
              <!--
              Icon when menu is open.
              Heroicon name: outline/x-mark
              Menu open: "block", Menu closed: "hidden"
              -->
              <svg
                class="hidden h-6 w-6"
                xmlns="http://www.w3.org/2000/svg"
                fill="none"
                viewBox="0 0 24 24"
                stroke-width="1.5"
                stroke="currentColor"
                aria-hidden="true">
                <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
              </svg>
            </button>
          </div>
    
          <div class="flex flex-1 items-center justify-center sm:items-stretch sm:justify-start">
            {{-- logotipo --}}
            <div class="flex flex-shrink-0 items-center">
              <img
                class="block h-8 w-auto lg:hidden"
                src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=500"
                alt="Your Company"
              >
              <img
                class="hidden h-8 w-auto lg:block"
                src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=500"
                alt="Your Company"
              >
            </div>
            {{-- Menu large --}}
            <div class="hidden sm:ml-6 sm:block">
              <div class="flex space-x-4">
                <!-- Current: "bg-gray-900 text-white", Default: "text-gray-300 hover:bg-gray-700 hover:text-white" -->
                <a
                  href="#"
                  class="bg-gray-900 text-white px-3 py-2 rounded-md text-sm font-medium"
                  aria-current="page"
                >Dashboard</a>
                <a
                  href="#"
                  class="text-gray-300 hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium"
                >Team</a>
                <a
                  href="#"
                  class="text-gray-300 hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium"
                >Projects</a>
                <a
                  href="#"
                  class="text-gray-300 hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium"
                >Calendar</a>
              </div>
            </div>
          </div>
    
          <div class="absolute inset-y-0 right-0 flex items-center pr-2 sm:static sm:inset-auto sm:ml-6 sm:pr-0">
            {{-- botón notificaciones --}}
            <button
              type="button"
              class="rounded-full bg-gray-800 p-1 text-gray-400 hover:text-white focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-gray-800">
              <span class="sr-only">View notifications</span>
              <!-- Heroicon name: outline/bell -->
              <svg
                class="h-6 w-6"
                xmlns="http://www.w3.org/2000/svg"
                fill="none"
                viewBox="0 0 24 24"
                stroke-width="1.5"
                stroke="currentColor"
                aria-hidden="true">
                <path
                  stroke-linecap="round"
                  stroke-linejoin="round"
                  d="M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0" />
              </svg>
            </button>
            <!-- Profile dropdown -->
            <div class="relative ml-3">
              <div>
                <button
                  type="button"
                  class="flex rounded-full bg-gray-800 text-sm focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-gray-800"
                  id="user-menu-button"
                  aria-expanded="false"
                  aria-haspopup="true">
                  <span class="sr-only">Open user menu</span>
                  <img
                    class="h-8 w-8 rounded-full"
                    src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
                    alt=""
                  >
                </button>
              </div>
              <!--
              Dropdown menu, show/hide based on menu state.
              Entering: "transition ease-out duration-100"
              From: "transform opacity-0 scale-95"
              To: "transform opacity-100 scale-100"
              Leaving: "transition ease-in duration-75"
              From: "transform opacity-100 scale-100"
              To: "transform opacity-0 scale-95"
              -->
              <div
                class="absolute right-0 z-10 mt-2 w-48 origin-top-right rounded-md bg-white py-1 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none"
                role="menu"
                aria-orientation="vertical"
                aria-labelledby="user-menu-button"
                tabindex="-1">
                <!-- Active: "bg-gray-100", Not Active: "" -->
                <a
                  href="#"
                  class="block px-4 py-2 text-sm text-gray-700"
                  role="menuitem"
                  tabindex="-1"
                  id="user-menu-item-0"
                >Your Profile</a>
                <a
                  href="#"
                  class="block px-4 py-2 text-sm text-gray-700"
                  role="menuitem"
                  tabindex="-1"
                  id="user-menu-item-1"
                >Settings</a>
                <a
                  href="#"
                  class="block px-4 py-2 text-sm text-gray-700"
                  role="menuitem"
                  tabindex="-1"
                  id="user-menu-item-2"
                >Sign out</a>
              </div>
            </div>
          </div>
    
        </div>
      </div>
    
      <!-- Mobile menu, show/hide based on menu state. -->
      <div class="sm:hidden" id="mobile-menu">
        <div class="space-y-1 px-2 pt-2 pb-3">
          <!-- Current: "bg-gray-900 text-white", Default: "text-gray-300 hover:bg-gray-700 hover:text-white" -->
          <a
            href="#"
            class="bg-gray-900 text-white block px-3 py-2 rounded-md text-base font-medium"
            aria-current="page"
          >Dashboard</a>
          <a
            href="#"
            class="text-gray-300 hover:bg-gray-700 hover:text-white block px-3 py-2 rounded-md text-base font-medium"
          >Team</a>
          <a
            href="#"
            class="text-gray-300 hover:bg-gray-700 hover:text-white block px-3 py-2 rounded-md text-base font-medium"
          >Projects</a>
          <a
            href="#"
            class="text-gray-300 hover:bg-gray-700 hover:text-white block px-3 py-2 rounded-md text-base font-medium"
          >Calendar</a>
        </div>
      </div>
    
    </nav>

     

  • Walter

    Walter hace 1 año

    ? 1° Creamos un componente de Livewire

     

    php artisan make:livewire navigation

     

    Este comando nos crea dos archivos:

    • /app/Http/Livewire/Navigation.php (CLASE)
    • /resources/views/livewire/navigation.blade.php (VISTA)

     

    ? Actualizamos el body de la plantilla /resources/views/layouts/app.blade.php:

     

    <x-jet-banner />
    
    <div class="min-h-screen bg-gray-100">
    
    	@livewire('navigation')
    
    	<!-- Page Content -->
    	<main>
    		{{ $slot }}
    	</main>
    </div>
    
    @stack('modals')
    
    @livewireScripts