diff --git a/libs/components/src/breadcrumbs/breadcrumb.component.html b/libs/components/src/breadcrumbs/breadcrumb.component.html
index b0334f1ac09..bca34bb0e8b 100644
--- a/libs/components/src/breadcrumbs/breadcrumb.component.html
+++ b/libs/components/src/breadcrumbs/breadcrumb.component.html
@@ -1,6 +1,6 @@
@if (icon(); as icon) {
-
+
}
diff --git a/libs/components/src/breadcrumbs/breadcrumb.component.ts b/libs/components/src/breadcrumbs/breadcrumb.component.ts
index 6c79b449a28..18024c0ef20 100644
--- a/libs/components/src/breadcrumbs/breadcrumb.component.ts
+++ b/libs/components/src/breadcrumbs/breadcrumb.component.ts
@@ -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();
+ /**
+ * Router link for the breadcrumb. Can be a string or an array of route segments.
+ */
readonly route = input();
+ /**
+ * Query parameters to include in the router link.
+ */
readonly queryParams = input>({});
+ /**
+ * How to handle query parameters when navigating. Options include 'merge' or 'preserve'.
+ */
readonly queryParamsHandling = input();
- // 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();
+ /** Used by the BreadcrumbsComponent to access the breadcrumb content */
readonly content = viewChild(TemplateRef);
onClick(args: unknown) {
- this.click.next(args);
+ this.click.emit(args);
}
}
diff --git a/libs/components/src/breadcrumbs/breadcrumbs.component.html b/libs/components/src/breadcrumbs/breadcrumbs.component.html
index b63b21de76b..ee5ad79c739 100644
--- a/libs/components/src/breadcrumbs/breadcrumbs.component.html
+++ b/libs/components/src/breadcrumbs/breadcrumbs.component.html
@@ -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) {
0) {
+@if (hasOverflow()) {
+ @if (beforeOverflow().length > 0) {
}
- @for (breadcrumb of overflow; track breadcrumb) {
+ @for (breadcrumb of overflow(); track breadcrumb) {
@if (breadcrumb.route(); as route) {
- @for (breadcrumb of afterOverflow; track breadcrumb; let last = $last) {
+ @for (breadcrumb of afterOverflow(); track breadcrumb; let last = $last) {
@if (breadcrumb.route(); as route) {
) {
- 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));
}
diff --git a/libs/components/src/breadcrumbs/breadcrumbs.stories.ts b/libs/components/src/breadcrumbs/breadcrumbs.stories.ts
index 3064ffe3cb4..d0ce221a780 100644
--- a/libs/components/src/breadcrumbs/breadcrumbs.stories.ts
+++ b/libs/components/src/breadcrumbs/breadcrumbs.stories.ts
@@ -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 {}