Duskmoon UI v10.0.11
Theme
Left Menu dm_left_menu, dm_left_menu_group
## Overview Sidebar navigation menu with native groups and an optional collapsible icon rail. ## Usage ```elixir <.dm_left_menu active="dashboard"> <:title>Navigation</:title> <:menu> <.dm_left_menu_group active="dashboard"> <:title>Main</:title> <:menu id="dashboard" to="/dashboard">Dashboard</:menu> <:menu id="settings" to="/settings">Settings</:menu> </.dm_left_menu_group> </:menu> </.dm_left_menu> ```

Collapsible Sidebar

The live example has 24 pages, a sticky sidebar and a bottom collapse button. Scroll the menu, close a group, then navigate or use Back and Forward to check that its state survives. Hover or focus a collapsed link to see its label.

Open persistent sidebar example Open host-owned state example ## Sticky layout and page navigation Register all package hooks using `import * as DuskmoonHooks from "phoenix_duskmoon/hooks"` in your LiveSocket options. The component attaches `DuskmoonLeftMenu` and `DuskmoonLeftMenuNavigation` automatically. In the shared **LiveView layout**, pass menu data and the current page directly: ```heex <.dm_left_menu id="admin-sidebar" sticky socket={@socket} groups={@menu_groups} active={@active_nav} brand={%{label: "Administration", icon: "view-dashboard"}} footer_text="My application" storage_key="my-app:admin-sidebar-collapsed" class="sticky top-0 h-dvh" /> ``` Each group is a map with string `id`, `label`, optional `open` and `items`. Each item needs string `id`, `label`, `to`, and optionally an MDI `icon`, `disabled`, `class` and `rest`. Use atom keys, unique IDs, and server-filtered menu data. Sticky mode accepts data instead of slots and enables the icon rail. Existing slot-based menus remain available without `sticky`. CSS `class="sticky top-0 h-dvh"` positions the menu and bounds its height; `sticky socket={@socket}` keeps its package-owned child alive across LiveView pages. The brand, footer and toggle stay fixed while only the menu body scrolls. CSS sticky remains constrained by its containing block and scrolling ancestors. For a top app bar, adjust both the offset and available height. The component owns collapse, group state, navigation scroll restoration and active-item synchronization. Supply the same menu ID and configuration on every destination page; changing only `active` preserves the child. Pass an empty string to clear highlighting. Changing groups, brand or presentation settings changes the configuration hash and remounts the child with current menu data. No application sidebar LiveView, navigation hook or event handler is required. For host session persistence, opt into `collapse_controlled`, pass authoritative `collapsed`, omit `storage_key`, and set `collapse_event` to a custom event name. User toggles emit a bubbling CustomEvent with `detail: {id, collapsed}`. The host validates and persists that boolean. Changed controlled values preserve the sticky child. A targeted `duskmoon:left-menu:set-collapsed` DOM event applies `detail: {collapsed: true}` silently, without notification or storage writes. The host-owned example uses parent LiveView assigns and server controls; a real session store belongs to the host application. Full HTTP navigation or a reload resets in-memory scroll and group state. Optional `storage_key` persists only the collapsed preference. See the [left-menu guide](https://hexdocs.pm/phoenix_duskmoon/left-menu.html) for the data format, shared layout and browser verification steps.

Menu with Groups

Menu Link Tooltips

Spread tooltip trigger attributes onto a menu slot to attach hover and keyboard-focus hints to its navigation link. Use the slot's rest map for other global link attributes.

Workspace
Dashboard

Sizes