Devextreme: Drawer - a new component for building responsive web app layouts

Created on 23 Aug 2018  Â·  32Comments  Â·  Source: DevExpress/DevExtreme

The Problem

Creating a responsive web application layout with navigation bars and collapsible panes is complex and time-consuming.

The Proposed Solution

We are planning to include the new Drawer widget in v18.2. This widget can be used to create responsive and themeable web application layouts. We are also planning to add such layouts to our products.

Below we have listed the features we would like to support in our Drawer. The code examples in this thread are in Angular. However, you can use a similar API with React, Vue and jQuery.

Specifying the main and Drawer pane content

You should wrap content in the Drawer component to add a drawer panel. In this case, the Drawer drops a shadow over the content and change its size or position when opened. The drawer pane’s content is specified via a ‘drawer-pane’ template.

<dx-drawer>
    <div *dxTemplate="let data of 'drawer-pane'">
        Drawer Panel Content
    </div>
   <div>
       Main Content
   </div>
</dx-drawer>

Opening and closing the Drawer

<dx-drawer [opened]="isDrawerOpened">
    <div *dxTemplate="let data of 'drawer-pane'">
        navigation
    </div>
   <div>
       <div (click)="isDrawerOpened = !isDrawerOpened">Toggle navigation menu</div>
   </div>
</dx-drawer>

```js
export class AppComponent {
isDrawerOpened: boolean = false;
}

or using the ‘toggle’ method:

```html
<dx-drawer #drawer>
    <div *dxTemplate="let data of 'drawer-pane'">
        navigation
    </div>
   <div>
       <div (click)="drawer.toggle()">Toggle navigation menu</div>
   </div>
</dx-drawer>

Changing the Drawer position

 <dx-drawer [position]="'left'|'right'">
   ...
 </dx-drawer>

Changing the Drawer open behavior

   <dx-drawer
     [openedStateMode]="'shrink'|'push'|'overlap'"
     [revealMode]="'slide'|'expand'"
   >
       ...
   </dx-drawer>

The ‘openedStateMode’ option values:

  • ‘shrink’ - opening the drawer pane shrinks the main content
  • ‘push’ - the drawer pane displaces the main content
  • ‘overlap’ - the drawer pane overlaps the main content

The ‘revealMode’ option values:

  • ‘slide’ - the drawer pane content is sliding during open/close animation
  • ‘expand’ - the drawer pane content is static during open/close animation (only the pane width is animating)

Enabling/Disabling the Drawer shading

<dx-drawer [shading]="false">
       ...
</dx-drawer>

Specifying the Drawer pane width

<dx-drawer [width]="200">
       ...
</dx-drawer>

Creating a responsive layout for mobile & desktop

You can use different drawer configuration options depending on the screen size or orientation. For instance, you can implement a persistent navigation pane for desktop applications, and a temporary pane for mobile phones.

You can use the BreakpointObserver from the Angular Component Dev Kit to build apps with Angular. We’ll add an Angular example to this post soon.

Using several drawers at once

You can compose drawers if you need more that one drawer pane in your layout:

<dx-drawer #leftDrawer openedStateMode="overlap">
   <div *dxTemplate="let data of 'drawer-pane'">
       navigation
   </div>
   <dx-drawer #rightDrawer openedStateMode="push" position="right">
       <div *dxTemplate="let data of 'drawer-pane'">
           right panel content
       </div>
       <div>
           <div (click)="leftDrawer.toggle()">Toggle navigation menu</div>
           <div (click)="rightDrawer.toggle()">Toggle right pane</div>
       </div>
   </dx-drawer>
</dx-drawer>

We Need Your Feedback

Take a Quick Poll

Does the new Drawer component meet your needs?

Live Sandbox

Check out the early working prototype

Get Notified of Updates

Subscribe to this thread or to our Facebook and Twitter accounts for updates on this topic.

18_2 alpha-testing typdiscussion

Most helpful comment

Initially, the Box and ResponsiveBox components were introduced as a JS fallback to CSS FlexBox for old web browsers. Currently, there is no reason to use them instead of pure CSS for building web layouts. By 'layout templates' I mean preconfigured application layouts with navigation bars, toolbars, a content area, a logo, a hamburger menu, etc.

