Navigation Menu

v0.0.10

v0.0.10StableHeadlessStatelessAccessibleJSApache-2.0
Installation mix mishka.ui.gen.headless navigation_menu
Source View Source

Overview of the Phoenix and LiveView Headless Navigation Menu Component

The Mishka Chelekom Headless Navigation Menu ships zero opinionated styling - only the semantic markup and full WAI-ARIA wiring. Every :item with body content gets a trigger and a hidden stored content panel; a single shared positioner to popup to viewport is rendered once and the engine moves the active item's content into it, morphing the popup's width and height and sliding the content via data-activation-direction. Hover opens after a configurable delay; label-only or href items render a plain link. Every part - list, item, link, trigger, icon, content, positioner, popup, viewport and arrow - is addressable through a *_class attribute, so you style it entirely with your own Tailwind classes while the accessibility and behavior keep working underneath.

Base UI Navigation Menu example - hero (Phoenix headless)

heex
<.navigation_menu
  id="baseui-navigation_menu-hero"
  style="--duration: 0.35s; --easing: cubic-bezier(0.22, 1, 0.36, 1);"
  class="min-w-max text-neutral-950 dark:text-white"
  list_class="relative flex gap-px"
  trigger_class="flex h-8 items-center justify-center gap-1.5 bg-transparent px-2 text-sm font-normal text-neutral-950 no-underline select-none min-[501px]:px-3 hover:bg-neutral-100 data-[popup-open]:bg-neutral-100 focus-visible:outline-2 focus-visible:-outline-offset-1 focus-visible:outline-neutral-950 dark:focus-visible:outline-white dark:text-white dark:hover:bg-neutral-800 dark:data-[popup-open]:bg-neutral-800"
  link_class="flex h-8 items-center justify-center gap-1.5 bg-transparent px-2 text-sm font-normal text-neutral-950 no-underline select-none min-[501px]:px-3 hover:bg-neutral-100 data-[popup-open]:bg-neutral-100 focus-visible:outline-2 focus-visible:-outline-offset-1 focus-visible:outline-neutral-950 dark:focus-visible:outline-white dark:text-white dark:hover:bg-neutral-800 dark:data-[popup-open]:bg-neutral-800"
  icon_class="transition-transform duration-200 ease-[ease] data-[open]:rotate-180"
  positioner_class="h-[var(--positioner-height)] w-[var(--positioner-width)] max-w-[var(--available-width)] transition-[top,left,right,bottom] duration-[var(--duration)] ease-[var(--easing)] before:absolute before:content-[''] data-[instant]:transition-none data-[side=bottom]:before:top-[-10px] data-[side=bottom]:before:right-0 data-[side=bottom]:before:left-0 data-[side=bottom]:before:h-2.5 data-[side=left]:before:top-0 data-[side=left]:before:right-[-10px] data-[side=left]:before:bottom-0 data-[side=left]:before:w-2.5 data-[side=right]:before:top-0 data-[side=right]:before:bottom-0 data-[side=right]:before:left-[-10px] data-[side=right]:before:w-2.5 data-[side=top]:before:right-0 data-[side=top]:before:bottom-[-10px] data-[side=top]:before:left-0 data-[side=top]:before:h-2.5"
  popup_class="relative h-[var(--popup-height)] w-[var(--popup-width)] origin-[var(--transform-origin)] border border-neutral-950 bg-white text-neutral-950 shadow-[0.25rem_0.25rem_0] shadow-black/12 outline-none transition-[opacity,transform,width,height,scale] duration-[var(--duration)] ease-[var(--easing)] data-[ending-style]:scale-90 data-[ending-style]:opacity-0 data-[ending-style]:duration-150 data-[ending-style]:ease-[ease] data-[starting-style]:scale-90 data-[starting-style]:opacity-0 dark:border-white dark:bg-neutral-950 dark:text-white dark:shadow-none"
  arrow_class="relative block h-1.5 w-3 overflow-clip transition-[left,right] duration-[var(--duration)] ease-[var(--easing)] before:absolute before:bottom-0 before:left-1/2 before:block before:h-[calc(6px*sqrt(2))] before:w-[calc(6px*sqrt(2))] before:-translate-x-1/2 before:translate-y-1/2 before:rotate-45 before:border before:border-neutral-950 before:bg-white before:content-[''] data-[side=bottom]:top-[-6px] data-[side=left]:right-[-9px] data-[side=left]:rotate-90 data-[side=right]:left-[-9px] data-[side=right]:-rotate-90 data-[side=top]:bottom-[-6px] data-[side=top]:rotate-180 dark:before:border-white dark:before:bg-neutral-950"
  viewport_class="relative h-full w-full overflow-hidden"
  content_class="h-full w-[calc(100vw-40px)] p-2 min-[500px]:w-max min-[500px]:max-w-[400px] transition-[opacity,transform,translate] duration-[var(--duration)] ease-[var(--easing)] data-[starting-style]:opacity-0 data-[ending-style]:opacity-0 data-[starting-style]:data-[activation-direction=left]:translate-x-[-50%] data-[starting-style]:data-[activation-direction=right]:translate-x-[50%] data-[ending-style]:data-[activation-direction=left]:translate-x-[50%] data-[ending-style]:data-[activation-direction=right]:translate-x-[-50%]"
