PhiaUi.Components.NavigationMenu (phia_ui v0.1.17)

Copy Markdown View Source

Horizontal navigation menu with optional dropdown panels.

A fully accessible horizontal navigation bar following the WAI-ARIA navigation landmark pattern. Supports both simple link items and trigger-plus-content dropdown panels. CSS-only layout — no JavaScript hook is required for static dropdowns; use server-side assigns to toggle panel visibility when needed.

Sub-components

ComponentElementPurpose
navigation_menu/1<nav>Root landmark with aria-label="Main navigation"
navigation_menu_list/1<ul>Horizontal flex list of items
navigation_menu_item/1<li>Container for a link or trigger+content pair
navigation_menu_link/1<a>Styled link with active-state highlight
navigation_menu_trigger/1<button>Dropdown toggle button with chevron icon
navigation_menu_content/1<div>Absolutely-positioned dropdown panel
<.navigation_menu>
  <.navigation_menu_list>
    <.navigation_menu_item>
      <.navigation_menu_link href="/" active={@current_path == "/"}>
        Home
      </.navigation_menu_link>
    </.navigation_menu_item>
    <.navigation_menu_item>
      <.navigation_menu_link href="/pricing" active={@current_path == "/pricing"}>
        Pricing
      </.navigation_menu_link>
    </.navigation_menu_item>
    <.navigation_menu_item>
      <.navigation_menu_link href="/contact" active={@current_path == "/contact"}>
        Contact
      </.navigation_menu_link>
    </.navigation_menu_item>
  </.navigation_menu_list>
</.navigation_menu>

With a dropdown panel

Pair navigation_menu_trigger/1 and navigation_menu_content/1 inside the same navigation_menu_item/1. The content panel is positioned absolutely below the item:

<.navigation_menu>
  <.navigation_menu_list>
    <.navigation_menu_item>
      <.navigation_menu_link href="/" active={@current_path == "/"}>Home</.navigation_menu_link>
    </.navigation_menu_item>

    <.navigation_menu_item>
      <.navigation_menu_trigger label="Products" />
      <.navigation_menu_content>
        <ul class="grid grid-cols-2 gap-3 p-4 w-[400px]">
          <li>
            <a href="/products/web" class="block rounded-md p-3 hover:bg-accent">
              <p class="font-medium">Web Platform</p>
              <p class="text-sm text-muted-foreground">Build scalable web apps</p>
            </a>
          </li>
          <li>
            <a href="/products/mobile" class="block rounded-md p-3 hover:bg-accent">
              <p class="font-medium">Mobile SDK</p>
              <p class="text-sm text-muted-foreground">Native iOS and Android</p>
            </a>
          </li>
        </ul>
      </.navigation_menu_content>
    </.navigation_menu_item>

    <.navigation_menu_item>
      <.navigation_menu_link href="/docs">Docs</.navigation_menu_link>
    </.navigation_menu_item>
  </.navigation_menu_list>
</.navigation_menu>

Marking the current page

Pass active={true} to navigation_menu_link/1 for the item matching the current route. In a LiveView, compare against @current_path or use the route helpers:

active={URI.parse(@current_url).path == "/pricing"}

Accessibility

  • The <nav> root has aria-label="Main navigation" to distinguish it from other navigation landmarks (e.g. breadcrumb, pagination).
  • Active links carry aria-current="page" so screen readers announce the current location.
  • Trigger buttons carry aria-haspopup="true" and aria-expanded="false" to communicate dropdown availability to assistive technologies.

Summary

Functions

Renders the navigation menu root <nav> element.

Renders the dropdown content panel for a trigger.

Renders a single navigation menu item.

Renders a styled navigation link.

Renders the horizontal menu list.

Renders a trigger button that opens a dropdown navigation panel.

Functions