Skip to content

Multi-level Drawer #31011

@jerryzhch

Description

@jerryzhch

Which @angular/* package(s) are relevant/related to the feature request?

No response

Description

I have implemented a PoC for a multilevel drawer for my company, which makes a highly respectable financial advisory tool for banks. To visualise how the multilevel drawer would look like: https://ant.design/components/drawer

and here is my PoC code (reduced to the minimum):

HTML:

<mat-drawer-container class="drawer-container-left" [hasBackdrop]="true">
  <mat-drawer #drawerLeft class="drawer-content"
              (openedStart)="prepareDrawer()"
              (closed)="cleanUpMainDrawer()">
    <drawer-header *ngIf="drawerHeaderTitleKey"
                       (closeClick)="toggleDrawer(DrawerSide.LEFT)"
                       [displayName]="drawerHeaderTitleKey | translateExtended">
    </drawer-header>
    <ng-container #drawerContentLeft></ng-container>
  </mat-drawer>
  <mat-drawer #subDrawerLeft class="drawer-content"
              (openedStart)="prepareDrawer()"
              (closed)="cleanUpSubDrawer()">
    <drawer-header *ngIf="subDrawerHeaderTitleKey"
                       (closeClick)="toggleDrawer(DrawerSide.SUB_LEFT)"
                       [displayName]="subDrawerHeaderTitleKey | translateExtended">
    </drawer-header>
    <ng-container #subDrawerContentLeft></ng-container>
  </mat-drawer>
  <mat-drawer-content class="drawer-outer-content-container">
    <mat-drawer-container class="drawer-container-right" [hasBackdrop]="true">
      <mat-drawer #drawerRight class="drawer-content"
                  (openedStart)="prepareDrawer()"
                  (closed)="cleanUpMainDrawer()">
        <drawer-header *ngIf="drawerHeaderTitleKey"
                           (closeClick)="toggleDrawer(DrawerSide.RIGHT)"
                           [displayName]="drawerHeaderTitleKey | translateExtended">
        </drawer-header>
        <ng-container #drawerContentRight></ng-container>
      </mat-drawer>
      <mat-drawer #subDrawerRight class="drawer-content"
                  (openedStart)="prepareDrawer()"
                  (closed)="cleanUpSubDrawer()">
        <drawer-header *ngIf="subDrawerHeaderTitleKey"
                           (closeClick)="toggleDrawer(DrawerSide.SUB_RIGHT)"
                           [displayName]="subDrawerHeaderTitleKey | translateExtended">
        </drawer-header>
        <ng-container #subDrawerContentRight></ng-container>
      </mat-drawer>
      <mat-drawer-content>
        <ng-content></ng-content>
      </mat-drawer-content>
    </mat-drawer-container>
  </mat-drawer-content>
</mat-drawer-container>

TS:

 ngOnInit() {
    this.drawerLeft.mode = 'over';
    this.drawerRight.mode = 'over';
    this.subDrawerLeft.mode = 'over';
    this.subDrawerRight.mode = 'over';

    this.drawerLeft.position = "start";
    this.drawerRight.position = 'end';
    this.subDrawerLeft.position = "start";
    this.subDrawerRight.position = 'end';

    this.drawerService.triggerDrawer.subscribe(side => {
      if (side === DrawerSide.LEFT) {
        this.drawerService.drawerState = this.drawerLeft.toggle();
      } else if (side === DrawerSide.RIGHT) {
        this.drawerService.drawerState = this.drawerRight.toggle();
      } else if (side === DrawerSide.SUB_LEFT) {
        this.drawerService.drawerState = this.subDrawerLeft.toggle();
      } else if (side === DrawerSide.SUB_RIGHT) {
        this.drawerService.drawerState = this.subDrawerRight.toggle();
      }
    });

    this.drawerLeft.closedStart.subscribe(() => {
      this.cleanUpMainDrawer();
    });
    this.drawerRight.closedStart.subscribe(() => {
      this.cleanUpMainDrawer();
    });
    this.subDrawerLeft.closedStart.subscribe(() => {
      this.cleanUpSubDrawer();
    });
    this.subDrawerRight.closedStart.subscribe(() => {
      this.cleanUpSubDrawer();
    });
    this.drawerService.closeDrawer.subscribe(ok => {
      if (this.isSubDrawer(this.drawerService.drawerConfig.side)) {
        this.subDrawerLeft.close()
        this.subDrawerRight.close()
        this.cleanUpSubDrawer();
      } else {
        this.drawerLeft.close();
        this.drawerRight.close();
        this.cleanUpMainDrawer();
      }
      if (ok && this.contentComponent?.instance?.submit) {
        this.contentComponent.instance.submit();
      }
    });
  }

Explanation: I have to create 4 drawer snippets, two of which have position "end" respectively "start". It generally works, but an error in the web console is shown saying this:

Image

Proposed solution

Maybe remove the constraint for only max 2 drawers (one on each side) ? Or maybe implement some type of safeguard for multiple drawers?

Alternatives considered

An alternative would just remove material components (mat-) in our drawer component. Which is a hassle since the PoC works but console errors don't look nice in prod.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions