Drawer

A Drawer is a panel that is typically overlaid on top of a page and slides in from the side. It contains a set of information or actions. Since that user can interact with the Drawer without leaving the current page, tasks can be achieved more efficient within the same context.

When To Use#

  • Use a Form to create or edit a set of information.
  • Processing subtasks. When subtasks are too heavy for Popover and we still want to keep the subtasks in the context of the main task, Drawer comes very handy.
  • When a same Form is needed in multiple places.

Import this Component Individually#

You can get more detail here.

import { NzDrawerModule } from 'ng-zorro-antd/drawer';

Examples

Basic drawer.

expand codeexpand code
import { Component } from '@angular/core';

@Component({
  selector: 'nz-demo-drawer-basic-right',
  template: `
    <button nz-button nzType="primary" (click)="open()">Open</button>
    <nz-drawer
      [nzClosable]="false"
      [nzVisible]="visible"
      nzPlacement="right"
      nzTitle="Basic Drawer"
      (nzOnClose)="close()"
    >
      <p>Some contents...</p>
      <p>Some contents...</p>
      <p>Some contents...</p>
    </nz-drawer>
  `
})
export class NzDemoDrawerBasicRightComponent {
  visible = false;

  open(): void {
    this.visible = true;
  }

  close(): void {
    this.visible = false;
  }
}

A drawer containing an editable form which needs to be collapsed by clicking the close button.

expand codeexpand code
import { Component } from '@angular/core';

@Component({
  selector: 'nz-demo-drawer-from-drawer',
  template: `
    <button nz-button nzType="primary" (click)="open()">Create</button>
    <nz-drawer
      [nzBodyStyle]="{ height: 'calc(100% - 55px)', overflow: 'auto', 'padding-bottom': '53px' }"
      [nzMaskClosable]="false"
      [nzWidth]="720"
      [nzVisible]="visible"
      nzTitle="Create"
      (nzOnClose)="close()"
    >
      <form nz-form>
        <div nz-row nzGutter="8">
          <div nz-col nzSpan="12">
            <nz-form-item>
              <nz-form-label>Name</nz-form-label>
              <nz-form-control>
                <input nz-input placeholder="please enter user name" />
              </nz-form-control>
            </nz-form-item>
          </div>
          <div nz-col nzSpan="12">
            <nz-form-item>
              <nz-form-label>Url</nz-form-label>
              <nz-form-control>
                <nz-input-group nzAddOnBefore="http://" nzAddOnAfter=".com">
                  <input type="text" nz-input placeholder="please enter url" />
                </nz-input-group>
              </nz-form-control>
            </nz-form-item>
          </div>
        </div>
        <div nz-row nzGutter="8">
          <div nz-col nzSpan="12">
            <nz-form-item>
              <nz-form-label>Owner</nz-form-label>
              <nz-form-control>
                <nz-select nzPlaceHolder="Please select an owner"></nz-select>
              </nz-form-control>
            </nz-form-item>
          </div>
          <div nz-col nzSpan="12">
            <nz-form-item>
              <nz-form-label>Type</nz-form-label>
              <nz-form-control>
                <nz-select nzPlaceHolder="Please choose the type"></nz-select>
              </nz-form-control>
            </nz-form-item>
          </div>
        </div>
        <div nz-row nzGutter="8">
          <div nz-col nzSpan="12">
            <nz-form-item>
              <nz-form-label>Approver</nz-form-label>
              <nz-form-control>
                <nz-select nzPlaceHolder="Please choose the approver"></nz-select>
              </nz-form-control>
            </nz-form-item>
          </div>
          <div nz-col nzSpan="12">
            <nz-form-item>
              <nz-form-label>DateTime</nz-form-label>
              <nz-form-control>
                <nz-range-picker></nz-range-picker>
              </nz-form-control>
            </nz-form-item>
          </div>
        </div>
        <div nz-row nzGutter="8">
          <div nz-col nzSpan="24">
            <nz-form-item>
              <nz-form-label>Description</nz-form-label>
              <nz-form-control>
                <textarea
                  nz-input
                  placeholder="please enter url description"
                  [nzAutosize]="{ minRows: 4, maxRows: 4 }"
                ></textarea>
              </nz-form-control>
            </nz-form-item>
          </div>
        </div>
      </form>
      <div class="footer">
        <button type="button" (click)="close()" class="ant-btn" style="margin-right: 8px;"><span>Cancel</span></button>
        <button type="button" (click)="close()" class="ant-btn ant-btn-primary"><span>Submit</span></button>
      </div>
    </nz-drawer>
  `,
  styles: [
    `
      .footer {
        position: absolute;
        bottom: 0px;
        width: 100%;
        border-top: 1px solid rgb(232, 232, 232);
        padding: 10px 16px;
        text-align: right;
        left: 0px;
        background: #fff;
      }
    `
  ]
})
export class NzDemoDrawerFromDrawerComponent {
  visible = false;

