Przejdź do treści

Navigation Menu

Stabilny

Główna nawigacja witryny z rozbudowanymi, animowanymi panelami — dla stron marketingowych i dokumentacji, w których każda sekcja potrzebuje czegoś więcej niż jednego linku.

Instalacja

$ pnpm dlx shadcn@latest add https://www.prfct.dev/r/navigation-menu.json

Użycie

import Link from "next/link"

import {
  NavigationMenu,
  NavigationMenuContent,
  NavigationMenuItem,
  NavigationMenuLink,
  NavigationMenuList,
  NavigationMenuTrigger,
  navigationMenuTriggerStyle,
} from "@/components/ui/navigation-menu"
<NavigationMenu>
  <NavigationMenuList>
    <NavigationMenuItem>
      <NavigationMenuTrigger>Products</NavigationMenuTrigger>
      <NavigationMenuContent>
        <NavigationMenuLink render={<Link href="/analytics" />}>
          Analytics
        </NavigationMenuLink>
      </NavigationMenuContent>
    </NavigationMenuItem>
    <NavigationMenuItem>
      <NavigationMenuLink
        render={<Link href="/pricing" />}
        className={navigationMenuTriggerStyle()}
      >
        Pricing
      </NavigationMenuLink>
    </NavigationMenuItem>
  </NavigationMenuList>
</NavigationMenu>

Wszystkie panele dzielą jeden popup. Gdy użytkownik przechodzi od jednego wyzwalacza do kolejnego, popup płynnie dopasowuje się do rozmiaru nowego panelu, a treść wsuwa się z kierunku ruchu — to wyraźna wskazówka przestrzenna, że przegląda elementy tego samego poziomu, a nie otwiera czegoś nowego.

Przykłady

Łącz wyzwalacze otwierające panele ze zwykłymi linkami ostylowanymi przez navigationMenuTriggerStyle() — dzięki temu każdy element paska wygląda i zachowuje się spójnie.

Dwukolumnowa lista miejsc docelowych, każde z ikoną i jednowierszowym opisem. To opisy robią tu najwięcej: pozwalają wybrać bez przeklikiwania się przez kolejne strony.

Zarezerwuj boczną kolumnę panelu na jedną aktualną pozycję — premierę, poradnik, wydarzenie. Jedno wyróżnienie na panel; dwa zaczną ze sobą konkurować.

Gdy nie ma paneli, menu jest ostylowaną listą linków z wędrującym fokusem (roving focus). Bieżącą sekcję oznacz propem active — ustawia on aria-current="page" i styl aktywnego elementu.

Wytyczne

Kiedy używać

  • Jako główna nawigacja stron marketingowych i dokumentacji z kilkoma sekcjami najwyższego poziomu.
  • Gdy sekcja potrzebuje drogowskazów — opisów, grupowania albo wyróżnionej pozycji — zanim użytkownik zdecyduje, dokąd przejść.

Kiedy nie używać

  • Do nawigacji w aplikacji z wieloma miejscami docelowymi lub głęboką hierarchią — użyj Sidebar.
  • Do poleceń i akcji — użyj Dropdown Menu lub Menubar. Menu nawigacyjne zawiera wyłącznie linki.
  • Na małych ekranach — poniżej md zwiń nawigację do prostej listy w panelu Sheet.

Zawartość panelu

Trzymaj się pięciu–siedmiu pozycji najwyższego poziomu. Każdy link w panelu dostaje krótki tytuł i najlepiej jednowierszowy opis w formie zwykłego zdania — z tą samą interpunkcją w całym panelu. Długie panele podziel na kolumny powiązanych linków i nie chowaj niczego ważnego wyłącznie w panelu — to samo miejsce powinno być osiągalne także z samej strony albo ze stopki.

