S SmartDocs
系列: vibe coding javascript 66 行 · 更新于 2026-04-26

Navbar.jsx

vibe_coding/src/components/Navbar.jsx

import { useEffect, useState } from 'react';
import { NavLink, Link, useLocation } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import LanguageSwitcher from './LanguageSwitcher.jsx';

export default function Navbar() {
  const { t } = useTranslation();
  const [scrolled, setScrolled] = useState(false);
  const [open, setOpen] = useState(false);
  const location = useLocation();

  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 40);
    onScroll();
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);

  useEffect(() => {
    setOpen(false);
  }, [location.pathname]);

  const isHome = location.pathname === '/';

  return (
    <header className={`navbar ${scrolled || !isHome ? 'scrolled' : ''}`}>
      <div className="navbar__inner">
        <Link to="/" className="navbar__logo">
          {t('brand.name')}
        </Link>

        <nav>
          <ul className={`navbar__links ${open ? 'open' : ''}`}>
            <li>
              <NavLink to="/proyectos">{t('nav.projects')}</NavLink>
            </li>
            <li>
              <NavLink to="/sobre-mi">{t('nav.about')}</NavLink>
            </li>
            <li>
              <NavLink to="/cv">{t('nav.cv')}</NavLink>
            </li>
            <li>
              <NavLink to="/contacto">{t('nav.contact')}</NavLink>
            </li>
            <li>
              <LanguageSwitcher />
            </li>
          </ul>
        </nav>

        <button
          type="button"
          className="navbar__toggle"
          aria-label="Toggle menu"
          aria-expanded={open}
          onClick={() => setOpen((v) => !v)}
        >
          <span />
          <span />
          <span />
        </button>
      </div>
    </header>
  );
}

相关文章