fix(icons): replace broken Material-icon-ligature text with app-icon in search suggestions

Search suggestions/popular-searches (search-autocomplete.service.ts,
search.facade.ts) set icon values like 'inventory_2', 'category', 'sell',
'auto_awesome', 'trending_up' - Material Symbols ligature names rendered as
raw {{ item.icon }} text in search-bar.component.html. No Material Icons
font is loaded anywhere in this Lucide/app-icon-based app, so these
rendered as literal garbled text ("inventory_2", etc.) instead of icons.

- SearchSuggestion.icon retyped from string to AppIconName (search.model.ts)
- Suggestion icon values mapped to registered app-icon names: product->package,
  category->folder, brand->tag, ai->zap, popular/trending->trendingUp (new
  registry entry, LucideTrendingUp)
- search-bar.component now renders <app-icon [name]="item.icon" /> instead of
  the raw ligature string, and its icon-only clear ("x") button now renders
  app-icon name="x" instead of a bare literal "x" character glyph

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
sdarbinyan
2026-07-25 20:15:36 +04:00
parent 5b3f969dfd
commit 6d663eb238
7 changed files with 24 additions and 16 deletions

View File

@@ -26,7 +26,9 @@
<span class="loading-dot" [attr.aria-label]="'search.searching' | translate"></span>
}
<button type="button" class="search-clear-btn" [disabled]="!query" (click)="clearQuery()" [attr.aria-label]="'catalog.clearSearch' | translate">×</button>
<button type="button" class="search-clear-btn" [disabled]="!query" (click)="clearQuery()" [attr.aria-label]="'catalog.clearSearch' | translate">
<app-icon name="x" [size]="16" />
</button>
<button type="submit" [disabled]="loading">{{ 'catalog.searchSubmit' | translate }}</button>
</form>
@@ -44,7 +46,7 @@
[attr.aria-selected]="$index === activeSuggestionIndex()"
[attr.aria-label]="suggestionLabel(item)"
(click)="selectSuggestion(item)">
<span class="suggestion-icon" aria-hidden="true">{{ item.icon }}</span>
<span class="suggestion-icon" aria-hidden="true"><app-icon [name]="item.icon" [size]="16" /></span>
<span class="suggestion-copy">
<span class="suggestion-title">{{ item.title }}</span>
@if (item.subtitle) {

View File

@@ -59,11 +59,13 @@
.search-clear-btn {
min-width: 44px;
min-height: 44px;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid var(--border-color) !important;
border-radius: var(--radius-sm);
background: var(--bg-primary) !important;
color: var(--text-secondary) !important;
font-size: var(--font-size-2xl, 1.25rem);
line-height: 1;
}
@@ -98,8 +100,8 @@
}
.suggestion-icon {
font-size: var(--font-size-xs, 0.75rem);
text-transform: uppercase;
display: flex;
align-items: center;
color: var(--text-secondary);
}

View File

@@ -2,12 +2,13 @@ import { ChangeDetectionStrategy, Component, EventEmitter, HostListener, Input,
import { FormsModule } from '@angular/forms';
import { SearchSuggestion } from '../../models/search.model';
import { TranslatePipe } from '../../../../i18n/translate.pipe';
import { IconComponent } from '../../../../shared/ui/icon/icon.component';
import { TrendingSearchesComponent } from '../trending-searches/trending-searches.component';
@Component({
selector: 'app-search-bar',
standalone: true,
imports: [FormsModule, TranslatePipe, TrendingSearchesComponent],
imports: [FormsModule, TranslatePipe, IconComponent, TrendingSearchesComponent],
templateUrl: './search-bar.component.html',
styleUrls: ['./search-bar.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush

View File

@@ -59,7 +59,7 @@ export class SearchFacade {
type: 'collection',
title: 'Smartphones',
text: 'Smartphones',
icon: 'trending_up',
icon: 'trendingUp',
target: { route: '/search', query: { q: 'Smartphones' } }
},
{
@@ -67,7 +67,7 @@ export class SearchFacade {
type: 'collection',
title: 'Sneakers',
text: 'Sneakers',
icon: 'trending_up',
icon: 'trendingUp',
target: { route: '/search', query: { q: 'Sneakers' } }
},
{
@@ -75,7 +75,7 @@ export class SearchFacade {
type: 'collection',
title: 'Headphones',
text: 'Headphones',
icon: 'trending_up',
icon: 'trendingUp',
target: { route: '/search', query: { q: 'Headphones' } }
},
{
@@ -83,7 +83,7 @@ export class SearchFacade {
type: 'collection',
title: 'Laptops',
text: 'Laptops',
icon: 'trending_up',
icon: 'trendingUp',
target: { route: '/search', query: { q: 'Laptops' } }
},
];

View File

@@ -1,4 +1,5 @@
import { Product, ProductSort } from '../../../core/products/models/product-domain.model';
import { AppIconName } from '../../../shared/ui/icon/icon-registry';
export type SearchFilterType =
| 'checkbox'
@@ -33,7 +34,7 @@ export interface SearchSuggestion {
text: string;
kind?: 'live' | 'recent' | 'popular';
subtitle?: string;
icon: string;
icon: AppIconName;
target: SearchNavigationTarget;
score?: number;
}

View File

@@ -22,7 +22,7 @@ export class SearchAutocompleteService {
text: item.name,
kind: 'live' as const,
subtitle: item.simpleDescription ?? '',
icon: 'inventory_2',
icon: 'package',
target: { route: '/product', params: { id: item.itemID } },
score: this.score(item.name, normalized),
}))
@@ -39,7 +39,7 @@ export class SearchAutocompleteService {
text: item.title,
kind: 'live' as const,
subtitle: '',
icon: 'category',
icon: 'folder',
target: { route: '/catalog', params: { id: item.id } },
score: this.score(item.title, normalized),
}))
@@ -57,7 +57,7 @@ export class SearchAutocompleteService {
text: tag,
kind: 'live' as const,
subtitle: '',
icon: 'sell',
icon: 'tag',
target: { route: '/search', query: { q: tag } },
score: this.score(tag, normalized),
}))
@@ -71,7 +71,7 @@ export class SearchAutocompleteService {
text: query,
kind: 'live',
subtitle: 'search.aiSuggestionHint',
icon: 'auto_awesome',
icon: 'zap',
target: { route: '/search', query: { q: query } },
score: 0,
}

View File

@@ -73,6 +73,7 @@ import {
LucideThumbsDown as ThumbsDown,
LucideThumbsUp as ThumbsUp,
LucideTrash2 as Trash2,
LucideTrendingUp as TrendingUp,
LucideTriangleAlert as TriangleAlert,
LucideUpload as Upload,
LucideUser as User,
@@ -171,7 +172,8 @@ export const APP_ICONS = {
verified: BadgeCheck,
video: Video,
circle: Circle,
zap: Zap
zap: Zap,
trendingUp: TrendingUp
} as const;
export type AppIconName = keyof typeof APP_ICONS;