The bundle supports two distinct levels of collapse behaviour, both driven by flags on the Menu entity and rendered with Bootstrap 5 markup.
Top-level collapse (collapsible)
When the Collapsible flag is enabled on a menu, the entire menu is wrapped in a block with a toggle button. Clicking the button expands or collapses the full <ul> tree.
The generated markup looks like this:
<div class="dashboard-menu-collapsible">
<button
type="button"
class="dashboard-menu-toggle btn btn-link ..."
data-bs-toggle="collapse"
data-bs-target="#dashboard-menu-sidebar"
aria-expanded="true"
aria-controls="dashboard-menu-sidebar"
>
<span>Sidebar</span>
<span class="dashboard-menu-toggle-icon" aria-hidden="true"></span>
</button>
<div id="dashboard-menu-sidebar" class="collapse show">
<ul class="dashboard-menu sidebar dashboard-menu-tree">
<!-- items -->
</ul>
</div>
</div>
- The toggle button label is the menu’s name (or code as fallback).
- The
dashboard-menu-toggle-icon span is a hook for a CSS chevron.
class="collapse show" when expanded; class="collapse" when collapsed.
Bootstrap’s collapse JavaScript must be loaded on the page for the toggle to work. The bundle only generates the markup and data attributes — it does not bundle Bootstrap JS.
Default state (collapsible_expanded)
The Collapsible expanded flag controls whether the menu starts open or closed:
collapsible_expanded | Initial state |
|---|
true (default) | Menu is open on page load |
false | Menu is collapsed on page load |
Nested item collapse (nested_collapsible)
When Nested collapsible is enabled, each item that has children gets its own toggle button beside the label. Children are rendered inside a Bootstrap collapse <div>.
<li>
<a href="/reports">Reports</a>
<button
type="button"
class="btn btn-link btn-sm p-0 ms-1 menu-nested-toggle"
data-bs-toggle="collapse"
data-bs-target="#sidebar-item-42"
aria-expanded="true"
aria-controls="sidebar-item-42"
>
<span class="menu-nested-toggle-icon" aria-hidden="true"><!-- chevron SVG --></span>
</button>
<div id="sidebar-item-42" class="collapse show">
<ul>
<!-- child items -->
</ul>
</div>
</li>
Branches that contain the current route always start expanded (class="collapse show"), regardless of the default expanded state.
Section items and nested collapse
Items with type Section (a non-clickable group header) also get a toggle button when nested_collapsible is enabled. The chevron is placed after the section label:
<span class="d-flex align-items-center flex-nowrap">
<span class="navigation-header">Reports</span>
<button ... data-bs-toggle="collapse" ...>
<span class="menu-nested-toggle-icon" aria-hidden="true">...</span>
</button>
</span>
Chevron styling
Both toggle types provide a <span> element for a CSS-driven chevron. Add this CSS (or adapt it to your design system):
/* Top-level menu toggle */
.dashboard-menu-toggle-icon::after {
content: "\25BE"; /* ▾ */
}
.dashboard-menu-toggle[aria-expanded="false"] .dashboard-menu-toggle-icon::after {
content: "\25B8"; /* ▸ */
}
/* Nested item toggle */
.menu-nested-toggle-icon::after {
content: "\25BE";
}
.menu-nested-toggle[aria-expanded="false"] .menu-nested-toggle-icon::after {
content: "\25B8";
}
The bundle inlines a small SVG chevron inside .menu-nested-toggle-icon by default. If you prefer a CSS ::after approach, override the template or remove the SVG via CSS (display: none) and use the ::after pseudo-element instead.
Configuring collapse options
All three flags are set on the Menu entity in the dashboard (gear icon → Configuration tab). There is no global YAML equivalent — the settings are per-menu.
| Flag | Effect |
|---|
collapsible | Wrap menu in a toggle block |
collapsible_expanded | Start expanded (true) or collapsed (false) |
nested_collapsible | Add per-item toggles for items with children |
These values are also exposed in the menuConfig array returned by dashboard_menu_config(), so custom templates can read them:
{% set menuConfig = dashboard_menu_config('sidebar') %}
{% if menuConfig.collapsible %}
{# wrap in your own collapsible markup #}
{% endif %}