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.

Dependencies

Note

This component requires HammerModule to be imported in the root module of the application for touch interactions to work as expected.

To start with all necessary dependencies you can use the IgxNavigationDrawerModule and import it in your application from 'igniteui-angular/navigation-drawer';

@NgModule({
    imports: [
        IgxNavigationDrawerModule,
        ...
    ]
})
export class AppModule {
}

Alternatively both barrels export the IgxNavigationDrawerComponent and additional directives, so those can be declared/referenced separately if needed.

Usage

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 */
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 igxButton and Icon component to style our toggle:

<main>
  <span igxButton="icon" 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";

...

export class AppComponent  {
    @ViewChild(IgxNavigationDrawerComponent, { static: true })
    public drawer: IgxNavigationDrawerComponent;

    // And of couse 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:

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:

@import '~igniteui-angular/lib/core/styles/themes/index';

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

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

As seen, the igx-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 igx-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 igx-navdrawer($custom-theme);
    }
}

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

@include igx-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 igx-css-vars($custom-theme);
}

API and Style References