mirror of
https://github.com/bitwarden/browser
synced 2025-12-29 22:53:44 +00:00
[CL-934] Migrate breadcrumbs to OnPush (#17390)
Migrates BreadcrumbComponent and BreadcrumbsComponent to OnPush and changes any property to computed signals.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<ng-template>
|
||||
@if (icon(); as icon) {
|
||||
<i class="bwi {{ icon }} !tw-me-2" aria-hidden="true"></i>
|
||||
<i class="bwi !tw-me-2" [class]="icon" aria-hidden="true"></i>
|
||||
}
|
||||
<ng-content></ng-content>
|
||||
</ng-template>
|
||||
|
||||
@@ -1,29 +1,55 @@
|
||||
import { Component, EventEmitter, Output, TemplateRef, input, viewChild } from "@angular/core";
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
TemplateRef,
|
||||
input,
|
||||
output,
|
||||
viewChild,
|
||||
} from "@angular/core";
|
||||
import { QueryParamsHandling } from "@angular/router";
|
||||
|
||||
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
|
||||
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
|
||||
/**
|
||||
* Individual breadcrumb item used within the `bit-breadcrumbs` component.
|
||||
* Represents a single navigation step in the breadcrumb trail.
|
||||
*
|
||||
* This component should be used as a child of `bit-breadcrumbs` and supports both
|
||||
* router navigation and custom click handlers.
|
||||
*/
|
||||
@Component({
|
||||
selector: "bit-breadcrumb",
|
||||
templateUrl: "./breadcrumb.component.html",
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class BreadcrumbComponent {
|
||||
/**
|
||||
* Optional icon to display before the breadcrumb text.
|
||||
*/
|
||||
readonly icon = input<string>();
|
||||
|
||||
/**
|
||||
* Router link for the breadcrumb. Can be a string or an array of route segments.
|
||||
*/
|
||||
readonly route = input<string | any[]>();
|
||||
|
||||
/**
|
||||
* Query parameters to include in the router link.
|
||||
*/
|
||||
readonly queryParams = input<Record<string, string>>({});
|
||||
|
||||
/**
|
||||
* How to handle query parameters when navigating. Options include 'merge' or 'preserve'.
|
||||
*/
|
||||
readonly queryParamsHandling = input<QueryParamsHandling>();
|
||||
|
||||
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
|
||||
// eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref
|
||||
@Output()
|
||||
click = new EventEmitter();
|
||||
/**
|
||||
* Emitted when the breadcrumb is clicked.
|
||||
*/
|
||||
readonly click = output<unknown>();
|
||||
|
||||
/** Used by the BreadcrumbsComponent to access the breadcrumb content */
|
||||
readonly content = viewChild(TemplateRef);
|
||||
|
||||
onClick(args: unknown) {
|
||||
this.click.next(args);
|
||||
this.click.emit(args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@for (breadcrumb of beforeOverflow; track breadcrumb; let last = $last) {
|
||||
@for (breadcrumb of beforeOverflow(); track breadcrumb; let last = $last) {
|
||||
@if (breadcrumb.route(); as route) {
|
||||
<a
|
||||
bitLink
|
||||
@@ -26,8 +26,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
@if (hasOverflow) {
|
||||
@if (beforeOverflow.length > 0) {
|
||||
@if (hasOverflow()) {
|
||||
@if (beforeOverflow().length > 0) {
|
||||
<i class="bwi bwi-angle-right tw-mx-1.5 tw-text-main"></i>
|
||||
}
|
||||
<button
|
||||
@@ -38,7 +38,7 @@
|
||||
[label]="'moreBreadcrumbs' | i18n"
|
||||
></button>
|
||||
<bit-menu #overflowMenu>
|
||||
@for (breadcrumb of overflow; track breadcrumb) {
|
||||
@for (breadcrumb of overflow(); track breadcrumb) {
|
||||
@if (breadcrumb.route(); as route) {
|
||||
<a
|
||||
bitMenuItem
|
||||
@@ -57,7 +57,7 @@
|
||||
}
|
||||
</bit-menu>
|
||||
<i class="bwi bwi-angle-right tw-mx-1.5 tw-text-main"></i>
|
||||
@for (breadcrumb of afterOverflow; track breadcrumb; let last = $last) {
|
||||
@for (breadcrumb of afterOverflow(); track breadcrumb; let last = $last) {
|
||||
@if (breadcrumb.route(); as route) {
|
||||
<a
|
||||
bitLink
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { Component, ContentChildren, QueryList, input } from "@angular/core";
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
computed,
|
||||
contentChildren,
|
||||
input,
|
||||
} from "@angular/core";
|
||||
import { RouterModule } from "@angular/router";
|
||||
|
||||
import { I18nPipe } from "@bitwarden/ui-common";
|
||||
@@ -15,42 +21,39 @@ import { BreadcrumbComponent } from "./breadcrumb.component";
|
||||
* Bitwarden uses this component to indicate the user's current location in a set of data organized in
|
||||
* containers (Collections, Folders, or Projects).
|
||||
*/
|
||||
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
|
||||
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
|
||||
@Component({
|
||||
selector: "bit-breadcrumbs",
|
||||
templateUrl: "./breadcrumbs.component.html",
|
||||
imports: [I18nPipe, CommonModule, LinkModule, RouterModule, IconButtonModule, MenuModule],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class BreadcrumbsComponent {
|
||||
/**
|
||||
* The maximum number of breadcrumbs to show before overflow.
|
||||
*/
|
||||
readonly show = input(3);
|
||||
|
||||
private breadcrumbs: BreadcrumbComponent[] = [];
|
||||
protected readonly breadcrumbs = contentChildren(BreadcrumbComponent);
|
||||
|
||||
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
|
||||
// eslint-disable-next-line @angular-eslint/prefer-signals
|
||||
@ContentChildren(BreadcrumbComponent)
|
||||
protected set breadcrumbList(value: QueryList<BreadcrumbComponent>) {
|
||||
this.breadcrumbs = value.toArray();
|
||||
}
|
||||
/** Whether the breadcrumbs exceed the show limit and require an overflow menu */
|
||||
protected readonly hasOverflow = computed(() => this.breadcrumbs().length > this.show());
|
||||
|
||||
protected get beforeOverflow() {
|
||||
if (this.hasOverflow) {
|
||||
return this.breadcrumbs.slice(0, this.show() - 1);
|
||||
/** Breadcrumbs shown before the overflow menu */
|
||||
protected readonly beforeOverflow = computed(() => {
|
||||
const items = this.breadcrumbs();
|
||||
const showCount = this.show();
|
||||
|
||||
if (items.length > showCount) {
|
||||
return items.slice(0, showCount - 1);
|
||||
}
|
||||
return items;
|
||||
});
|
||||
|
||||
return this.breadcrumbs;
|
||||
}
|
||||
/** Breadcrumbs hidden in the overflow menu */
|
||||
protected readonly overflow = computed(() => {
|
||||
return this.breadcrumbs().slice(this.show() - 1, -1);
|
||||
});
|
||||
|
||||
protected get overflow() {
|
||||
return this.breadcrumbs.slice(this.show() - 1, -1);
|
||||
}
|
||||
|
||||
protected get afterOverflow() {
|
||||
return this.breadcrumbs.slice(-1);
|
||||
}
|
||||
|
||||
protected get hasOverflow() {
|
||||
return this.breadcrumbs.length > this.show();
|
||||
}
|
||||
/** The last breadcrumb, shown after the overflow menu */
|
||||
protected readonly afterOverflow = computed(() => this.breadcrumbs().slice(-1));
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component, importProvidersFrom } from "@angular/core";
|
||||
import { ChangeDetectionStrategy, Component, importProvidersFrom } from "@angular/core";
|
||||
import { RouterModule } from "@angular/router";
|
||||
import { Meta, StoryObj, applicationConfig, moduleMetadata } from "@storybook/angular";
|
||||
|
||||
@@ -18,10 +18,9 @@ interface Breadcrumb {
|
||||
route: string;
|
||||
}
|
||||
|
||||
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
|
||||
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
|
||||
@Component({
|
||||
template: "",
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
class EmptyComponent {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user