AnalitykaŚledź wykorzystanie w czasie rzeczywistym
AutomatyzacjeProcesy, które działają same
Dobrze.Tytuły, które użytkownicy rozpoznają, i opisy, które pomagają wybrać.
Pulse
Flow Engine X
Nimbus
Źle.Marketingowe nazwy bez kontekstu zmuszają do klikania, żeby sprawdzić, co się za nimi kryje.

Najechanie i kliknięcie

Panele otwierają się po kliknięciu oraz po najechaniu, z krótkim opóźnieniem delay (50 ms). Popup i wyzwalacz łączy niewidoczny mostek, więc kursor może przejść po skosie do panelu, nie zamykając go. Nigdy nie umieszczaj celu nawigacji na samym wyzwalaczu — wyzwalacz tylko otwiera swój panel; strona przeglądowa sekcji należy do panelu jako jego pierwszy link.

Dostępność

Navigation Menu renderuje element <nav> z listą pozycji. Wyzwalacze to przyciski z aria-expanded; panele to rozwijana treść, a nie menu — do linków w środku przechodzi się klawiszem Tab, tak samo jak na stronie.

KlawiszDziałanie
Tab
Przechodzi między wyzwalaczami i linkami, a także do linków otwartego panelu.
Przenosi fokus między wyzwalaczami i linkami najwyższego poziomu.
EnterSpacja
Otwiera lub zamyka panel wyzwalacza, na którym jest fokus; na linku przechodzi pod jego adres.
Na wyzwalaczu otwiera jego panel i przenosi do niego fokus.
Esc
Zamyka panel i przywraca fokus na jego wyzwalacz.
  • Bieżąca strona. Przekaż active do linku bieżącej strony lub sekcji — technologie wspomagające dostaną tę informację jako aria-current="page".
  • Nazwij każdą nawigację. Jeśli strona ma więcej niż jeden <nav>, nadaj każdemu aria-label (Główna, Stopka), aby użytkownicy czytników ekranu mogli je rozróżnić.

Dokumentacja API

Główny element <nav>. Przyjmuje wszystkie propsy NavigationMenu.Root z Base UI.

PropTypDomyślnie
value

Kontrolowana wartość otwartej pozycji. Wartość inna niż null oznacza, że panel jest otwarty.

anynull
defaultValue

Pozycja otwarta na starcie, gdy menu jest niekontrolowane.

anynull
onValueChange

Wywoływana, gdy zmienia się otwarta pozycja.

(value: any, details) => voidBrak wartości domyślnej
delay

Opóźnienie otwarcia panelu po najechaniu, w ms.

number50
closeDelay

Opóźnienie zamknięcia po opuszczeniu menu przez kursor, w ms.

number50
orientation

Układ i kierunek nawigacji strzałkami.

"horizontal" | "vertical""horizontal"
align

Wyrównanie wspólnego popupu względem aktywnego wyzwalacza.

"start" | "center" | "end""start"
PropTypDomyślnie
value

Identyfikuje pozycję w trybie kontrolowanym. Jeśli go pominiesz, zostanie wygenerowany.

anyBrak wartości domyślnej

Otwiera panel swojej pozycji. Renderuje strzałkę, która obraca się, gdy panel jest otwarty. Przyjmuje disabled.

Panel pozycji. Jego rozmiar ustal, nadając szerokość pierwszemu elementowi potomnemu; popup animuje przejścia między rozmiarami paneli.

PropTypDomyślnie
keepMounted

Zachowuje treść zamkniętego panelu w DOM, aby roboty wyszukiwarek mogły indeksować jego linki.

booleanfalse
PropTypDomyślnie
active

Oznacza bieżącą stronę: ustawia aria-current i styl aktywnego elementu.

booleanfalse
closeOnClick

Zamyka otwarty panel po kliknięciu linku.

booleanfalse
render

Renderuje link frameworka, np. <Link href="/pricing" />.

ReactElement | (props, state) => ReactElementBrak wartości domyślnej

Generator klas, dzięki któremu zwykły NavigationMenuLink wygląda dokładnie jak wyzwalacz. Przyjmuje { className }, aby rozszerzyć style.