refactor: extract shared app-breadcrumb component (Z14)
Only breadcrumb logic anywhere in the storefront was a local signal + inline markup inside catalog-container. Extracted a generic shared/ui/breadcrumb component (rootLabel/items/ariaLabel inputs, rootClick/itemClick outputs) and repointed catalog-container onto it, removing the now-dead inline SCSS block. Future breadcrumb usages (product detail, admin) have something to reuse instead of duplicating. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
7
src/app/shared/ui/breadcrumb/breadcrumb.component.html
Normal file
7
src/app/shared/ui/breadcrumb/breadcrumb.component.html
Normal file
@@ -0,0 +1,7 @@
|
||||
<nav class="app-breadcrumb" [attr.aria-label]="ariaLabel() || null">
|
||||
<button type="button" (click)="rootClick.emit()">{{ rootLabel() }}</button>
|
||||
@for (item of items(); track item.id) {
|
||||
<span aria-hidden="true">/</span>
|
||||
<button type="button" (click)="itemClick.emit(item)">{{ item.label }}</button>
|
||||
}
|
||||
</nav>
|
||||
19
src/app/shared/ui/breadcrumb/breadcrumb.component.scss
Normal file
19
src/app/shared/ui/breadcrumb/breadcrumb.component.scss
Normal file
@@ -0,0 +1,19 @@
|
||||
.app-breadcrumb {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
color: var(--text-secondary);
|
||||
font-size: var(--font-size-md, 0.9375rem);
|
||||
|
||||
button {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
color: var(--primary-color);
|
||||
font: inherit;
|
||||
font-weight: var(--font-weight-bold, 700);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
26
src/app/shared/ui/breadcrumb/breadcrumb.component.ts
Normal file
26
src/app/shared/ui/breadcrumb/breadcrumb.component.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { ChangeDetectionStrategy, Component, input, output } from '@angular/core';
|
||||
|
||||
export interface BreadcrumbItem {
|
||||
id: string | number;
|
||||
label: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic breadcrumb trail. Consumer owns navigation - this component only
|
||||
* renders the trail and emits which item was clicked (root or a trail item).
|
||||
*/
|
||||
@Component({
|
||||
selector: 'app-breadcrumb',
|
||||
standalone: true,
|
||||
templateUrl: './breadcrumb.component.html',
|
||||
styleUrl: './breadcrumb.component.scss',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class BreadcrumbComponent {
|
||||
readonly rootLabel = input.required<string>();
|
||||
readonly items = input<BreadcrumbItem[]>([]);
|
||||
readonly ariaLabel = input<string>('');
|
||||
|
||||
readonly rootClick = output<void>();
|
||||
readonly itemClick = output<BreadcrumbItem>();
|
||||
}
|
||||
Reference in New Issue
Block a user