Navbar.svelte 9.65 KB
<script>
  import { onMount } from 'svelte';

  let { onOpenDrawer = () => {}, onOpenSearch = () => {} } = $props();

  let isDark = $state(false);
  let isMac = $state(false);

  function toggleTheme() {
    isDark = !isDark;
    document.documentElement.classList.toggle('dark', isDark);
    localStorage.setItem('theme', isDark ? 'dark' : 'light');
  }

  onMount(() => {
    // Detect Mac for keyboard shortcut display
    isMac = /Mac|iPod|iPhone|iPad/.test(navigator.platform);

    // Read actual state from document (set by app.html)
    isDark = document.documentElement.classList.contains('dark');

    // Listen for theme changes (e.g., from drawer on mobile)
    const observer = new MutationObserver(() => {
      isDark = document.documentElement.classList.contains('dark');
    });
    observer.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ['class']
    });

    return () => observer.disconnect();
  });
</script>

<!-- MÓVIL: Búsqueda + Theme + hamburguesa arriba a la derecha -->
<div class="navbar-mobile">
  <button
    onclick={onOpenSearch}
    class="nav-btn-icon-mobile"
    aria-label="Buscar"
  >
    <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2" stroke-linecap="round">
      <circle cx="11" cy="11" r="8"/>
      <path d="m21 21-4.3-4.3"/>
    </svg>
  </button>
  <button
    onclick={toggleTheme}
    class="nav-btn-icon-mobile"
    aria-label={isDark ? 'Cambiar a modo claro' : 'Cambiar a modo oscuro'}
  >
    {#if isDark}
      <svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
        <path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z"/>
      </svg>
    {:else}
      <svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
        <path fill-rule="evenodd" d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z" clip-rule="evenodd"/>
      </svg>
    {/if}
  </button>
  <button
    onclick={onOpenDrawer}
    class="nav-btn-icon-mobile"
    aria-label="Abrir menú"
  >
    <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2">
      <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5"/>
    </svg>
  </button>
</div>

<!-- DESKTOP: Barra completa con Search + Theme + Menu -->
<div class="navbar-desktop">
  <div class="navbar-desktop-inner">

    <!-- BOTÓN BÚSQUEDA GLOBAL -->
    <div class="relative group/search">
      <button
        onclick={onOpenSearch}
        class="nav-search-btn"
        aria-label="Buscar"
      >
        <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2" stroke-linecap="round">
          <circle cx="11" cy="11" r="8"/>
          <path d="m21 21-4.3-4.3"/>
        </svg>
        <span class="nav-search-shortcut">
          <kbd>{isMac ? '\u2318' : 'Ctrl'}</kbd>
          <kbd>K</kbd>
        </span>
      </button>
      <!-- Tooltip -->
      <div class="absolute right-0 top-full mt-2 px-3 py-1.5 bg-gray-900/90 text-white text-xs rounded-lg whitespace-nowrap opacity-0 invisible group-hover/search:opacity-100 group-hover/search:visible transition-all duration-200 pointer-events-none backdrop-blur-sm">
        Buscar
        <div class="absolute right-3 bottom-full mb-[-4px] w-2 h-2 bg-gray-900/90 rotate-45"></div>
      </div>
    </div>

    <!-- BOTÓN THEME TOGGLE (Sol/Luna) -->
    <div class="relative group/theme">
      <button
        onclick={toggleTheme}
        class="nav-btn-icon"
        aria-label={isDark ? 'Cambiar a modo claro' : 'Cambiar a modo oscuro'}
      >
        {#if isDark}
          <svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
            <path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z"/>
          </svg>
        {:else}
          <svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
            <path fill-rule="evenodd" d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z" clip-rule="evenodd"/>
          </svg>
        {/if}
      </button>
      <!-- Tooltip -->
      <div class="absolute right-0 top-full mt-2 px-3 py-1.5 bg-gray-900/90 text-white text-xs rounded-lg whitespace-nowrap opacity-0 invisible group-hover/theme:opacity-100 group-hover/theme:visible transition-all duration-200 pointer-events-none backdrop-blur-sm">
        {isDark ? 'Cambiar a modo claro' : 'Cambiar a modo oscuro'}
        <div class="absolute right-3 bottom-full mb-[-4px] w-2 h-2 bg-gray-900/90 rotate-45"></div>
      </div>
    </div>

    <!-- BOTÓN MENÚ HAMBURGUESA -->
    <div class="relative group/menu">
      <button
        onclick={onOpenDrawer}
        class="nav-btn-icon"
        aria-label="Abrir menú"
      >
        <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2">
          <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5"/>
        </svg>
      </button>
      <!-- Tooltip -->
      <div class="absolute right-0 top-full mt-2 px-3 py-1.5 bg-gray-900/90 text-white text-xs rounded-lg whitespace-nowrap opacity-0 invisible group-hover/menu:opacity-100 group-hover/menu:visible transition-all duration-200 pointer-events-none backdrop-blur-sm">
        Menú
        <div class="absolute right-3 bottom-full mb-[-4px] w-2 h-2 bg-gray-900/90 rotate-45"></div>
      </div>
    </div>

  </div>
</div>

<style>
  /* Responsive navbar containers */
  .navbar-mobile {
    display: flex;
    position: fixed;
    top: 1rem;
    right: 1rem;
    z-index: 110;
    align-items: center;
    gap: 0.25rem;
  }

  .navbar-desktop {
    display: none;
    position: fixed;
    top: 1.5rem;
    right: 1.5rem;
    z-index: 110;
  }

  .navbar-desktop-inner {
    display: flex;
    align-items: center;
    gap: 0.25rem;
  }

  @media (min-width: 768px) {
    .navbar-mobile {
      display: none;
    }
    .navbar-desktop {
      display: flex;
    }
  }

  /* Iconos del navbar */
  .nav-icon {
    background-color: transparent;
    color: #8A8578;
    transition: color 0.2s ease;
  }
  .nav-icon:hover {
    color: #F5F0E8;
  }

  /* Modo claro */
  :global(html:not(.dark)) .nav-icon {
    color: #333333;
  }
  :global(html:not(.dark)) .nav-icon:hover {
    color: #1A1A18;
  }

  /* Search button */
  .nav-search-btn {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 7px 12px 7px 12px;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 10px;
    color: #9B9890;
    cursor: pointer;
    transition: all 0.2s ease;
  }

  .nav-search-btn:hover {
    background: rgba(255, 255, 255, 0.1);
    border-color: rgba(201, 167, 81, 0.4);
    color: #F5F0E8;
  }

  .nav-search-shortcut {
    display: flex;
    gap: 4px;
  }

  .nav-search-shortcut kbd {
    font-family: system-ui, -apple-system, sans-serif;
    font-size: 11px;
    font-weight: 500;
    padding: 3px 7px;
    background: #2a2a2a;
    border: 1px solid #444;
    border-radius: 5px;
    color: #aaa;
    box-shadow: 0 1px 2px rgba(0,0,0,0.3), inset 0 1px 0 rgba(255,255,255,0.05);
    line-height: 1;
  }

  /* Modo claro */
  :global(html:not(.dark)) .nav-search-btn {
    background: rgba(0, 0, 0, 0.04);
    border-color: rgba(0, 0, 0, 0.12);
    color: #666;
  }

  :global(html:not(.dark)) .nav-search-btn:hover {
    background: rgba(0, 0, 0, 0.08);
    border-color: rgba(201, 167, 81, 0.5);
    color: #1A1A18;
  }

  /* Icon buttons (theme, menu) */
  .nav-btn-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 8px;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 10px;
    color: #9B9890;
    cursor: pointer;
    transition: all 0.2s ease;
  }

  .nav-btn-icon:hover {
    background: rgba(255, 255, 255, 0.1);
    border-color: rgba(201, 167, 81, 0.4);
    color: #F5F0E8;
  }

  :global(html:not(.dark)) .nav-btn-icon {
    background: rgba(0, 0, 0, 0.04);
    border-color: rgba(0, 0, 0, 0.12);
    color: #666;
  }

  :global(html:not(.dark)) .nav-btn-icon:hover {
    background: rgba(0, 0, 0, 0.08);
    border-color: rgba(201, 167, 81, 0.5);
    color: #1A1A18;
  }

  :global(html:not(.dark)) .nav-search-shortcut kbd {
    background: #f5f5f5;
    border-color: #d0d0d0;
    color: #666;
    box-shadow: 0 1px 2px rgba(0,0,0,0.1), inset 0 1px 0 rgba(255,255,255,0.8);
  }

  /* Mobile icon buttons */
  .nav-btn-icon-mobile {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 8px;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 8px;
    color: #9B9890;
    cursor: pointer;
    transition: all 0.2s ease;
  }

  :global(html:not(.dark)) .nav-btn-icon-mobile {
    background: rgba(0, 0, 0, 0.04);
    border-color: rgba(0, 0, 0, 0.12);
    color: #666;
  }
</style>