Drawer
The drawer component creates a flexible overlay panel that provides focused workspace for forms, detailed views, or supplementary information.
import {DrawerModule} from "@qualcomm-ui/angular/drawer"Overview
The drawer's API is similar to the Dialog component.
Examples
Placement End
The drawer's default placement is end, which maps to the right side of the screen in LTR languages and the left side in RTL languages.
import {Component} from "@angular/core"
import {ButtonModule} from "@qualcomm-ui/angular/button"
import {DrawerModule} from "@qualcomm-ui/angular/drawer"
@Component({
imports: [DrawerModule, ButtonModule],
selector: "drawer-placement-demo",
template: `
<div q-drawer-root>
<button emphasis="primary" q-button q-drawer-trigger variant="fill">
Open Drawer
</button>
<q-drawer-floating-portal>
<div q-drawer-body>
<button q-drawer-close-button></button>
<h2 q-drawer-heading>Drawer Title</h2>
<div q-drawer-description>Drawer Description</div>
</div>
<div q-drawer-footer>
<button q-button q-drawer-close-trigger size="sm" variant="fill">
Close
</button>
</div>
</q-drawer-floating-portal>
</div>
`,
})
export class DrawerPlacementDemo {}Placement Start
Use placement start to change the placement to the left side of the screen.
<div placement="start" q-drawer-root>
Controlled State
Set the initial visibility using the defaultOpen prop, or use open and openChanged to control the visibility manually. These props follow our controlled state pattern.
import {Component, signal} from "@angular/core"
import {ButtonModule} from "@qualcomm-ui/angular/button"
import {DrawerModule} from "@qualcomm-ui/angular/drawer"
@Component({
imports: [DrawerModule, ButtonModule],
selector: "drawer-controlled-state-demo",
template: `
<div q-drawer-root [open]="open()" (openChanged)="onOpenChange($event)">
<button emphasis="primary" q-button q-drawer-trigger variant="fill">
Open Drawer
</button>
<q-drawer-floating-portal>
<div q-drawer-body>
<button q-drawer-close-button></button>
<h2 q-drawer-heading>Drawer Title</h2>
<div q-drawer-description>Drawer Description</div>
</div>
<div q-drawer-footer>
<button q-button q-drawer-close-trigger size="sm" variant="fill">
Close
</button>
</div>
</q-drawer-floating-portal>
</div>
`,
})
export class DrawerControlledStateDemo {
readonly open = signal(false)
onOpenChange(open: boolean) {
console.debug("Drawer open changed:", open)
this.open.set(open)
}
}Custom Container
Use the container prop of the <q-portal> component to render the drawer in a custom container. You'll need to override the positioner's default styles to position the drawer correctly.
Consider setting closeOnInteractOutside to false to prevent the drawer from closing when interacting outside the drawer.
Drawer Title
import {Component} from "@angular/core"
import {PortalComponent} from "@qualcomm-ui/angular-core/portal"
import {ButtonModule} from "@qualcomm-ui/angular/button"
import {DrawerModule} from "@qualcomm-ui/angular/drawer"
@Component({
imports: [DrawerModule, ButtonModule, PortalComponent],
selector: "drawer-custom-container-demo",
template: `
<div
closeOnEscape="false"
closeOnInteractOutside="false"
preventScroll="false"
q-drawer-root
trapFocus="false"
>
<div
#containerRef
class="border-neutral-03 relative box-border flex h-96 w-[600px] overflow-hidden border p-8"
>
<button emphasis="primary" q-button q-drawer-trigger variant="fill">
Open Drawer
</button>
</div>
<q-portal [container]="containerRef">
<div class="absolute z-0 h-full w-full" q-drawer-positioner>
<section q-drawer-content>
<div q-drawer-body>
<button q-drawer-close-button></button>
<h2 q-drawer-heading>Drawer Title</h2>
<div q-drawer-description>Drawer Description</div>
</div>
<div q-drawer-footer>
<button q-button q-drawer-close-trigger size="sm" variant="fill">
Close
</button>
</div>
</section>
</div>
</q-portal>
</div>
`,
})
export class DrawerCustomContainerDemo {}Shortcuts
<q-drawer-floating-portal>
A helper component that combines the portal, positioner, and content components. This shortcut is equivalent to:
<q-portal>
<div q-drawer-backdrop></div>
<div q-drawer-positioner>
<section q-drawer-content><ng-content /></section>
</div>
</q-portal>API
The Drawer shares many of its props and data attributes with the Dialog component.
<q-drawer-root>
stringbooleanbooleanboolean'ltr' | 'rtl'
| 'info'
| 'success'
| 'warning'
| 'danger'
| 'neutral'
() => HTMLElement
() =>
| Node
| ShadowRoot
| Document
boolean() => HTMLElement
booleanbooleanbooleanArray<
() => Element
>
- should not have pointer-events disabled
- should not trigger the dismiss event
| 'start'
| 'end'
booleanbooleanboolean| 'dialog'
| 'alertdialog'
| 'inside'
| 'outside'
'sm' | 'md'
booleanbooleanbooleanKeyboardEventvoidCustomEvent<{
event?: E
}>
| CustomEvent<{event?: E}>
| CustomEvent<{event?: E}>
booleanCustomEvent<{
event?: E
}>
CustomEvent<{
originalIndex: number
originalLayer: HTMLElement
targetIndex: number
targetLayer: HTMLElement
}>
<q-drawer-floating-portal>
q-drawer-backdrop
class'qui-dialog__backdrop'data-dialog-part'backdrop'data-state| 'open'
| 'closed'
hiddenbooleanq-drawer-positioner
stringclass'qui-drawer__positioner'data-dialog-part'positioner'data-placement| 'start'
| 'end'
styleq-drawer-content
stringclass'qui-drawer__content'data-dialog-part'content'data-placement| 'start'
| 'end'
data-size'sm' | 'md'
data-state| 'open'
| 'closed'
hiddenbooleantabIndex-1
q-drawer-body
booleanclass'qui-dialog__body'data-dialog-part'body'data-size'sm' | 'md'
q-drawer-heading
stringclass'qui-dialog__heading'data-dialog-part'heading'data-size'sm' | 'md'
q-drawer-footer
class'qui-dialog__footer'data-dialog-part'footer'data-size'sm' | 'md'
q-drawer-indicator-icon
class'qui-dialog__indicator-icon'data-emphasis| 'info'
| 'success'
| 'warning'
| 'danger'
| 'neutral'
data-size'sm' | 'md'
q-drawer-close-button
stringclass'qui-dialog__close-button'data-dialog-part'close-trigger'