● Zion Boggan
repos/Stepping App/apps/web/src/components/mobile-nav.tsx
zionboggan.com ↗
90 lines · tsx
History for this file →
1
"use client";
2
 
3
import { useEffect, useState } from "react";
4
import Link from "next/link";
5
import { Wordmark } from "@/components/wordmark";
6
 
7
const LINKS = [
8
  { href: "#sets", label: "The Sets", index: "01" },
9
  { href: "#floor", label: "The Floor", index: "02" },
10
  { href: "#road", label: "The Road", index: "03" },
11
];
12
 
13
export function MobileNav() {
14
  const [open, setOpen] = useState(false);
15
 
16
  useEffect(() => {
17
    if (!open) return;
18
    const onKey = (e: KeyboardEvent) => {
19
      if (e.key === "Escape") setOpen(false);
20
    };
21
    document.documentElement.style.overflow = "hidden";
22
    window.addEventListener("keydown", onKey);
23
    return () => {
24
      document.documentElement.style.overflow = "";
25
      window.removeEventListener("keydown", onKey);
26
    };
27
  }, [open]);
28
 
29
  return (
30
    <div className="sm:hidden">
31
      <button
32
        type="button"
33
        aria-label="Open menu"
34
        aria-expanded={open}
35
        onClick={() => setOpen(true)}
36
        className="mobile-nav-trigger flex h-12 w-12 flex-col items-end justify-center gap-[6px] text-gold"
37
      >
38
        <span className="block h-[2px] w-7 bg-gold" />
39
        <span className="block h-[2px] w-7 bg-gold" />
40
        <span className="block h-[2px] w-5 bg-gold" />
41
      </button>
42
 
43
      {open && (
44
        <div className="mobile-nav-sheet fixed inset-0 z-[70] flex flex-col bg-stage px-5 pb-12 pt-4">
45
          <div className="flex items-center justify-between">
46
            <span className="text-lg">
47
              <Wordmark />
48
            </span>
49
            <button
50
              type="button"
51
              aria-label="Close menu"
52
              onClick={() => setOpen(false)}
53
              className="flex h-12 w-12 items-center justify-center text-gold"
54
            >
55
              <span className="display text-3xl leading-none">×</span>
56
            </button>
57
          </div>
58
 
59
          <nav className="mt-16 flex flex-1 flex-col justify-center gap-2">
60
            {LINKS.map((l) => (
61
              <a
62
                key={l.href}
63
                href={l.href}
64
                onClick={() => setOpen(false)}
65
                className="group flex items-baseline gap-5 border-b border-[var(--line)] py-6"
66
              >
67
                <span className="kicker text-gold">{l.index}</span>
68
                <span className="display text-5xl text-bone group-active:text-gold">
69
                  {l.label}
70
                </span>
71
              </a>
72
            ))}
73
            <Link
74
              href="/about"
75
              onClick={() => setOpen(false)}
76
              className="group flex items-baseline gap-5 border-b border-[var(--line)] py-6"
77
            >
78
              <span className="kicker text-gold">04</span>
79
              <span className="display text-5xl text-bone group-active:text-gold">
80
                About
81
              </span>
82
            </Link>
83
          </nav>
84
 
85
          <p className="kicker mt-8 text-ash">Chicago Stepping. Your City.</p>
86
        </div>
87
      )}
88
    </div>
89
  );
90
}