  open(): void {
    this.visible = true;
  }

  close(): void {
    this.visible = false;
  }
}

Open a new drawer on top of an existing drawer to handle multi branch tasks

expand codeexpand code
import { Component } from '@angular/core';

@Component({
  selector: 'nz-demo-drawer-multi-level-drawer',
  template: `
    <button nz-button nzType="primary" (click)="open()">New Cookbook</button>
    <nz-drawer
      [nzClosable]="false"
      [nzOffsetX]="childrenVisible ? 180 : 0"
      [nzWidth]="320"
      [nzVisible]="visible"
      nzTitle="Cookbook"
      (nzOnClose)="close()"
    >
      <form nz-form>
        <div nz-row>
          <div nz-col nzSpan="24">
            <nz-form-item>
              <nz-form-label>Name</nz-form-label>
              <nz-form-control>
                <input nz-input placeholder="please enter cookbook name" />
              </nz-form-control>
            </nz-form-item>
          </div>
        </div>
        <div nz-row>
          <div nz-col nzSpan="24">
            <nz-form-item>
              <nz-form-label>Food</nz-form-label>
              <nz-form-control>
                <nz-tag>potato</nz-tag>
                <nz-tag>eggplant</nz-tag>
                <nz-tag (click)="openChildren()">+</nz-tag>
              </nz-form-control>
            </nz-form-item>
          </div>
        </div>
      </form>
      <div class="footer">
        <button type="button" (click)="close()" class="ant-btn" style="margin-right: 8px;"><span>Cancel</span></button>
        <button type="button" (click)="close()" class="ant-btn ant-btn-primary"><span>Submit</span></button>
      </div>
      <nz-drawer [nzClosable]="false" [nzVisible]="childrenVisible" nzTitle="Food" (nzOnClose)="closeChildren()">
        <nz-list [nzDataSource]="vegetables" [nzRenderItem]="item">
          <ng-template #item let-item>
            <nz-list-item [nzContent]="item"></nz-list-item>
          </ng-template>
        </nz-list>
      </nz-drawer>
    </nz-drawer>
  `,
  styles: [
    `
      .footer {
        position: absolute;
        bottom: 0px;
        width: 100%;
        border-top: 1px solid rgb(232, 232, 232);
        padding: 10px 16px;
        text-align: right;
        left: 0px;
        background: #fff;
      }
    `
  ]
})
export class NzDemoDrawerMultiLevelDrawerComponent {
  visible = false;
  childrenVisible = false;

  vegetables = ['asparagus', 'bamboo', 'potato', 'carrot', 'cilantro', 'potato', 'eggplant'];

  open(): void {
    this.visible = true;
  }

  close(): void {
    this.visible = false;
  }

  openChildren(): void {
    this.childrenVisible = true;
  }

  closeChildren(): void {
    this.childrenVisible = false;
  }
}

Basic drawer.

expand codeexpand code
import { Component } from '@angular/core';

@Component({
  selector: 'nz-demo-drawer-placement',
  template: `
    <nz-radio-group [(ngModel)]="placement">
      <label nz-radio nzValue="top">top</label>
      <label nz-radio nzValue="right">right</label>
      <label nz-radio nzValue="bottom">bottom</label>
      <label nz-radio nzValue="left">left</label>
    </nz-radio-group>
    <button nz-button nzType="primary" (click)="open()">Open</button>
    <nz-drawer
      [nzClosable]="false"
      [nzVisible]="visible"
      [nzPlacement]="placement"
      nzTitle="Basic Drawer"
      (nzOnClose)="close()"
    >
      <p>Some contents...</p>
      <p>Some contents...</p>
      <p>Some contents...</p>
    </nz-drawer>
  `
})
export class NzDemoDrawerPlacementComponent {
  visible = false;
  placement = 'left';
  open(): void {
    this.visible = true;
  }

