# VelvetKit

## Navigation menu (`UI::NavigationMenu`)

Site navigation with links and hover or click panels of rich links.

Add it: `bin/rails generate velvetkit:add navigation_menu`

Also adds: `icon`

Stimulus: `ui--navigation-menu`

Installs: `@floating-ui/dom`

### Arguments

```ruby
UI::NavigationMenu.new(label: nil, open_delay: 150, close_delay: 200, class: nil, **html_attrs)
```

Slots: `with_item`, `with_link`

### Notes

UI::NavigationMenu — a site's main navigation: plain links, and triggers
that open a panel of rich links (title, description, optional icon).

Follows the WAI-ARIA disclosure navigation pattern (buttons with
aria-expanded controlling a panel of ordinary links), not role="menu",
which is for application menus.

  <%= render(UI::NavigationMenu.new) do |nav| %>
    <% nav.with_item(label: "Getting started") do |item| %>
      <% item.with_link(title: "Introduction", href: "/docs",
                        description: "Re-usable components built with Tailwind CSS.") %>
    <% end %>
    <% nav.with_item(label: "Docs", href: "/docs") %>
  <% end %>

A panel opens on hover (mouse, after `open_delay` ms; instantly when
another panel is already open), on click, or with Enter/Space/ArrowDown.
Escape, a click outside or tabbing away closes it.

Compound:
  UI::NavigationMenu         — the <nav> and its list
  UI::NavigationMenu::Item   — a plain link, or a trigger plus its panel
  UI::NavigationMenu::Link   — a rich link inside a panel

### Example: Simple

```erb
<div class="flex min-h-96 justify-center pt-8">
  <%= render(UI::NavigationMenu.new) do |nav| %>
    <% nav.with_item(label: "Getting started") do |item| %>
      <% item.with_link(title: "Introduction", href: "#introduction", description: "Re-usable components built with Tailwind CSS.") %>
      <% item.with_link(title: "Installation", href: "#installation", description: "How to install dependencies and structure your app.") %>
      <% item.with_link(title: "Typography", href: "#typography", description: "Styles for headings, paragraphs, lists…etc") %>
    <% end %>
    <% nav.with_item(label: "Components", columns: 2) do |item| %>
      <% item.with_link(title: "Alert", href: "#alert", description: "A callout for important information.") %>
      <% item.with_link(title: "Dialog", href: "#dialog", description: "A modal window on top of the page.") %>
      <% item.with_link(title: "Menu", href: "#menu", description: "A list of actions behind a button.") %>
      <% item.with_link(title: "Tabs", href: "#tabs", description: "Panels shown one at a time.") %>
      <% item.with_link(title: "Toast", href: "#toast", description: "A short message that disappears on its own.") %>
      <% item.with_link(title: "Tooltip", href: "#tooltip", description: "A label that appears on hover or focus.") %>
    <% end %>
    <% nav.with_item(label: "With Icon") do |item| %>
      <% item.with_link(title: "Backlog", href: "#backlog", icon: "circle-alert") %>
      <% item.with_link(title: "To do", href: "#todo", icon: "info") %>
      <% item.with_link(title: "Done", href: "#done", icon: "circle-check") %>
    <% end %>
    <% nav.with_item(label: "Docs", href: "#docs") %>
  <% end %>
</div>
```

### Example: Custom panel

```erb
<%# Any markup can go in a panel alongside, or instead of, its links. %>
<div class="flex min-h-[28rem] justify-center pt-8">
  <%= render(UI::NavigationMenu.new) do |nav| %>
    <% nav.with_item(label: "Company", panel_class: "w-[32rem]") do |item| %>
      <% item.with_link(title: "About", href: "#about", description: "Who we are and why we build this.") %>
      <% item.with_link(title: "Careers", href: "#careers", description: "Open roles, remote-first.") %>
      <% item.with_link(title: "Customers", href: "#customers", description: "Teams that run on Acme, in their words.") %>
      <% item.with_link(title: "Contact", href: "#contact", description: "Sales, support and partnerships.") %>
      <div class="mt-2 flex items-center justify-between gap-4 rounded-md bg-muted p-4">
        <div>
          <p class="text-sm font-medium">We're hiring</p>
          <p class="mt-1 text-sm text-muted-foreground">Three engineering roles are open this quarter.</p>
        </div>
        <%= render(UI::Button.new(size: :sm, variant: :outline)) { "See roles" } %>
      </div>
    <% end %>
    <% nav.with_item(label: "Blog", href: "#blog") %>
    <% nav.with_item(label: "Contact", href: "#contact") %>
  <% end %>
</div>
```
