Nav Link
v0.0.10
mix mishka.ui.gen.headless nav_link
Leaf links
A leaf is a link with data-part="link". Pass the label as label or as the default slot, and set active on the one that matches the current page. On a group, active only sets data-active on the <details>.
<.nav_link navigate={~p"/dashboard"} active={@active_tab == :dashboard}>
<:icon><.icon name="hero-home" class="size-4" /></:icon>
Dashboard
</.nav_link>Keeping a group open in a LiveView
default_opened opens a group on first render, which is enough on a static page. Inside a LiveView, pass opened instead. It is the server's truth for the group and overrides default_opened. on_toggle is a phx-click on the control row, so use it to flip the value you pass as opened.
<.nav_link label="Projects" opened={@projects_open} on_toggle="toggle_projects">
<:children>
<.nav_link label="Active" navigate={~p"/projects/active"} />
<.nav_link label="Archived" navigate={~p"/projects/archived"} />
</:children>
</.nav_link>def handle_event("toggle_projects", _params, socket) do
{:noreply, update(socket, :projects_open, &(!&1))}
endParts & data attributes
Each part carries a stable data-part and a structural chelekom-nav-link__* class you can target, plus the state attributes below. The root of a leaf has data-part="link" and the root of a group has data-part="root".
| Part | data-part | State / ARIA | Purpose |
|---|---|---|---|
| Link (leaf root) | link | data-active, aria-current | The LiveView link of an item with no children. |
| Root (group) | root | data-active, open | The details element of an item with children. |
| Control | control | - | The summary that toggles the group. on_toggle is attached here. |
| Icon | icon | - | Wraps the icon slot. Rendered only when the slot is given. |
| Label | label | - | The text of the item. |
| Trailing | trailing | - | Wraps the trailing slot, for example a chevron. |
| Children | children | - | The container of the nested links. |
Accessibility
There is no formal WAI-ARIA APG pattern for a navigation link. The active leaf carries aria-current="page". A group uses the native details and summary disclosure: the summary is focusable, Enter and Space toggle it, and browsers expose its open state to assistive technology. Put the links inside a <nav> with an aria-label of your own.
Attributes
| Name | Type | Default | Values | Required | Description |
|---|---|---|---|---|---|
id
|
string
| — | — | No | Optional unique id |
label
|
string
| — | — | No | Label text (or use the default slot) |
href
|
string
| — | — | No | Leaf link href |
navigate
|
string
| — | — | No | LiveView navigate |
patch
|
string
| — | — | No | LiveView patch |
active
|
boolean
|
false
| — | No | Marks the item current (data-active + aria-current) |
default_opened
|
boolean
|
false
| — | No | Open nested children initially |
opened
|
boolean
| — | — | No | Server-controlled open state (overrides default_opened; survives LiveView patches) |
on_toggle
|
any
| — | — | No | phx-click for the control row — flip `opened` server-side when controlling the group |
class
|
any
| — | — | No | Extra classes for the root |
control_class
|
any
| — | — | No | — |
icon_class
|
any
| — | — | No | — |
label_class
|
any
| — | — | No | — |
trailing_class
|
any
| — | — | No | — |
children_class
|
any
| — | — | No | Extra classes for the nested container |
rest
|
global
| — | — | No | — |
Slots
| Name | Required | Description |
|---|---|---|
icon
| No | Leading icon |
trailing
| No | Trailing content (e.g. a chevron) |
inner_block
| No | Label content, used when the label attr is not set |
children
| No | Nested nav links — when present, the item becomes a disclosure |
Options
Each option takes one or more of its values, separated by commas.
| Option | Values |
|---|---|
--type
|
nav_link
|
--module
| A module name of your own |
What it generates
mix mishka.ui.gen.headless nav_link