  close(): void {
    this.visible = false;
  }
}

Lily

Progresser AFX

Lily

Progresser AFX

Use when you need to quickly preview the outline of the object. Such as list item preview.

expand codeexpand code
import { Component } from '@angular/core';

@Component({
  selector: 'nz-demo-drawer-user-profile',
  template: `
    <nz-list [nzDataSource]="data" [nzRenderItem]="item" [nzItemLayout]="'horizontal'">
      <ng-template #item let-item>
        <nz-list-item [nzActions]="[viewAction]">
          <ng-template #viewAction>
            <a (click)="open()">View Profile</a>
          </ng-template>
          <nz-list-item-meta
            [nzTitle]="nzTitle"
            nzAvatar="https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png"
            nzDescription="Progresser AFX"
          >
            <ng-template #nzTitle>
              <a href="https://ng.ant.design">{{ item.name }}</a>
            </ng-template>
          </nz-list-item-meta>
        </nz-list-item>
      </ng-template>
    </nz-list>
    <nz-drawer [nzVisible]="visible" [nzWidth]="640" [nzClosable]="false" (nzOnClose)="close()">
      <p class="title" style=" margin-bottom: 24px;">User Profile</p>
      <p class="title">Personal</p>
      <div nz-row>
        <div nz-col nzSpan="12">
          <div class="item-wrap">
            <p class="label">Full Name:</p>
            Lily
          </div>
        </div>
        <div nz-col nzSpan="12">
          <div class="item-wrap">
            <p class="label">Account:</p>
            AntDesign@example.com
          </div>
        </div>
      </div>
      <div nz-row>
        <div nz-col nzSpan="12">
          <div class="item-wrap">
            <p class="label">City:</p>
            HangZhou
          </div>
        </div>
        <div nz-col nzSpan="12">
          <div class="item-wrap">
            <p class="label">Country:</p>
            China🇨🇳
          </div>
        </div>
      </div>
      <div nz-row>
        <div nz-col nzSpan="12">
          <div class="item-wrap">
            <p class="label">Birthday:</p>
            February 2,1900
          </div>
        </div>
        <div nz-col nzSpan="12">
          <div class="item-wrap">
            <p class="label">Website:</p>
            -
          </div>
        </div>
      </div>
      <div nz-row>
        <div nz-col nzSpan="24">
          <div class="item-wrap">
            <p class="label">Message:</p>
            Make things as simple as possible but no simpler.
          </div>
        </div>
      </div>
      <nz-divider></nz-divider>
      <p class="title">Company</p>
      <div nz-row>
        <div nz-col nzSpan="12">
          <div class="item-wrap">
            <p class="label">Position:</p>
            Programmer
          </div>
        </div>
        <div nz-col nzSpan="12">
          <div class="item-wrap">
            <p class="label">Responsibilities:</p>
            Coding
          </div>
        </div>
      </div>
      <div nz-row>
        <div nz-col nzSpan="12">
          <div class="item-wrap">
            <p class="label">Department:</p>
            AFX
          </div>
        </div>
        <div nz-col nzSpan="12">
          <div class="item-wrap">
            <p class="label">Supervisor:</p>
            <a>Lin</a>
          </div>
        </div>
      </div>
      <div nz-row>
        <div nz-col nzSpan="24">
          <div class="item-wrap">
            <p class="label">Skills:</p>
            C / C + +, data structures, software engineering, operating systems, computer networks, databases, compiler
            theory, computer architecture, Microcomputer Principle and Interface Technology, Computer English, Java,
            ASP, etc.
          </div>
        </div>
      </div>
      <nz-divider></nz-divider>
      <p class="title">Contacts</p>
      <div nz-row>
        <div nz-col nzSpan="12">
          <div class="item-wrap">
            <p class="label">Email:</p>
            AntDesign@example.com
          </div>
        </div>
        <div nz-col nzSpan="12">
          <div class="item-wrap">
            <p class="label">Phone Number:</p>
            +86 181 0000 0000
          </div>
        </div>
      </div>
      <div nz-row>
        <div nz-col nzSpan="24">
          <div class="item-wrap">
            <p class="label">Github:</p>
            <a href="https://github.com/NG-ZORRO/ng-zorro-antd" target="_blank">github.com/NG-ZORRO/ng-zorro-antd</a>
          </div>
        </div>
      </div>
    </nz-drawer>
  `,
  styles: [
    `
      .title {
        font-size: 16px;
        color: rgba(0, 0, 0, 0.85);
        line-height: 24px;
        display: block;
        margin-bottom: 16px;
      }
      .item-wrap {
        font-size: 14px;
        line-height: 22px;
        margin-bottom: 7px;
        color: rgba(0, 0, 0, 0.65);
      }
      .label {
        margin-right: 8px;
        display: inline-block;
        color: rgba(0, 0, 0, 0.85);
      }
    `
  ]
})
export class NzDemoDrawerUserProfileComponent {
  data = [
    {
      name: 'Lily'
    },
    {
      name: 'Lily'
    }
  ];