>
  <:icon>
    <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor" class="block">
      <path d="M12 6H4l4 4.5z" />
    </svg>
  </:icon>

  <:item label="Overview">
    <ul class="m-0 grid list-none grid-cols-2 p-0 max-[500px]:grid-cols-1">
      <li>
        <a
          href="/chelekom/docs"
          class="relative block h-full w-full border-0 bg-transparent p-2 text-left text-inherit no-underline hover:bg-neutral-100 data-[popup-open]:bg-neutral-100 focus-visible:outline-2 focus-visible:-outline-offset-1 focus-visible:outline-neutral-950 dark:focus-visible:outline-white dark:hover:bg-neutral-800 dark:data-[popup-open]:bg-neutral-800"
        >
          <h3 class="m-0 mb-1 text-sm leading-4 font-normal">Quick Start</h3>
          <p class="m-0 text-sm text-neutral-500 dark:text-neutral-400">
            Install and assemble your first component.
          </p>
        </a>
      </li>
      <li>
        <a
          href="/chelekom/docs/headless"
          class="relative block h-full w-full border-0 bg-transparent p-2 text-left text-inherit no-underline hover:bg-neutral-100 data-[popup-open]:bg-neutral-100 focus-visible:outline-2 focus-visible:-outline-offset-1 focus-visible:outline-neutral-950 dark:focus-visible:outline-white dark:hover:bg-neutral-800 dark:data-[popup-open]:bg-neutral-800"
        >
          <h3 class="m-0 mb-1 text-sm leading-4 font-normal">Accessibility</h3>
          <p class="m-0 text-sm text-neutral-500 dark:text-neutral-400">
            Learn how we build accessible components.
          </p>
        </a>
      </li>
      <li>
        <a
          href="/blog/tag/release"
          class="relative block h-full w-full border-0 bg-transparent p-2 text-left text-inherit no-underline hover:bg-neutral-100 data-[popup-open]:bg-neutral-100 focus-visible:outline-2 focus-visible:-outline-offset-1 focus-visible:outline-neutral-950 dark:focus-visible:outline-white dark:hover:bg-neutral-800 dark:data-[popup-open]:bg-neutral-800"
        >
          <h3 class="m-0 mb-1 text-sm leading-4 font-normal">Releases</h3>
          <p class="m-0 text-sm text-neutral-500 dark:text-neutral-400">
            See what's new in the latest Base UI versions.
          </p>
        </a>
      </li>
      <li>
        <a
          href="/chelekom"
          class="relative block h-full w-full border-0 bg-transparent p-2 text-left text-inherit no-underline hover:bg-neutral-100 data-[popup-open]:bg-neutral-100 focus-visible:outline-2 focus-visible:-outline-offset-1 focus-visible:outline-neutral-950 dark:focus-visible:outline-white dark:hover:bg-neutral-800 dark:data-[popup-open]:bg-neutral-800"
        >
          <h3 class="m-0 mb-1 text-sm leading-4 font-normal">About</h3>
          <p class="m-0 text-sm text-neutral-500 dark:text-neutral-400">
            Learn more about Base UI and our mission.
          </p>
        </a>
      </li>
    </ul>
  </:item>

  <:item label="Handbook">
    <ul class="m-0 flex max-w-[400px] list-none flex-col justify-center p-0">
      <li>
        <a
          href="/chelekom/docs/design-system"
          class="relative block h-full w-full border-0 bg-transparent p-2 text-left text-inherit no-underline hover:bg-neutral-100 data-[popup-open]:bg-neutral-100 focus-visible:outline-2 focus-visible:-outline-offset-1 focus-visible:outline-neutral-950 dark:focus-visible:outline-white dark:hover:bg-neutral-800 dark:data-[popup-open]:bg-neutral-800"
        >
          <h3 class="m-0 mb-1 text-sm leading-4 font-normal">Styling</h3>
          <p class="m-0 text-sm text-neutral-500 dark:text-neutral-400">
            Base UI components can be styled with plain CSS, Tailwind CSS, CSS-in-JS, or CSS Modules.
          </p>
        </a>
      </li>
      <li>
        <a
          href="/chelekom/docs/headless"
          class="relative block h-full w-full border-0 bg-transparent p-2 text-left text-inherit no-underline hover:bg-neutral-100 data-[popup-open]:bg-neutral-100 focus-visible:outline-2 focus-visible:-outline-offset-1 focus-visible:outline-neutral-950 dark:focus-visible:outline-white dark:hover:bg-neutral-800 dark:data-[popup-open]:bg-neutral-800"
        >
          <h3 class="m-0 mb-1 text-sm leading-4 font-normal">Animation</h3>
          <p class="m-0 text-sm text-neutral-500 dark:text-neutral-400">
            Base UI components can be animated with CSS transitions, CSS animations, or JavaScript libraries.
          </p>
        </a>
      </li>
      <li>
        <a
          href="/chelekom/docs/headless"
          class="relative block h-full w-full border-0 bg-transparent p-2 text-left text-inherit no-underline hover:bg-neutral-100 data-[popup-open]:bg-neutral-100 focus-visible:outline-2 focus-visible:-outline-offset-1 focus-visible:outline-neutral-950 dark:focus-visible:outline-white dark:hover:bg-neutral-800 dark:data-[popup-open]:bg-neutral-800"
        >
          <h3 class="m-0 mb-1 text-sm leading-4 font-normal">Composition</h3>
          <p class="m-0 text-sm text-neutral-500 dark:text-neutral-400">
            Base UI components can be replaced and composed with your own existing components.
          </p>
        </a>
      </li>
    </ul>
  </:item>

  <:item label="Docs" href="/chelekom/docs" />
