mirror of
https://github.com/bitwarden/browser
synced 2025-12-18 17:23:37 +00:00
[CL-428] create drawer component (#12812)
* remove private/protected/lifecycle fields from Storybook docs table * move theme override decorator into util method * implement base drawer component * update bit-layout to be drawer container * create drawer helper components * expose new APIs to DS barrel file * write docs * update docs; add role input * use host directive instead of service * clean up logic a tad * add start slot to story * update docs * Apply suggestions from code review Co-authored-by: Victoria League <vleague@bitwarden.com> * update docs * Update libs/components/src/drawer/drawer.mdx Co-authored-by: Victoria League <vleague@bitwarden.com> * update docs / stories * add non text element to drawer --------- Co-authored-by: Victoria League <vleague@bitwarden.com>
This commit is contained in:
76
libs/components/src/drawer/drawer.component.ts
Normal file
76
libs/components/src/drawer/drawer.component.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import { CdkPortal, PortalModule } from "@angular/cdk/portal";
|
||||
import { CommonModule } from "@angular/common";
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
effect,
|
||||
inject,
|
||||
input,
|
||||
model,
|
||||
viewChild,
|
||||
} from "@angular/core";
|
||||
|
||||
import { DrawerHostDirective } from "./drawer-host.directive";
|
||||
|
||||
/**
|
||||
* A drawer is a panel of supplementary content that is adjacent to the page's main content.
|
||||
*
|
||||
* Drawers render in `bit-layout`. Drawers must be a descendant of `bit-layout`, but they do not need to be a direct descendant.
|
||||
*/
|
||||
@Component({
|
||||
selector: "bit-drawer",
|
||||
standalone: true,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [CommonModule, PortalModule],
|
||||
templateUrl: "drawer.component.html",
|
||||
})
|
||||
export class DrawerComponent {
|
||||
private drawerHost = inject(DrawerHostDirective);
|
||||
private portal = viewChild.required(CdkPortal);
|
||||
|
||||
/**
|
||||
* Whether or not the drawer is open.
|
||||
*
|
||||
* Note: Does not support implicit boolean transform due to Angular limitation. Must be bound explicitly `[open]="true"` instead of just `open`.
|
||||
* https://github.com/angular/angular/issues/55166#issuecomment-2032150999
|
||||
**/
|
||||
open = model<boolean>(false);
|
||||
|
||||
/**
|
||||
* The ARIA role of the drawer.
|
||||
*
|
||||
* - [complementary](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/complementary_role)
|
||||
* - For drawers that contain content that is complementary to the page's main content. (default)
|
||||
* - [navigation](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/navigation_role)
|
||||
* - For drawers that primary contain links to other content.
|
||||
*/
|
||||
role = input<"complementary" | "navigation">("complementary");
|
||||
|
||||
constructor() {
|
||||
effect(
|
||||
() => {
|
||||
this.open() ? this.drawerHost.open(this.portal()) : this.drawerHost.close(this.portal());
|
||||
},
|
||||
{
|
||||
allowSignalWrites: true,
|
||||
},
|
||||
);
|
||||
|
||||
// Set `open` to `false` when another drawer is opened.
|
||||
effect(
|
||||
() => {
|
||||
if (this.drawerHost.portal() !== this.portal()) {
|
||||
this.open.set(false);
|
||||
}
|
||||
},
|
||||
{
|
||||
allowSignalWrites: true,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/** Toggle the drawer between open & closed */
|
||||
toggle() {
|
||||
this.open.update((prev) => !prev);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user