  visible = false;

  open(): void {
    this.visible = true;
  }

  close(): void {
    this.visible = false;
  }
}
 

Usage of Drawer's service, examples demonstrate user-defined templates, custom components.

NOTE If you use Component mode, you need to add your custom Component into declarations and entryComponents for a NgModule

expand codeexpand code
/* entryComponents: NzDrawerCustomComponent */

import { Component, Input, TemplateRef, ViewChild } from '@angular/core';
import { NzDrawerRef, NzDrawerService } from 'ng-zorro-antd';

@Component({
  selector: 'nz-demo-drawer-service',
  template: `
    <ng-template #drawerTemplate let-data let-drawerRef="drawerRef">
      value: {{ data?.value }}
      <br />
      <button nz-button nzType="primary" (click)="drawerRef.close()">close</button>
    </ng-template>
    <div nz-form>
      <nz-form-item>
        <input nz-input [(ngModel)]="value" />
      </nz-form-item>
    </div>
    <button nz-button nzType="primary" (click)="openTemplate()">Use Template</button>&nbsp;
    <button nz-button nzType="primary" (click)="openComponent()">Use Component</button>
  `
})
export class NzDemoDrawerServiceComponent {
  @ViewChild('drawerTemplate', { static: false }) drawerTemplate: TemplateRef<{
    $implicit: { value: string };
    drawerRef: NzDrawerRef<any>;
  }>;
  value = 'ng';

  constructor(private drawerService: NzDrawerService) {}

  openTemplate(): void {
    const drawerRef = this.drawerService.create({
      nzTitle: 'Template',
      nzContent: this.drawerTemplate,
      nzContentParams: {
        value: this.value
      }
    });

    drawerRef.afterOpen.subscribe(() => {
      console.log('Drawer(Template) open');
    });

    drawerRef.afterClose.subscribe(() => {
      console.log('Drawer(Template) close');
    });
  }

  openComponent(): void {
    const drawerRef = this.drawerService.create<NzDrawerCustomComponent, { value: string }, string>({
      nzTitle: 'Component',
      nzContent: NzDrawerCustomComponent,
      nzContentParams: {
        value: this.value
      }
    });

    drawerRef.afterOpen.subscribe(() => {
      console.log('Drawer(Component) open');
    });

    drawerRef.afterClose.subscribe(data => {
      console.log(data);
      if (typeof data === 'string') {
        this.value = data;
      }
    });
  }
}

@Component({
  selector: 'nz-drawer-custom-component',
  template: `
    <div>
      <input nz-input [(ngModel)]="value" />
      <nz-divider></nz-divider>
      <button nzType="primary" (click)="close()" nz-button>Confirm</button>
    </div>
  `
})
export class NzDrawerCustomComponent {
  @Input() value = '';

  constructor(private drawerRef: NzDrawerRef<string>) {}

  close(): void {
    this.drawerRef.close(this.value);
  }
}

API#

nz-drawer#

PropsDescriptionTypeDefault
[nzClosable]Whether a close (x) button is visible on top right of the Drawer dialog or not.booleantrue
[nzMask]Whether to show mask or not.booleantrue
[nzMaskClosable]Clicking on the mask (area outside the Drawer) to close the Drawer or not.booleantrue
[nzMaskStyle]Style for Drawer's mask element.object{}
[nzBodyStyle]Body style for drawer body element. Such as height, padding etc.object{}
[nzTitle]The title for Drawer.string | TemplateRef<void>-
[nzVisible]Whether the Drawer dialog is visible or not.booleanfalse
[nzPlacement]The placement of the Drawer.'top' | 'right' | 'bottom' | 'left''right'
[nzWidth]Width of the Drawer dialog, only when placement is 'right' or 'left'.number | string256
[nzHeight]Height of the Drawer dialog, only when placement is 'top' or 'bottom'.number | string256
[nzOffsetX]The the X coordinate offset(px), only when placement is 'right' or 'left'.number0
[nzOffsetY]The the Y coordinate offset(px), only when placement is 'top' or 'bottom'.number0
[nzWrapClassName]The class name of the container of the Drawer dialog.string-
[nzZIndex]The z-index of the Drawer.number1000
(nzOnClose)Specify a callback that will be called when a user clicks mask, close button or Cancel button.EventEmitter<MouseEvent>-

