A vertical sidebar navigation component for explicit tree data with optional icons, collapsible width, and configurable always-expanded section rendering.
<script type="module" src="https://cdn.q360.ai/assets/components/sidebar-menu/qds-sidebar-menu.js"></script>
Or load the full component bundle:
<script type="module" src="https://cdn.q360.ai/assets/components/index.js"></script>
<div style="height: 600px;">
<qds-sidebar-menu
data='[{"name":"Home","linkUrl":"#","items":[{"name":"Dashboard","linkUrl":"#dashboard"}]}]'
icon-root="https://cdn.q360.ai/"
use-icons>
</qds-sidebar-menu>
</div>
| Attribute | Type | Description | Default |
|---|---|---|---|
data |
String | JSON string containing hierarchical menu items | [] |
icon-root |
String | Base URL for relative icon paths | "https://cdn.q360.ai/" |
use-icons |
Boolean | Whether to display icons next to menu items | false |
collapsed |
Boolean | Whether the sidebar width is collapsed | false |
always-expanded |
Boolean | Whether all tree branches stay open and non-collapsible | false |
| Property | Type | Description |
|---|---|---|
useIcons |
Boolean | Get/set whether icons are displayed in menu items |
collapsed |
Boolean | Get/set whether the sidebar width is collapsed |
alwaysExpanded |
Boolean | Get/set whether the tree stays fully expanded |
| Event Name | Detail | Description |
|---|---|---|
itemSelected |
{ url: String, text: String } |
Fired when a link item is selected |
toggleCollapse |
{ collapsed: Boolean } |
Fired when the sidebar width is collapsed or expanded |
| Part | Description |
|---|---|
sidebar |
The sidebar container |
item |
Menu items, including links and category rows |
toggle |
Collapse/expand toggle button |
<div style="height: 100vh;">
<qds-sidebar-menu id="appSidebar" use-icons></qds-sidebar-menu>
</div>
<script>
const menuItems = [
{ name: "Dashboard", linkUrl: "/dashboard", icon: "dashboard.svg" },
{
name: "Finance",
linkUrl: "#",
icon: "folder.svg",
items: [
{ name: "Expense Reports", linkUrl: "/finance/expenses", icon: "xlsx.svg" },
{ name: "Budget Planning", linkUrl: "/finance/budget", icon: "pptx.svg" }
]
},
{ name: "Help", linkUrl: "/help", icon: "help.svg" }
];
const sidebar = document.getElementById('appSidebar');
sidebar.setAttribute('data', JSON.stringify(menuItems));
</script>
<div style="height: 100vh;">
<qds-sidebar-menu id="sidebar" always-expanded use-icons></qds-sidebar-menu>
</div>
The component is designed to inherit from the shared DS token set first, then allow host-level overrides:
qds-sidebar-menu {
--sidebar-bg-color: var(--theme-background-secondary);
--sidebar-text-color: var(--theme-text-primary);
--sidebar-border-color: var(--theme-border-primary);
--sidebar-toggle-bg-color: var(--theme-background-primary);
--sidebar-item-hover-bg-color: var(--theme-background-hover);
--sidebar-item-active-bg-color: var(--theme-background-accent-subtle);
--sidebar-item-active-color: var(--theme-accent-primary);
--sidebar-item-active-border-left: 2px solid var(--theme-accent-primary);
--sidebar-item-border-radius: var(--theme-radius-md);
--sidebar-content-padding: var(--theme-space-3) 0 var(--theme-space-4);
--sidebar-nested-indent: var(--theme-space-4);
}
qds-sidebar-menu.sectioned {
--sidebar-width: 220px;
--sidebar-content-top-offset: 0;
--sidebar-content-padding: var(--theme-space-3) 0 var(--theme-space-4);
--sidebar-category-spacing: var(--theme-space-2);
--sidebar-item-border-radius: var(--theme-radius-md);
--sidebar-nested-indent: 0;
--sidebar-level-0-text-transform: uppercase;
--sidebar-level-0-font-size: var(--theme-font-size-xs);
--sidebar-level-0-font-weight: var(--theme-font-weight-semibold);
--sidebar-level-0-letter-spacing: 0.12em;
--sidebar-level-0-padding: var(--theme-space-3) var(--theme-space-4) var(--theme-space-2);
--sidebar-level-1-padding: var(--theme-space-2) var(--theme-space-4);
}
[data-theme="dark"] qds-sidebar-menu.sectioned-dark {
--sidebar-bg-color: var(--theme-background-primary);
--sidebar-text-color: var(--theme-text-primary);
--sidebar-border-color: var(--theme-border-primary);
--sidebar-toggle-bg-color: var(--theme-background-tertiary);
--sidebar-toggle-color: var(--theme-text-primary);
--sidebar-section-color: var(--theme-text-tertiary);
--sidebar-item-color: var(--theme-text-secondary);
--sidebar-item-hover-bg-color: var(--button-hover-bg);
--sidebar-item-active-bg-color: var(--theme-background-warning-subtle);
--sidebar-item-active-color: var(--theme-warning);
--sidebar-item-active-border-left: 2px solid var(--theme-warning);
}
qds-sidebar-menu {
--sidebar-level-0-text-transform: uppercase;
--sidebar-level-0-font-size: var(--theme-font-size-xs);
--sidebar-level-1-font-size: var(--theme-font-size-sm);
--sidebar-level-2-color: var(--theme-text-tertiary);
}
This component works in modern browsers that support Custom Elements v1 and ES modules.