Angular Navigation Drawer Component Overview

    The Ignite UI for Angular Navigation Drawer component is a side navigation container. It can rest above content and slide in/out of view or be pinned to expand/collapse within the content. A mini version provides quick access to navigation even when closed. The Navigation Drawer features responsive mode selection and touch gestures. Content is completely customizable and can make use of default menu item styling.

    Angular Navigation Drawer Example

    Getting Started with Ignite UI for Angular Navigation Drawer

    To get started with the Ignite UI for Angular Navigation Drawer component, first you need to install Ignite UI for Angular. In an existing Angular application, type the following command:

    ng add igniteui-angular
    

    For a complete introduction to the Ignite UI for Angular, read the getting started topic.

    The first step is to import the IgxNavigationDrawerModule inside our app.module.ts file.

    Note

    The IgxNavigationDrawerComponent also depends on the BrowserAnimationsModule and optionally the HammerModule for touch interactions, so they need to be added to the AppModule as well:

    // app.module.ts
    ...
    import { HammerModule } from '@angular/platform-browser';
    import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
    import { IgxNavigationDrawerModule } from 'igniteui-angular';
    // import { IgxNavigationDrawerModule } from '@infragistics/igniteui-angular'; for licensed package
    
    @NgModule({
        ...
        imports: [..., BrowserAnimationsModule, HammerModule, IgxNavigationDrawerModule],
        ...
    })
    export class AppModule {}
    

    Alternatively, as of 16.0.0 you can import the IgxNavigationDrawerComponent as a standalone dependency, or use the IGX_NAVIGATION_DRAWER_DIRECTIVES token to import the component and all of its supporting components and directives.

    // home.component.ts
    
    import { HammerModule } from '@angular/platform-browser';
    import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
    import { NgFor } from '@angular/common';
    import { IGX_NAVIGATION_DRAWER_DIRECTIVES, IgxRippleDirective, IgxIconComponent } from 'igniteui-angular';
    // import { IGX_NAVIGATION_DRAWER_DIRECTIVES, IgxRippleDirective, IgxIconComponent } from '@infragistics/igniteui-angular'; for licensed package
    
    @Component({
        selector: 'app-home',
        template: `
        <div class="content-wrap">
            <igx-nav-drawer [isOpen]="true">
                <ng-template igxDrawer>
                    <nav>
                        <span igxDrawerItem [isHeader]="true">Components</span>
                        <span *ngFor="let item of navItems" igxDrawerItem [active]="item.text === selected" igxRipple (click)="navigate(item)">
                            <igx-icon fontSet="material">{{ item.name }}</igx-icon>
                            <span>{{ item.text }}</span>
                        </span>
                    </nav>
                </ng-template>
            </igx-nav-drawer>
            <main>
                <!-- app content -->
            </main>
        </div>
        `,
        styleUrls: ['home.component.scss'],
        standalone: true,
        imports: [BrowserAnimationsModule, HammerModule, IGX_NAVIGATION_DRAWER_DIRECTIVES, IgxRippleDirective, IgxIconComponent, NgFor]
        /* or imports: [BrowserAnimationsModule, HammerModule, IgxNavigationDrawerComponent, IgxNavDrawerTemplateDirective, IgxNavDrawerItemDirective, IgxIconComponent, IgxRippleDirective, NgFor] */
    })
    export class HomeComponent {
        public navItems: Product [];
    }
    

    Now that you have the Ignite UI for Angular Navigation Drawer module or directives imported, you can start using the igx-nav-drawer component.

    Using the Angular Navigation Drawer

    With the dependencies imported, the Navigation Drawer can be defined in the app component template:

    <igx-nav-drawer id="navdrawer" [isOpen]="true">
        <!-- template(s) -->
    </igx-nav-drawer>
    

    The content for the drawer should be provided via <ng-template> decorated with igxDrawer directive. While any content can be provided in the template, the igxDrawerItem directive (see Item styling) is available to apply out-of-the-box styling to items. The directive has two @Input properties:

    • active to style an item as selected.
    • isHeader to style an item as a group header, cannot be active.

    The igxRipple directive completes the look and feel:

    <!-- app.component.html -->
    <div class="content-wrap">
      <igx-nav-drawer id="navigation" #drawer [isOpen]="true">
        <ng-template igxDrawer>
          <nav>
            <span igxDrawerItem [isHeader]="true">Components</span>
            <span *ngFor="let item of navItems" igxDrawerItem [active]="item.text === selected"
            igxRipple (click)="navigate(item)">
              <igx-icon fontSet="material">{{ item.name }}</igx-icon>
              <span>{{ item.text }}</span>
            </span>
          </nav>
        </ng-template>
      </igx-nav-drawer>
      <main>
        <!-- app content -->
      </main>
    </div>
    

    An additional template decorated with igxDrawerMini directive can be provided for the alternative Mini variant as closed state.

    Note

    The Navigation Drawer can float above the content or be pinned alongside it. By default the drawer switches between those modes depending on the viewport size. See Modes for more information.

    To accommodate for the drawer switching modes, a simple flexible wrapper around the two content sections can be styled like so:

    /* app.component.css */
    .content-wrap
    {
        width: 100%;
        height: 100%;
        display: flex;
    }
    

    To add elements to our navigation drawer and be able to select them, our typescript file should look like this:

    /* app.component.ts */
    @Component({...})
    export class AppComponent {
        public navItems = [
            { name: 'account_circle', text: 'Avatar' },
            ...
        ];
    
        public selected = 'Avatar';
    
        public navigate(item) {
            this.selected = item.text;
        }
    }
    

    There are various ways to open and close the drawer. Input properties can be bound to app state, programatic access to the API in the component using a @ViewChild(IgxNavigationDrawerComponent) reference or even in this case using the #drawer template reference variable:

    <button (click)="drawer.toggle()"> Menu </button>
    

    The Navigation Drawer also integrates with igxNavigationService and can be targeted by id with an igxToggleAction directive.

    Let's replace the <main> in app.component.html with the following, adding igxIconButton and Icon component to style our toggle:

    <main>
      <span igxIconButton="flat" igxToggleAction="navigation">
        <igx-icon fontSet="material">menu</igx-icon>
      </span>
    </main>
    

    Also, if you want the drawer to close when you select an item from it, you can use a @ViewChild(IgxNavigationDrawerComponent) reference like that:

    /* app.component.ts */
    import { Component, ViewChild } from '@angular/core';
    import { IgxNavigationDrawerComponent } from 'igniteui-angular';
    // import { IgxNavigationDrawerComponent } from '@infragistics/igniteui-angular'; for licensed package
    
    @Component({...})
    export class AppComponent  {
        @ViewChild(IgxNavigationDrawerComponent, { static: true })
        public drawer: IgxNavigationDrawerComponent;
    
        // And of course add the key line to our navigate function
    
        public navigate(item) {
            this.selected = item.text;
            this.drawer.close();
        }
    }
    

    If everything went well, you should see the demo sample in your browser.

    Modes

    Unpinned (elevated above the content) mode is the normal behavior where the drawer sits above and applies a darkened overlay over the content. Generally used to provide temporary navigation suitable for mobile devices.

    The drawer can be pinned to take advantage of larger screens, placing it within normal content flow with relative position. Depending on whether the app provides a way to toggle the drawer, the pinned mode can be used to achieve either permanent or persistent behavior.

    Note

    By default the Navigation Drawer is responsive, actively changing between unpinned and pinned mode based on screen size. This behavior is controlled by the pinThreshold property and can be disabled by setting a falsy value (e.g. 0).

    Pinned (persistent) setup

    Pin changes the position of the drawer from fixed to relative to put it on the same flow as content. Therefore, the app styling should account for such layout, especially if the drawer needs to be toggled in this mode. While there's more than one way to achieve such fluid layout (including programmatically), the easiest way is using igxLayout and igxFlex directives.

    Here's how that would look applied to the previous example:

    <div class="content-wrap" igxLayout igxLayoutDir="row">
        <igx-nav-drawer id="navigation" #drawer [isOpen]="true" [pin]="true" [pinThreshold]="0">
            <!-- template(s) -->
        </igx-nav-drawer>
        <main igxFlex>
            <!-- content here -->
        </main>
    </div>
    
    .content-wrap {
        width: 100%;
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
    }
    

    Now the changed example should look like that:

    The drawer applies flex-basis on its host element, allowing the rest of the content to take up the remaining width. Alternatively, skipping using directives, manual styling can be applied similar to:

    .main {
        position: absolute;
        display: flex;
        flex-flow: row nowrap;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        width: 100%;
    }
    
    .main > * {
        width: 100%;
    }
    

    Mini variant

    With the mini variant, the Navigation Drawer changes its width instead of closing. Most commonly used to maintain quick selection available on the side at all times, leaving just the icons. This variant is enabled simply by the presence of an alternative mini template decorated with igxDrawerMini directive.

    The mini variant is commonly used in a persistent setup, so we've set pin and disabled the responsive threshold:

    <igx-nav-drawer id="navigation" [pin]="true" [pinThreshold]="0">
        <ng-template igxDrawer>
            <span *ngFor="let item of navItems" igxDrawerItem [active]="item.text === selected" igxRipple (click)="navigate(item)">
              <igx-icon fontSet="material">{{ item.name }}</igx-icon>
              <span>{{ item.text }}</span>
            </span>
        </ng-template>
        <ng-template igxDrawerMini>
            <span *ngFor="let item of navItems" igxDrawerItem [active]="item.text === selected" igxRipple (click)="navigate(item)">
                <igx-icon fontSet="material">{{ item.name }}</igx-icon>
            </span>
        </ng-template>
    </igx-nav-drawer>
    

    Using Angular Router

    To use the Angular Router, first, we need to import git from @angular/router and create an instance of the router in our constructor. Then we have to define our navigation items using the router for their link values.

    /* app.component.ts */
     ...
    
    export class AppComponent {
        public componentLinks = [
            {
                link: 'avatar',
                name: 'Avatar'
            },
            {
                link:  'badge',
                name: 'Badge'
            },
            {
                link:  'button-group',
                name: 'Button Group'
            }
        ];
    }
    

    You can use routerLinkActive where it's assigned to a template variable and its isActive property can be used for binding to the active input on the igxDrawerItem. The <igx-nav-drawer> template would look like this:

    /* app.component.html */
    
    <!-- ... -->
    <ng-template igxDrawer>
        <nav>
            <span igxDrawerItem [isHeader]="true">Components</span>
    
            <span *ngFor="let item of componentLinks" routerLink="{{item.link}}"
                routerLinkActive #rla="routerLinkActive"
                igxDrawerItem igxRipple [active]="rla.isActive">
                    {{item.name}}
            </span>
        </nav>
    </ng-template>
    <!-- ... -->
    

    Finally, import the RouterModule along with the items' routes in your app.module.ts file:

    /*app.module.ts*/
    import { RouterModule } from '@angular/router';
    
    @NgModule([
        imports: [
            RouterModule,
    		RouterModule.forRoot([
                {path: 'avatar', component: NavDrawerRoutingComponent},
                {path: 'badge', component: NavDrawerRoutingComponent},
                {path: 'button-group', component: NavDrawerRoutingComponent}
            ])
        ]
    ])
    

    After all the steps above are completed, your app should look like that:

    Hierarchical Navigation

    To create a multi-level hierarchical navigation using the IgxNavigationDrawerComponent, you can use the IgxTreeComponent in the igxDrawer template. The tree can be constructed directly from your application Routes object. Here's how this can be achieved:

    <igx-nav-drawer [isOpen]="true" [enableGestures]="true" width="280px">
        <ng-template igxDrawer>
            <igx-tree>
                <igx-tree-node *ngFor="let route of routes">
                    <a igxTreeNodeLink [routerLink]="route.path" routerLinkActive="route-selected-class">{{ route.data?.displayName }}</a>
                    <igx-tree-node *ngFor="let child of route.children">
                        <a igxTreeNodeLink [routerLink]="[route.path, child.path]" routerLinkActive="route-selected-class">{{ child.data?.displayName }}</a>
                    </igx-tree-node>
                </igx-tree-node>
            </igx-tree>
        </ng-template>
    </igx-nav-drawer>
    
    Note

    In this example, we're not using the igxDrawerItem, instead we're populating directly with custom igxDrawer content, in this case using an igx-tree.

    import { menusRoutes } from '../../menus-routing.module';
    
    @Component({
      selector: 'app-nav-drawer-hierarchical',
      templateUrl: './nav-drawer-hierarchical.component.html',
      styleUrls: ['./nav-drawer-hierarchical.component.scss']
    })
    export class NavDrawerHierarchicalComponent {
        public routes = menusRoutes;
    }
    

    In this example, we're populating the routes with custom routing data, which contains a displayName property, used to visualize the link text in the igx-tree nodes. A sample Route looks like this:

    export const menusRoutes: Routes = [
        {
            component: NavDrawerHierarchicalComponent,
            path: 'navigation-drawer-hierarchical',
            data: { displayName: 'Hierarchical Drawer Menu' }
        }
    ];
    

    There's also child routing extracted from the children property of the routes. The sample shows two levels of hierarchy, but if your routing has more, then all you need to do is define the levels below the second one in the tree node templates.

    Note

    Keep in mind that some routes, like empty route redirect, error route, page not found, etc., might not be suitable for visualization directly. Before binding the tree to the routing object, you can strip those routes out of your object in your component logic.

    The example below presents the capabilities of a hierarchical structure by using predefined data with topic names and links. The structure allows users to easily generate functional and detailed navigations and to have the ability to define each element whether to be displayed as a link or as an indicator.

    Styling

    To get started with styling the navigation drawer, we need to import the index file, where all the theme functions and component mixins live:

    @use "igniteui-angular/theming" as *;
    
    // IMPORTANT: Prior to Ignite UI for Angular version 13 use:
    // @import '~igniteui-angular/lib/core/styles/themes/index';
    

    Following the simplest approach, we create a new theme that extends the navdrawer-theme and accepts a few parameters that style the navdrawer's items:

    $custom-theme: navdrawer-theme(
        $background: #2d313a,
        $item-active-background: #ecc256,
        $item-header-text-color: #ecc256
    );
    

    As seen, the navdrawer-theme exposes some useful parameters for basic styling of its items.

    Including themes

    The last step is to include the component theme in our application.

    If $legacy-support is set to true, include the component theme like that:

     @include navdrawer($custom-theme);
    
    Note

    If the component is using an Emulated ViewEncapsulation, it is necessary to penetrate this encapsulation using ::ng-deep

    :host {
         ::ng-deep {
            @include navdrawer($custom-theme);
        }
    }
    

    If $legacy-support is set to false(default), include the component css variables like that:

    @include css-vars($custom-theme);
    
    Note

    If the component is using an Emulated ViewEncapsulation, you still have to use :host because you need a global selector in order to override the variables.

    :host {
        @include css-vars($custom-theme);
    }
    

    API and Style References