1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-13 06:54:07 +00:00

[CL-303] Prevent chip menu from running offscreen (#11348)

This commit is contained in:
Victoria League
2024-10-07 11:27:16 -04:00
committed by GitHub
parent e24ddae5b9
commit ad7cf7de15
4 changed files with 24 additions and 3 deletions

View File

@@ -22,6 +22,7 @@
[disabled]="disabled"
[title]="label"
#menuTrigger="menuTrigger"
(click)="setMenuWidth()"
>
<span class="tw-inline-flex tw-items-center tw-gap-1.5 tw-truncate">
<i class="bwi !tw-text-[inherit]" [ngClass]="icon"></i>
@@ -57,7 +58,11 @@
</div>
<bit-menu #menu (closed)="handleMenuClosed()">
<div *ngIf="renderedOptions" class="tw-max-h-80 tw-min-w-52 tw-max-w-80 tw-text-sm">
<div
*ngIf="renderedOptions"
class="tw-max-h-80 tw-min-w-32 tw-max-w-80 tw-text-sm"
[ngStyle]="menuWidth && { width: menuWidth + 'px' }"
>
<ng-container *ngIf="getParent(renderedOptions) as parent">
<button
type="button"

View File

@@ -98,6 +98,12 @@ export class ChipSelectComponent<T = unknown> implements ControlValueAccessor, A
/** The option that is currently selected by the user */
protected selectedOption: ChipSelectOption<T>;
/**
* The initial calculated width of the menu when it opens, which is used to
* keep the width consistent as the user navigates through submenus
*/
protected menuWidth: number | null = null;
/** The label to show in the chip button */
protected get label(): string {
return this.selectedOption?.label || this.placeholderText;
@@ -122,6 +128,8 @@ export class ChipSelectComponent<T = unknown> implements ControlValueAccessor, A
protected handleMenuClosed(): void {
this.setOrResetRenderedOptions();
// reset menu width so that it can be recalculated upon open
this.menuWidth = null;
}
protected selectOption(option: ChipSelectOption<T>, _event: MouseEvent) {
@@ -201,6 +209,14 @@ export class ChipSelectComponent<T = unknown> implements ControlValueAccessor, A
});
}
/**
* Calculate the width of the menu according to the initially rendered options
*/
protected setMenuWidth() {
this.menuWidth =
this.menu.menuItems.first.elementRef.nativeElement.getBoundingClientRect().width;
}
/** Control Value Accessor */
private notifyOnChange?: (value: T) => void;

View File

@@ -163,7 +163,7 @@ export const NestedOptions: Story = {
icon: "bwi-folder",
children: [
{
label: "Foo1",
label: "Foo1 very long name of folder but even longer than you thought",
value: "foo1",
icon: "bwi-folder",
children: [

View File

@@ -41,7 +41,7 @@ export class MenuItemDirective implements FocusableOption {
@Input({ transform: coerceBooleanProperty }) disabled?: boolean = false;
constructor(private elementRef: ElementRef) {}
constructor(public elementRef: ElementRef<HTMLButtonElement>) {}
focus() {
this.elementRef.nativeElement.focus();