</.navigation_menu>

Base UI Navigation Menu example - nested (Phoenix headless)

heex
<.navigation_menu
  id="baseui-navigation_menu-nested"
  style="--duration: 0.35s; --easing: cubic-bezier(0.22, 1, 0.36, 1);"
  class="min-w-max text-neutral-950 dark:text-white"
  list_class="relative flex gap-px"
  trigger_class="flex h-8 items-center justify-center gap-1.5 bg-transparent px-2 text-sm font-normal text-neutral-950 no-underline select-none min-[501px]:px-3 hover:bg-neutral-100 data-[popup-open]:bg-neutral-100 focus-visible:outline-2 focus-visible:-outline-offset-1 focus-visible:outline-neutral-950 dark:focus-visible:outline-white dark:text-white dark:hover:bg-neutral-800 dark:data-[popup-open]:bg-neutral-800"
  icon_class="transition-transform duration-200 ease-[ease] data-[open]:rotate-180"
  positioner_class="h-[var(--positioner-height)] w-[var(--positioner-width)] max-w-[var(--available-width)] transition-[top,left,right,bottom] duration-[var(--duration)] ease-[var(--easing)] before:absolute before:content-[''] data-[instant]:transition-none data-[side=bottom]:before:top-[-10px] data-[side=bottom]:before:right-0 data-[side=bottom]:before:left-0 data-[side=bottom]:before:h-2.5 data-[side=left]:before:top-0 data-[side=left]:before:right-[-10px] data-[side=left]:before:bottom-0 data-[side=left]:before:w-2.5 data-[side=right]:before:top-0 data-[side=right]:before:bottom-0 data-[side=right]:before:left-[-10px] data-[side=right]:before:w-2.5 data-[side=top]:before:right-0 data-[side=top]:before:bottom-[-10px] data-[side=top]:before:left-0 data-[side=top]:before:h-2.5"
  popup_class="relative h-[var(--popup-height)] w-[var(--popup-width)] origin-[var(--transform-origin)] border border-neutral-950 bg-white text-neutral-950 shadow-[0.25rem_0.25rem_0] shadow-black/12 outline-none transition-[opacity,transform,width,height,scale] duration-[var(--duration)] ease-[var(--easing)] data-[ending-style]:scale-90 data-[ending-style]:opacity-0 data-[ending-style]:duration-150 data-[ending-style]:ease-[ease] data-[starting-style]:scale-90 data-[starting-style]:opacity-0 dark:border-white dark:bg-neutral-950 dark:text-white dark:shadow-none"
  arrow_class="relative block h-1.5 w-3 overflow-clip transition-[left,right] duration-[var(--duration)] ease-[var(--easing)] before:absolute before:bottom-0 before:left-1/2 before:block before:h-[calc(6px*sqrt(2))] before:w-[calc(6px*sqrt(2))] before:-translate-x-1/2 before:translate-y-1/2 before:rotate-45 before:border before:border-neutral-950 before:bg-white before:content-[''] data-[side=bottom]:top-[-6px] data-[side=left]:right-[-9px] data-[side=left]:rotate-90 data-[side=right]:left-[-9px] data-[side=right]:-rotate-90 data-[side=top]:bottom-[-6px] data-[side=top]:rotate-180 dark:before:border-white dark:before:bg-neutral-950"
  viewport_class="relative h-full w-full overflow-hidden"
  content_class="h-full w-[calc(100vw-40px)] p-2 min-[500px]:w-max min-[500px]:min-w-[400px] transition-[opacity,transform,translate] duration-[var(--duration)] ease-[var(--easing)] data-[starting-style]:opacity-0 data-[ending-style]:opacity-0 data-[starting-style]:data-[activation-direction=left]:translate-x-[-50%] data-[starting-style]:data-[activation-direction=right]:translate-x-[50%] data-[ending-style]:data-[activation-direction=left]:translate-x-[50%] data-[ending-style]:data-[activation-direction=right]:translate-x-[-50%]"
