1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-05 19:23:19 +00:00
Files
browser/libs/components/src/drawer/drawer.component.ts
Will Martin b8a1856fc6 [CL-696] un-revert "various drawer improvements" + bug fix (#14887)
* Revert "Revert "[CL-622][CL-562][CL-621][CL-632] various drawer improvements …"

This reverts commit 4b32d1f9dd.

* fix virtual scroll: add .cdk-virtual-scrollable to scroll viewport target

* remove references to main el

* use directives instead of querySelector (#14950)

* remove references to main el

* wip

* banish querySelector to the shadow realm

* revert apps/ files

* Add virtual scrolling docs

Co-authored-by: Vicki League <vleague@bitwarden.com>

* add jsdoc

* run eslint

* fix skip links bug

* Update libs/components/src/layout/layout.component.ts

Co-authored-by: Vicki League <vleague@bitwarden.com>

* update tab handler

* only run on tab

* fix lint

* fix virtual scroll issue due to Angular 19 upgrade (#15193)

thanks Vicki

---------

Co-authored-by: Vicki League <vleague@bitwarden.com>
2025-06-17 11:05:14 -04:00

76 lines
2.2 KiB
TypeScript

import { CdkPortal, PortalModule } from "@angular/cdk/portal";
import { CommonModule } from "@angular/common";
import {
ChangeDetectionStrategy,
Component,
effect,
inject,
input,
model,
viewChild,
} from "@angular/core";
import { DrawerService } from "./drawer.service";
/**
* 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",
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [CommonModule, PortalModule],
templateUrl: "drawer.component.html",
})
export class DrawerComponent {
private drawerHost = inject(DrawerService);
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);
}
}