NzDrawerService#

MethodDescriptionParamsReturn
createcreate and open an DrawerNzDrawerOptions<T, D, R>NzDrawerRef<R>

NzDrawerOptions#

ParamsDescriptionTypeDefault
nzContentThe drawer body content.TemplateRef<{ $implicit: D, drawerRef: NzDrawerRef }> | Type<T>-
nzContentParamsThe component inputs the param / The Template context.D-
nzClosableWhether a close (x) button is visible on top right of the Drawer dialog or not.booleantrue
nzOnCancelExecute when click on the mask or the upper cancel button, This function returns a promise, which is automatically closed when the execution is complete or the promise ends (return false to prevent closing)() => Promise<any>-
nzMaskClosableClicking on the mask (area outside the Drawer) to close the Drawer or not.booleantrue
nzMaskWhether to show mask or not.booleantrue
nzMaskStyleStyle for Drawer's mask element.object{}
nzBodyStyleBody style for modal body element. Such as height, padding etc.object{}
nzTitleThe title for Drawer.string | TemplateRef<void>-
nzWidthWidth of the Drawer dialog.number | string256
nzHeightHeight of the Drawer dialog, only when placement is 'top' or 'bottom'.number | string256
nzWrapClassNameThe class name of the container of the Drawer dialog.string-
nzZIndexThe z-index of the Drawer.number1000
nzPlacementThe placement of the Drawer.'top' | 'right' | 'bottom' | 'left''right'
nzOffsetXThe the X coordinate offset(px).number0
nzOffsetYThe the Y coordinate offset(px), only when placement is 'top' or 'bottom'.number0

NzDrawerRef#

Methods#

NameDescriptionType
closeclose the drawer.(result?: R) => void
openopen the drawer.() => void

Property#

NameDescriptionType
afterOpenCallback called after open.Observable<void>
afterCloseCallback called after close.Observable<R>
nzClosableWhether a close (x) button is visible on top right of the Drawer dialog or not.booleantrue
nzMaskClosableClicking on the mask (area outside the Drawer) to close the Drawer or not.booleantrue
nzMaskWhether to show mask or not.booleantrue
nzMaskStyleStyle for Drawer's mask element.object{}
nzBodyStyleBody style for modal body element. Such as height, padding etc.object{}
nzTitleThe title for Drawer.string | TemplateRef<void>-
nzWidthWidth of the Drawer dialog.number | string256
nzHeightHeight of the Drawer dialog, only when placement is 'top' or 'bottom'.number | string256
nzWrapClassNameThe class name of the container of the Drawer dialog.string-
nzZIndexThe z-index of the Drawer.number1000
nzPlacementThe placement of the Drawer.'top' | 'right' | 'bottom' | 'left''right'
nzOffsetXThe the X coordinate offset(px).number0
nzOffsetYThe the Y coordinate offset(px), only when placement is 'top' or 'bottom'.number0
Basic Drawer

Some contents...

Some contents...

Some contents...

Create
http://.com
Please select an owner
Please choose the type
Please choose the approver
~
Cookbook
potatoeggplant+
Food
asparagusbamboopotatocarrotcilantropotatoeggplant
Basic Drawer

Some contents...

Some contents...

Some contents...

User Profile

Personal

Full Name:

Lily

Account:

AntDesign@example.com

City:

HangZhou

Country:

China🇨🇳

Birthday:

February 2,1900

Website:

-

Message:

Make things as simple as possible but no simpler.

Company

Position:

Programmer

Responsibilities:

Coding

Department:

AFX

Supervisor:

Lin

Skills:

C / C + +, data structures, software engineering, operating systems, computer networks, databases, compiler theory, computer architecture, Microcomputer Principle and Interface Technology, Computer English, Java, ASP, etc.

Contacts

Email:

AntDesign@example.com

Phone Number:

+86 181 0000 0000