All 32 comments

I know it seems a little out there, but would the drawer be able to work as top and bottom positions as well? Left and right positions are fairly standard ux at this point. I'd be interested in a drawer that could work in all four positions. Bootstrap nav has had a menu that expands from the top for a while now. The bottom drawer could feel similar to the drawer of apps on an Android phone.

I'm looking forward to hearing your thoughts on this

Hi @jakehockey10,

Thanks for sharing your feedback. We are considering the capabilities you are talking about. Let me clarify some details. Do you need to implement exactly the same use-cases that you've mentioned? I mean a responsive bootstrap-like navbar (top position) and a popup panel with buttons or custom content (bottom position). These two specific use-cases don't require the 'push' and 'shrink' expand strategies. Such panels usually overlap the underlying content.

P.S. It would also be very helpful if you could share some reference links to the existing solutions that meet your specific needs.

I do not need this functionality for anything specific but considered it when thinking about patterns I've seen in Mobile apps and operating systems. I don't have any specific examples other than the app drawer of all versions of Android.

I think left and right positions work as they've become a standard but when I try to think of which is better than the other I can't really think of good reasons either way. Depends on how big the phone is, which handedness the user is, etc. I've also seen both used to offer site navigation vs. options in the current view. But top and bottom, to me, seem more universally accessible and thought I'd throw the suggestion out there.

Thanks KS for taking the time to respond, and I wish I had more to offer you! Please keep up the good work!

I found something pretty similar to what I was thinking for the bottom position here: https://material.io/design/components/app-bars-bottom.html# and here: https://material.io/design/components/navigation-drawer.html#navigation-drawer

Thanks for the clarification and links. We'll take all this information into consideration.

Is there a angular beta that can be used to play with?

The Angular support doesn't appear to work as yet, no drawer items using examples or code below

[shading]="false">





{{itemIndex}}




@bobskigit Angular version does work. I have tested it personally and they have included an example in devextreme-angular repository, but the API has changed since this issue has been opened and you need to use both the latest unstable devextreme version (18.2.1-pre-18239) and the latest unstable devextreme-angular version (18.2.1-beta.2). Also, you are assigning "openedStateMode" incorrectly - you either have to wrap openedStateMode in square brackets or remove single quotes from overlap.

@dxbykov The new drawer component works nicely. I just have one small suggestion: I think it would make a lot of sense to set default openedStateMode to shrink instead of push, opened to true and shading to false, because that's what the other UI frameworks do (ie Angular Material) and that's what at least I, as a user, expect to be the default behavior.

I see the API change now

rather than

I think need a title region on top of drawer also an option fullWidth for the mobile edition

In your sample in codepen: https://codepen.io/anon/pen/OwepVJ
when close drawer the "dx-drawer-shader" visibility remain visible.

Thank you, everybody, for testing and sharing your feedback. Note that the API might slightly change until the final release. We'll update the code samples in this thread according to the changes.
 
@hakimio @samoilis We'll take your suggestions and notes into account.
 
@samoilis It's not clear what you mean by 'title region on top of drawer'. Could you please give some examples or reference implementation of such a region?

@dxbykov like dxPopup title, with optional close button (default true in mobile devices)

@samoilis I do not believe that should be part of the drawer widget itself. Instead you should just be able to place some "card" widget (like Angular Material card) in the menu drawer to get this functionality or just define the title bar yourself (which is quite easy to do - just put a single div with absolute position).

EDIT: Also you could simply put a dx-toolbar in the menu drawer.

@samoilis thanks for the clarification.

Also you could simply put a dx-toolbar in the menu drawer.

Yes, that's our recommended way of implementing the mentioned UI. We'd like to keep the Drawer API as minimal as possible but keep it customizable.

A follow-up to my previous comment, such a toolbar could also be implemented within our layout templates. So, you won't have to build and configure everything from scratch.

@dxbykov by saying "layout templates" do you mean box and responsive box layouts?