>
  <:icon>
    <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor" class="block">
      <path d="M12 6H4l4 4.5z" />
    </svg>
  </:icon>

  <:item label="Overview">
    <ul class="m-0 grid list-none grid-cols-2 p-0 min-[640px]:grid-cols-[12rem_12rem]">
      <li>
        <a
          href="/chelekom/docs"
          class="relative block h-full w-full border-0 bg-transparent p-2 text-left text-inherit no-underline hover:bg-neutral-100 data-[popup-open]:bg-neutral-100 focus-visible:outline-2 focus-visible:-outline-offset-1 focus-visible:outline-neutral-950 dark:focus-visible:outline-white dark:hover:bg-neutral-800 dark:data-[popup-open]:bg-neutral-800"
        >
          <h3 class="m-0 mb-1 text-sm leading-4 font-normal">Quick Start</h3>
          <p class="m-0 text-sm text-neutral-500 dark:text-neutral-400">
            Install and assemble your first component.
          </p>
        </a>
      </li>
      <li>
        <a
          href="/chelekom/docs/headless"
          class="relative block h-full w-full border-0 bg-transparent p-2 text-left text-inherit no-underline hover:bg-neutral-100 data-[popup-open]:bg-neutral-100 focus-visible:outline-2 focus-visible:-outline-offset-1 focus-visible:outline-neutral-950 dark:focus-visible:outline-white dark:hover:bg-neutral-800 dark:data-[popup-open]:bg-neutral-800"
        >
          <h3 class="m-0 mb-1 text-sm leading-4 font-normal">Accessibility</h3>
          <p class="m-0 text-sm text-neutral-500 dark:text-neutral-400">
            Learn how we build accessible components.
          </p>
        </a>
      </li>
      <li>
        <a
          href="/blog/tag/release"
          class="relative block h-full w-full border-0 bg-transparent p-2 text-left text-inherit no-underline hover:bg-neutral-100 data-[popup-open]:bg-neutral-100 focus-visible:outline-2 focus-visible:-outline-offset-1 focus-visible:outline-neutral-950 dark:focus-visible:outline-white dark:hover:bg-neutral-800 dark:data-[popup-open]:bg-neutral-800"
        >
          <h3 class="m-0 mb-1 text-sm leading-4 font-normal">Releases</h3>
          <p class="m-0 text-sm text-neutral-500 dark:text-neutral-400">
            See what's new in the latest Base UI versions.
          </p>
        </a>
      </li>
      <li class="relative">
        <div class="m-0 flex w-full min-w-[10rem] flex-col items-start gap-1 border-0 bg-transparent p-2 text-left text-inherit hover:bg-neutral-100 data-[popup-open]:bg-neutral-100 dark:hover:bg-neutral-800 dark:data-[popup-open]:bg-neutral-800">
          <span class="m-0 mb-1 text-sm leading-4 font-normal">Handbook</span>
          <p class="m-0 text-sm text-neutral-500 dark:text-neutral-400">
            How to use Base UI effectively.
          </p>
        </div>
        <ul class="m-0 flex list-none flex-col justify-center p-0">
          <li>
            <a
              href="/chelekom/docs/design-system"
              class="relative block h-full w-full border-0 bg-transparent p-2 text-left text-inherit no-underline hover:bg-neutral-100 data-[popup-open]:bg-neutral-100 focus-visible:outline-2 focus-visible:-outline-offset-1 focus-visible:outline-neutral-950 dark:focus-visible:outline-white dark:hover:bg-neutral-800 dark:data-[popup-open]:bg-neutral-800"
            >
              <h3 class="m-0 mb-1 text-sm leading-4 font-normal">Styling</h3>
              <p class="m-0 text-sm text-neutral-500 dark:text-neutral-400">
                Base UI components can be styled with plain CSS, Tailwind CSS, CSS-in-JS, or CSS Modules.
              </p>
            </a>
          </li>
          <li>
            <a
              href="/chelekom/docs/headless"
              class="relative block h-full w-full border-0 bg-transparent p-2 text-left text-inherit no-underline hover:bg-neutral-100 data-[popup-open]:bg-neutral-100 focus-visible:outline-2 focus-visible:-outline-offset-1 focus-visible:outline-neutral-950 dark:focus-visible:outline-white dark:hover:bg-neutral-800 dark:data-[popup-open]:bg-neutral-800"
            >
              <h3 class="m-0 mb-1 text-sm leading-4 font-normal">Animation</h3>
              <p class="m-0 text-sm text-neutral-500 dark:text-neutral-400">
                Base UI components can be animated with CSS transitions, CSS animations, or JavaScript libraries.
              </p>
            </a>
          </li>
          <li>
            <a
              href="/chelekom/docs/headless"
              class="relative block h-full w-full border-0 bg-transparent p-2 text-left text-inherit no-underline hover:bg-neutral-100 data-[popup-open]:bg-neutral-100 focus-visible:outline-2 focus-visible:-outline-offset-1 focus-visible:outline-neutral-950 dark:focus-visible:outline-white dark:hover:bg-neutral-800 dark:data-[popup-open]:bg-neutral-800"
            >
              <h3 class="m-0 mb-1 text-sm leading-4 font-normal">Composition</h3>
              <p class="m-0 text-sm text-neutral-500 dark:text-neutral-400">
                Base UI components can be replaced and composed with your own existing components.
              </p>
            </a>
          </li>
        </ul>
      </li>
    </ul>
  </:item>
</.navigation_menu>

Base UI Navigation Menu example - nested inline (Phoenix headless)

Base UI Navigation Menu example - nested inline (Phoenix headless)

heex
<.navigation_menu
  id="baseui-navigation_menu-nested-inline"
  style="--duration: 0.35s; --easing: cubic-bezier(0.22, 1, 0.36, 1);"
  class="min-w-max text-neutral-950 dark:text-white"
  list_class="relative flex gap-px"
  trigger_class="flex h-8 items-center justify-center gap-1.5 bg-transparent px-2 text-sm font-normal text-neutral-950 no-underline select-none min-[501px]:px-3 hover:bg-neutral-100 data-[popup-open]:bg-neutral-100 focus-visible:outline-2 focus-visible:-outline-offset-1 focus-visible:outline-neutral-950 dark:focus-visible:outline-white dark:text-white dark:hover:bg-neutral-800 dark:data-[popup-open]:bg-neutral-800"
  link_class="flex h-8 items-center justify-center gap-1.5 bg-transparent px-2 text-sm font-normal text-neutral-950 no-underline select-none min-[501px]:px-3 hover:bg-neutral-100 data-[popup-open]:bg-neutral-100 focus-visible:outline-2 focus-visible:-outline-offset-1 focus-visible:outline-neutral-950 dark:focus-visible:outline-white dark:text-white dark:hover:bg-neutral-800 dark:data-[popup-open]:bg-neutral-800"
  icon_class="transition-transform duration-200 ease-[ease] data-[open]:rotate-180"
  positioner_class="h-[var(--positioner-height)] w-[var(--positioner-width)] max-w-[var(--available-width)] transition-[top,left,right,bottom] duration-[var(--duration)] ease-[var(--easing)] before:absolute before:content-[''] data-[instant]:transition-none data-[side=bottom]:before:top-[-10px] data-[side=bottom]:before:right-0 data-[side=bottom]:before:left-0 data-[side=bottom]:before:h-2.5 data-[side=left]:before:top-0 data-[side=left]:before:right-[-10px] data-[side=left]:before:bottom-0 data-[side=left]:before:w-2.5 data-[side=right]:before:top-0 data-[side=right]:before:bottom-0 data-[side=right]:before:left-[-10px] data-[side=right]:before:w-2.5 data-[side=top]:before:right-0 data-[side=top]:before:bottom-[-10px] data-[side=top]:before:left-0 data-[side=top]:before:h-2.5"
  popup_class="relative h-[var(--popup-height)] w-[var(--popup-width)] origin-[var(--transform-origin)] border border-neutral-950 bg-white text-neutral-950 shadow-[0.25rem_0.25rem_0] shadow-black/12 outline-none transition-[opacity,transform,width,height,scale] duration-[var(--duration)] ease-[var(--easing)] data-[ending-style]:scale-90 data-[ending-style]:opacity-0 data-[ending-style]:duration-150 data-[ending-style]:ease-[ease] data-[ending-style]:transition-[opacity,scale] data-[starting-style]:scale-90 data-[starting-style]:opacity-0 dark:border-white dark:bg-neutral-950 dark:text-white dark:shadow-none"
  arrow_class="relative block h-1.5 w-3 overflow-clip transition-[left,right] duration-[var(--duration)] ease-[var(--easing)] before:absolute before:bottom-0 before:left-1/2 before:block before:h-[calc(6px*sqrt(2))] before:w-[calc(6px*sqrt(2))] before:-translate-x-1/2 before:translate-y-1/2 before:rotate-45 before:border before:border-neutral-950 before:bg-white before:content-[''] data-[side=bottom]:top-[-6px] data-[side=left]:right-[-9px] data-[side=left]:rotate-90 data-[side=right]:left-[-9px] data-[side=right]:-rotate-90 data-[side=top]:bottom-[-6px] data-[side=top]:rotate-180 dark:before:border-white dark:before:bg-neutral-950"
  viewport_class="relative h-full w-full overflow-hidden"
  content_class="h-full p-0 min-[700px]:[width:min(675px,calc(100vw-40px))] transition-[opacity,translate] duration-[calc(var(--duration)*0.5),var(--duration)] ease-[ease,cubic-bezier(0.4,0,0.2,1)] data-[starting-style]:data-[activation-direction=left]:opacity-0 data-[starting-style]:data-[activation-direction=right]:opacity-0 data-[ending-style]:opacity-0 data-[ending-style]:duration-[calc(var(--duration)*0.5)] data-[ending-style]:ease-[ease] data-[starting-style]:data-[activation-direction=left]:translate-x-[-2rem] data-[starting-style]:data-[activation-direction=right]:translate-x-[2rem] data-[ending-style]:data-[activation-direction=left]:translate-x-[2rem] data-[ending-style]:data-[activation-direction=right]:translate-x-[-2rem]"
