Drawer
Typed modal edge panel opened imperatively via kuiDrawer(), not rendered as a bound component instance. Built on Angular CDK Overlay. Use it for secondary workflows that keep page context visible: filters, detail panels, edit forms, navigation panels, and mobile action sheets.
Import the inject-function factory and drawer-host contract types from the published package entrypoint.
import {
KUI_DRAWER_CONTEXT,
KuiButtonDirective,
KuiDrawerContext,
KuiDrawerHost,
kuiDrawer,
} from '@kikita-labs/ui';
// Import runtime styles once, application-wide:
import '@kikita-labs/ui/styles';Implement KuiDrawerHost on your drawer component, inject KUI_DRAWER_CONTEXT to read data and close, then create a typed opener with kuiDrawer() and call it with data to open. The returned observable emits the typed result once and completes.
<div class="basic-drawer-example">
<button kuiButton type="button" (click)="edit()">Edit item</button>
@if (lastResult()) {
<p class="basic-drawer-example__result">Last result: {{ lastResult() }}</p>
}
</div>side selects the edge the drawer docks to and enters from: right (default), left, bottom, or top. Left/right drawers size by width; top/bottom drawers size by height.
<div class="drawer-sides-example">
@for (side of sides; track side) {
<button kuiButton type="button" shape="outline" (click)="open(side)">{{ side }}</button>
}
</div>size selects a width preset for left/right drawers and a height preset for top/bottom drawers: sm, md (default), lg, full, or auto. auto sizes the panel to its content (min 320px width for left/right, min 200px height for top/bottom).
<div class="drawer-sizes-example">
@for (size of sizes; track size) {
<button kuiButton type="button" shape="outline" (click)="open(size)">{{ size }}</button>
}
</div>API verified against @kikita-labs/ui v1.6.1 public typings.
| Name | Type | Default | Description |
|---|---|---|---|
| kuiDrawer(component, config?) | (component: Type<TComponent>, config?: Omit<KuiDrawerConfig, "data">) => (data: TData) => Observable<TResult | undefined> | - | Inject-function factory. Call once per injection context to get a typed opener bound to that component. |
| KuiDrawerHost<TResult, TData> | interface | - | Contract your drawer component implements. Requires a drawerContext property injected from KUI_DRAWER_CONTEXT. |
| KUI_DRAWER_CONTEXT | InjectionToken<KuiDrawerContext<TResult, TData>> | - | Injected inside the drawer component to read data and close the drawer. |
| drawerContext.data | TData | - | Data passed via the opener call, e.g. openDrawer(data). |
| drawerContext.side | KuiDrawerSide | - | Drawer side resolved from KuiDrawerConfig.side, read-only. |
| drawerContext.size | KuiDrawerSize | - | Drawer size preset resolved from KuiDrawerConfig.size, read-only. |
| drawerContext.closable | boolean | - | Mirrors KuiDrawerConfig.closable. Informational only -- the container renders .kui-drawer-close itself when true. |
| drawerContext.close(result?) | (result?: TResult) => void | - | Closes the drawer, optionally emitting a typed result to the opener subscription. |
| KuiDrawerConfig.data | TData | undefined | Available on the low-level config type; kuiDrawer() passes feature data through the returned opener function instead. |
| KuiDrawerConfig.side | 'right' | 'left' | 'bottom' | 'top' | 'right' | Edge from which the drawer enters and docks. |
| KuiDrawerConfig.size | 'sm' | 'md' | 'lg' | 'full' | 'auto' | 'md' | Width for left/right drawers, height for top/bottom drawers. 'auto' sizes to content (min 320px width for left/right, min 200px height for top/bottom). |
| KuiDrawerConfig.closeOnBackdropClick | boolean | true | Closes the drawer on backdrop click. Disable for required actions. |
| KuiDrawerConfig.closeOnEscape | boolean | true | Closes the drawer on Escape. Disable for required actions. |
| KuiDrawerConfig.closable | boolean | true | Shows the .kui-drawer-close button the container renders automatically, absolutely positioned top-right of the panel. |
| KuiDrawerRef<TResult> | class | - | Return type of kuiDrawer(component, config). Calling it with data opens the drawer and returns Observable<TResult | undefined>. |
| .kui-drawer-header / .kui-drawer-title / .kui-drawer-subtitle | CSS classes | - | Header structure classes. .kui-drawer-title is wired as aria-labelledby automatically when present. |
| .kui-drawer-body / .kui-drawer-footer | CSS classes | - | Scrollable content region and action row classes. |
| --kui-drawer-bg | CSS custom property | - | Panel background color. |
| --kui-drawer-border | CSS custom property | - | Panel border color. |
| --kui-drawer-radius | CSS custom property | - | Panel corner radius. |
| --kui-drawer-backdrop-bg | CSS custom property | - | Backdrop fill color. |
| --kui-drawer-width-sm / -md / -lg | CSS custom properties | - | Width presets used by left/right drawers. |
| --kui-drawer-height-sm / -md / -lg | CSS custom properties | - | Height presets used by top/bottom drawers. |
| --kui-drawer-duration-open / -close | CSS custom properties | - | Enter/exit animation durations. |
Drawer traps focus and matches native modal expectations while docked to a viewport edge.
- The panel renders
role="dialog"andaria-modal="true"automatically. .kui-drawer-titleis wired asaria-labelledbyautomatically when present in your content. Always include one.- Focus is trapped inside the drawer while open and returns to the opener on close.
- Escape closes by default unless
closeOnEscape: false; backdrop click closes by default unlesscloseOnBackdropClick: false. Disable both for required actions. - The panel renders
.kui-drawer-closeitself, top-right of the header, whenclosableistrue(the default); the header reserves space for it automatically.drawerContext.closableis retained for informational use only.