import { Component } from '@angular/core';
import { WrSidebar } from 'ngwr/sidebar';
@Component({ imports: [WrSidebar] })
export class MyComponent {}Sidebar
Navigation drawn from data: pages and groups, three levels deep.
Installation
Import the class, and @use the entry point in your global styles: without it the component renders unstyled.
Basic usage
Pass [entries]: pages and groups. Every group above the current route opens.
<wr-sidebar [entries]="entries" /> To drop the inner padding, set --wr-sidebar-padding: 0 on .wr-sidebar, not on its container.
Subtitle, badge and count
Any row can take a one-line subtitle, a word badge under the title and a count at the end. Give a group a url to make it a page too.
protected readonly entries: WrSidebarEntry[] = [
{ title: 'Introduction', icon: 'book', url: ['/intro'] },
{
title: 'Components',
count: 4,
countLabel: '4 pages', // what a screen reader hears
children: [
{
title: 'Graph',
subtitle: 'Nodes and edges',
badge: { text: 'New', tone: 'primary' }, // 'neutral' | 'primary' | 'danger'
url: ['/components/graph'],
},
{
title: 'Navigation',
url: ['/components/navigation'], // also a page: the arrow opens it
children: [{ title: 'Sidebar', url: ['/components/sidebar'] }],
},
],
},
];Which route counts as active
Pages match by URL prefix, so give ['/'] activeOptions: { exact: true }, or it is the current page everywhere.
protected readonly entries: WrSidebarEntry[] = [
// Without exact, '/' matches every URL
{ title: 'Home', url: ['/'], activeOptions: { exact: true } },
{ title: 'Orders', url: ['/orders'] }, // stays active on /orders/42
];API
| Name | Description | Type | Default |
|---|---|---|---|
entries | Pages and groups, in order. Groups nest three levels deep. | readonly WrSidebarEntry[] | [] |
ariaLabel | Name of the navigation landmark. Falls back to sidebar.label. | string | null | null |
defaultGroupIcon | Icon for a group whose icon is omitted. null draws none. | string | null | null |
defaultItemIcon | Icon for a page whose icon is omitted. null draws none. | string | null | null |
autoExpand | Open every group above the current route. | boolean | true |
autoCollapse | Close the groups the last navigation opened when the next one leaves them. | boolean | false |
WrSidebarRow | { title, subtitle?, icon?, badge?, count?, countLabel? }: what every row shows. | interface | — |
WrSidebarItem | WrSidebarRow plus { url, disabled?, activeOptions? }: a page. | interface | — |
WrSidebarGroup | WrSidebarRow plus { children, url?, defaultOpen? }: a group, and a page too with url. | interface | — |
WrSidebarBadge | { text, tone? }, where tone is 'neutral', 'primary' or 'danger'. | interface | — |
WrSidebarActiveOptions | { exact: boolean } or any subset of the router's own match options. | type | — |
CSS variables
Set these on the component's selector or a wrapper, not on :root: the defaults are declared on ngwr/sidebar's own element.
| Variable | Default | Declared on |
|---|---|---|
--wr-sidebar-badge-font-size | 0.5625rem | .wr-sidebar |
--wr-sidebar-badge-font-weight | var(--wr-font-weight-semibold) | .wr-sidebar |
--wr-sidebar-badge-line-height | 0.75rem | .wr-sidebar |
--wr-sidebar-badge-padding-x | var(--wr-space-xs) | .wr-sidebar |
--wr-sidebar-badge-radius | 0.25rem | .wr-sidebar |
--wr-sidebar-chevron | color-mix(in srgb, var(--wr-color-on-surface-muted) 70%, transparent) | .wr-sidebar |
--wr-sidebar-chevron-size | 0.875rem | .wr-sidebar +1 variant override |
--wr-sidebar-font-family | var(--wr-font-family-base) | .wr-sidebar |
--wr-sidebar-gap | 0.125rem | .wr-sidebar |
--wr-sidebar-group-gap | 0.375rem | .wr-sidebar |
--wr-sidebar-guide | var(--wr-border-base) | .wr-sidebar |
--wr-sidebar-guide-gap | var(--wr-space-sm) | .wr-sidebar |
--wr-sidebar-guide-width | 1px | .wr-sidebar |
--wr-sidebar-icon-gap | var(--wr-space-sm) | .wr-sidebar |
--wr-sidebar-icon-size | 1rem | .wr-sidebar |
--wr-sidebar-meta-gap | 0.375rem | .wr-sidebar |
--wr-sidebar-padding | var(--wr-space-sm) | .wr-sidebar |
--wr-sidebar-row-font-size | var(--wr-text-sm) | .wr-sidebar |
--wr-sidebar-row-height | 2rem | .wr-sidebar +1 variant override |
--wr-sidebar-row-line-height | var(--wr-text-sm-leading) | .wr-sidebar |
--wr-sidebar-row-padding-x | var(--wr-space-sm) | .wr-sidebar |
--wr-sidebar-row-padding-y | 0.375rem | .wr-sidebar +1 variant override |
--wr-sidebar-row-radius | var(--wr-border-radius-sm) | .wr-sidebar |
--wr-sidebar-subtitle-font-size | var(--wr-text-xs) | .wr-sidebar |
--wr-sidebar-subtitle-line-height | var(--wr-text-xs-leading) | .wr-sidebar |
Dependencies
| @angular/router | @angular/router(optional peer) |
|---|---|
| Built on | Icon |
See also
Component LayoutAn app shell: header, sider, content and footer.Component BurgerA menu button that morphs between a hamburger and a close mark.Component DrawerA side panel that slides in from any edge of the screen.Component BreadcrumbsShows where the current page sits in the site.Component IconRenders an SVG icon you register by name; ngwr ships none of its own.