>
  <:icon>
    <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor" class="block">
      <path d="M12 6H4l4 4.5z" />
    </svg>
  </:icon>

  <:item label="Product">
    <div class="grid grid-cols-1 overflow-hidden overflow-clip min-[700px]:grid-cols-[13rem_minmax(0,1fr)]">
      <ul class="m-0 flex list-none flex-row gap-1 overflow-x-auto p-2 min-[700px]:flex-col min-[700px]:gap-px min-[700px]:overflow-x-visible min-[700px]:overflow-y-clip min-[700px]:border-r min-[700px]:border-r-neutral-950 dark:min-[700px]:border-r-white">
        <li>
          <div class="m-0 flex w-full min-w-[10rem] flex-col items-start gap-1 border-0 bg-transparent p-2 text-left text-inherit hover:bg-neutral-100 data-[popup-open]:bg-neutral-100 dark:hover:bg-neutral-800 dark:data-[popup-open]:bg-neutral-800">
            <span class="text-sm leading-4 font-normal text-neutral-950 dark:text-white">
              Developers
            </span>
            <span class="text-sm text-neutral-500 dark:text-neutral-400">
              Go from idea to UI faster.
            </span>
          </div>
        </li>
        <li>
          <div class="m-0 flex w-full min-w-[10rem] flex-col items-start gap-1 border-0 bg-transparent p-2 text-left text-inherit hover:bg-neutral-100 data-[popup-open]:bg-neutral-100 dark:hover:bg-neutral-800 dark:data-[popup-open]:bg-neutral-800">
            <span class="text-sm leading-4 font-normal text-neutral-950 dark:text-white">
              Design Systems
            </span>
            <span class="text-sm text-neutral-500 dark:text-neutral-400">
              Keep patterns aligned across teams.
            </span>
          </div>
        </li>
        <li>
          <div class="m-0 flex w-full min-w-[10rem] flex-col items-start gap-1 border-0 bg-transparent p-2 text-left text-inherit hover:bg-neutral-100 data-[popup-open]:bg-neutral-100 dark:hover:bg-neutral-800 dark:data-[popup-open]:bg-neutral-800">
            <span class="text-sm leading-4 font-normal text-neutral-950 dark:text-white">
              Engineering Leads
            </span>
            <span class="text-sm text-neutral-500 dark:text-neutral-400">
              Roll out shared UI without drag.
            </span>
          </div>
        </li>
        <li>
          <div class="m-0 flex w-full min-w-[10rem] flex-col items-start gap-1 border-0 bg-transparent p-2 text-left text-inherit hover:bg-neutral-100 data-[popup-open]:bg-neutral-100 dark:hover:bg-neutral-800 dark:data-[popup-open]:bg-neutral-800">
            <span class="text-sm leading-4 font-normal text-neutral-950 dark:text-white">
              Startups
            </span>
            <span class="text-sm text-neutral-500 dark:text-neutral-400">
              Ship polished basics while things change.
            </span>
          </div>
        </li>
      </ul>
      <div class="relative min-h-[16.5rem] overflow-hidden border-t border-neutral-950 min-[700px]:border-t-0 dark:border-white">
        <div class="flex h-full flex-col gap-4 p-4">
          <div>
            <h4 class="m-0 text-base leading-5 font-normal">
              Build product UI without giving up control
            </h4>
            <p class="m-0 mt-1 text-sm text-neutral-500 dark:text-neutral-400">
              Start with accessible parts and shape them to your app instead of working around a preset design system.
            </p>
          </div>
          <ul class="-mx-2 m-0 flex list-none flex-col gap-0 p-0">
            <li>
              <a
                href="/chelekom/docs"
                class="relative block h-full w-full border-0 bg-transparent p-2 text-left text-inherit no-underline hover:bg-neutral-100 data-[popup-open]:bg-neutral-100 focus-visible:outline-2 focus-visible:-outline-offset-1 focus-visible:outline-neutral-950 dark:focus-visible:outline-white dark:hover:bg-neutral-800 dark:data-[popup-open]:bg-neutral-800"
              >
                <h5 class="m-0 text-sm leading-4 font-normal">Quick start</h5>
                <p class="m-0 text-sm text-neutral-500 dark:text-neutral-400">
                  Install Base UI and get your first interactive primitive on screen fast.
                </p>
              </a>
            </li>
            <li>
              <a
                href="/chelekom/docs/headless"
                class="relative block h-full w-full border-0 bg-transparent p-2 text-left text-inherit no-underline hover:bg-neutral-100 data-[popup-open]:bg-neutral-100 focus-visible:outline-2 focus-visible:-outline-offset-1 focus-visible:outline-neutral-950 dark:focus-visible:outline-white dark:hover:bg-neutral-800 dark:data-[popup-open]:bg-neutral-800"
              >
                <h5 class="m-0 text-sm leading-4 font-normal">Composition</h5>
                <p class="m-0 text-sm text-neutral-500 dark:text-neutral-400">
                  Wrap and combine parts to match your product structure without hacks.
                </p>
              </a>
            </li>
          </ul>
        </div>
      </div>
    </div>
  </:item>

  <:item label="Learn">
    <div class="flex flex-col gap-4 p-4 text-neutral-950 dark:text-white">
      <div>
        <h4 class="m-0 text-base leading-5 font-normal">Where teams usually start</h4>
        <p class="m-0 mt-1 text-sm text-neutral-500 dark:text-neutral-400">
          These are the docs people reach for first when they are turning a prototype into shared UI.
        </p>
      </div>
      <ul class="-mx-2 m-0 flex list-none flex-col gap-0 p-0">
        <li>
          <a
            href="/chelekom/docs/headless"
            class="relative block h-full w-full border-0 bg-transparent p-2 text-left text-inherit no-underline hover:bg-neutral-100 data-[popup-open]:bg-neutral-100 focus-visible:outline-2 focus-visible:-outline-offset-1 focus-visible:outline-neutral-950 dark:focus-visible:outline-white dark:hover:bg-neutral-800 dark:data-[popup-open]:bg-neutral-800"
          >
            <h5 class="m-0 text-sm leading-4 font-normal">Accessibility handbook</h5>
            <p class="m-0 text-sm text-neutral-500 dark:text-neutral-400">
              Take a practical pass over focus order, semantics, and keyboard support.
            </p>
          </a>
        </li>
        <li>
          <a
            href="/chelekom/docs/headless"
            class="relative block h-full w-full border-0 bg-transparent p-2 text-left text-inherit no-underline hover:bg-neutral-100 data-[popup-open]:bg-neutral-100 focus-visible:outline-2 focus-visible:-outline-offset-1 focus-visible:outline-neutral-950 dark:focus-visible:outline-white dark:hover:bg-neutral-800 dark:data-[popup-open]:bg-neutral-800"
          >
            <h5 class="m-0 text-sm leading-4 font-normal">Composition handbook</h5>
            <p class="m-0 text-sm text-neutral-500 dark:text-neutral-400">
              Learn when to wrap parts, share behavior, and expose flexible APIs.
            </p>
          </a>
        </li>
        <li>
          <a
            href="/chelekom/docs/design-system"
            class="relative block h-full w-full border-0 bg-transparent p-2 text-left text-inherit no-underline hover:bg-neutral-100 data-[popup-open]:bg-neutral-100 focus-visible:outline-2 focus-visible:-outline-offset-1 focus-visible:outline-neutral-950 dark:focus-visible:outline-white dark:hover:bg-neutral-800 dark:data-[popup-open]:bg-neutral-800"
          >
            <h5 class="m-0 text-sm leading-4 font-normal">Styling handbook</h5>
            <p class="m-0 text-sm text-neutral-500 dark:text-neutral-400">
              Apply tokens and state styles without fighting the underlying markup.
            </p>
          </a>
        </li>
      </ul>
    </div>
  </:item>

  <:item label="Releases" href="/blog/tag/release" />
  <:item label="Docs" href="/chelekom/docs" />