Initially, the Box and ResponsiveBox components were introduced as a JS fallback to CSS FlexBox for old web browsers. Currently, there is no reason to use them instead of pure CSS for building web layouts. By 'layout templates' I mean preconfigured application layouts with navigation bars, toolbars, a content area, a logo, a hamburger menu, etc.

What is the major difference between this component, and a slide-out-view? Can you give examples in your proposal on what advantages and differences in use it would have to use the drawer over the already existing widgets?

Hi @anderschbe,
 
I would say that the new Drawer component is a replacement for SlideOutView rather than an addition. SlideOutView was initially optimized for the following:

  • a mobile UI only
  • a single menu
  • a single behavior mode

We'd like to come to a more general solution that can be used on both desktop and mobile devices. We've fixed naming issues and extended supported scenarios. Of course, we could apply all these changes to the existing SlideOutView component, but this would result in breaking changes for those who are using it. So, the new component allows you to smoothly migrate from the old mobile-oriented control to the new one.

Thank you, that was what I was speculating myself, but wasn't sure about. Maybe it would be prudent to add a link in the slideoutview documentation towards drawer?

From the simple demo, it is not clear to me if the drawer can be completely closed. I need a way to slide the drawer completely off the screen.

What is about nested drawers?
I mean will it be possible to have a drawer with main menu, and several small drawes inside the working area with view-specific tools on the right and left sides of the working area?

@vangundy Yes, the drawer can be completely closed if you keep the default min-width of zero.

@Shiko1st Yes, you can have nested drawers.

When you can expect eamples ora a document with implementation of a drawer?

I use in the "18.2-unstable" version and devextreme-angular version "18.2.1-beta6" and try to implement nested drawers, byt unfortunately it does not work the way I want. Maybe someone knows how to do it?

@JunkFunk You can find the documentation preview here.

If it doesn't help, could you please describe your use-case details and share your code that doesn't work?

It would be that the control would manage the display shape ideal for small and large screen sizes.

For example, for small screens come with the following options:

opened: false
closeOnOutsideClick: true

For larger screens the default setting below would make more sense:

opened: true
closeOnOutsideClick: false

Something similar to what happens by resizing the screen for small and large sizes in the example below:
https://www.cssscript.com/demo/responsive-sidebar-navigation-with-javascript-and-css3/

I think for most of the basic scenarios, developers would very much like the control to manage display by screen size as I've described, perhaps by inserting a new property like enableResponsivity, or something to turn on automatic behavior.

@ricardonoronha That's definitely not something the drawer component should take care of. Different apps might require different size breakpoints and different behaviors on small/medium and large screens. You can't have a solution which fits all cases. Current level of customizability is perfect.

@hakimio, really the control is very well done and allows a high level of customization, but in the vast majority of standard applications, what you see is to define a screen measurement from which we can consider a "big" screen and the side panel it could simply be displayed by default.

An example of this abarding is used in the dxForm, according to the link below:
https://js.devexpress.com/Demos/WidgetsGallery/Demo/Form/ColumnsAdaptability/jQuery/Light/

I believe that implementing this functionality would prevent many customers from making the same adjustments in their implementations to achieve the result I described.

@ricardonoronha Thank you for sharing your thoughts. I clearly understand what you are talking about. We'll consider how to make the Drawer user life easier.

Thanks to everybody who gave us early feedback on this feature. The feature is now available in the v18.2 release. I'm closing this thread. In the case of bugs or questions, feel free to create new GitHub issues or tickets in our Support Center.

Angular Drawer Component

I like this component, but have found a few problems. I want to use a drawer in a drawer(left and right).

  1. left drawer works fine.
  2. right drawer appears to be on top of left drawer if revealMode is set to overlap on the right drawer.
  3. right drawer does not display if revealMode is set to push.
  4. right drawer works fine if revealMode is set to shrink.

Would be VERY cool if overlap worked on both drawers at the same time.

I tried on a local Angular app as well as on the demo page itself. Is this a known issue or am I doing something wrong?

Thanks!! - Shane

Was this page helpful?
0 / 5 - 0 ratings