</.navigation_menu>

Parts & data attributes

Each part carries a stable data-part and a structural chelekom-navigation_menu__* class you can target, plus paired-presence state for open/closed transitions and side/align placement.

Partdata-partState / ARIAPurpose
Rootrootdata-orientationCarries the NavigationMenu hook; reads value, delay, orientation, side and align from its data attributes.
List / Itemlist / itemdata-valueThe top-level nav list and each of its entries.
Linklinkaria-current, data-activeA plain nav item (no dropdown), used for label + href items.
Trigger / Icontrigger / iconaria-haspopup, aria-expanded, aria-controls, data-popup-open, data-value, data-openThe button that opens a dropdown, and its caret icon.
Contentcontentdata-activation-direction, data-valueStored hidden; the active item's content is moved into the viewport and morphed.
Positioner / Popuppositioner / popupdata-open, data-closed, data-side, data-align, data-instantThe shared floating surface; exposes --positioner-width/height and --popup-width/height (the morphing size).
Viewport / Arrowviewport / arrowdata-side, data-alignWhere the active content lives, and the pointer arrow.

Accessibility

Base UI's Navigation Menu has no dedicated WAI-ARIA pattern of its own, so this component is built menubar-like, following the WAI-ARIA Menubar pattern. Arrow keys move focus between triggers along the configured orientation, a cross-axis arrow or Enter/Space opens the dropdown, and Escape closes it, restoring focus to the trigger and tabbing out closes it as well.