feat(search): repli des rails filtres + boutons sources en icones
CI / build-and-test (push) Successful in 14m10s
CI / build-and-test (push) Successful in 14m10s
- nouveau bouton oeil a droite de 'Filtres' pour replier le bloc types + sources (railsOpen, persiste en localStorage) ; pastille d'accent quand un filtre de type est actif alors que le rail est replie - nouveau composant app-provider-icon : marques des 6 sources en trait, currentColor pour que l'icone herite de l'etat actif/masque du bouton - pastilles sources en icone seule (h-8 w-8), libelle et compte passes par aria-label / title ; plus de point de couleur ni de nom visible - suppression de PROVIDER_DOTS et providerDotStyle
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||
|
||||
/** Clés courtes du registre fournisseurs (provider-registry.ts). */
|
||||
export type ProviderIconKey = 'yt' | 'dm' | 'tw' | 'pt' | 'od' | 'ru';
|
||||
|
||||
/**
|
||||
* Marque d'une source, dessinée au trait et colorée en `currentColor` :
|
||||
* - l'icône hérite de la couleur du bouton, donc l'état actif / masqué
|
||||
* reste lisible sans ajouter une pastille de couleur à côté ;
|
||||
* - un seul style graphique pour les six sources, cohérent avec les icônes
|
||||
* d'interface (œil, chevron…) de la même barre.
|
||||
*
|
||||
* Les formes sont volontairement géométriques et sobres : l'identité vient du
|
||||
* geste (bouton lecture, bulle de discussion, initiale), pas d'un logo coloré
|
||||
* qui ne serait plus lisible une fois réduit à 18 px.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'app-provider-icon',
|
||||
standalone: true,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
template: `
|
||||
@switch (normalized) {
|
||||
@case ('yt') {
|
||||
<!-- YouTube : cadre arrondi + triangle de lecture -->
|
||||
<svg [attr.width]="size" [attr.height]="size" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<rect x="2.5" y="5.5" width="19" height="13" rx="4" />
|
||||
<path d="M10.4 9.4v5.2l4.4-2.6-4.4-2.6Z" fill="currentColor" stroke="none" />
|
||||
</svg>
|
||||
}
|
||||
@case ('tw') {
|
||||
<!-- Twitch : bulle de discussion + deux yeux -->
|
||||
<svg [attr.width]="size" [attr.height]="size" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<path d="M4 3h16v11.2L14.8 19.4h-4.3L7.2 22.7V19.4H4V3Z" />
|
||||
<path d="M9.2 8.4v2.8M14.8 8.4v2.8" />
|
||||
</svg>
|
||||
}
|
||||
@case ('dm') {
|
||||
<!-- Dailymotion : « D » -->
|
||||
<svg [attr.width]="size" [attr.height]="size" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<path d="M5.5 4.5v15" />
|
||||
<path d="M5.5 4.5h4.2a7.5 7.5 0 0 1 0 15H5.5" />
|
||||
</svg>
|
||||
}
|
||||
@case ('pt') {
|
||||
<!-- PeerTube : « P » -->
|
||||
<svg [attr.width]="size" [attr.height]="size" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<path d="M7.5 20V4.5h5.6a5.4 5.4 0 0 1 0 10.8H7.5" />
|
||||
</svg>
|
||||
}
|
||||
@case ('od') {
|
||||
<!-- Odysee : « O » barré -->
|
||||
<svg [attr.width]="size" [attr.height]="size" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<circle cx="12" cy="12" r="8.2" />
|
||||
<path d="M8.3 15.7 15.7 8.3" />
|
||||
</svg>
|
||||
}
|
||||
@case ('ru') {
|
||||
<!-- Rumble : « R » -->
|
||||
<svg [attr.width]="size" [attr.height]="size" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<path d="M6 20V4.5h6.2a4.6 4.6 0 0 1 0 9.2H6" />
|
||||
<path d="M12.4 13.7 17.6 20" />
|
||||
</svg>
|
||||
}
|
||||
}
|
||||
`
|
||||
})
|
||||
export class ProviderIconComponent {
|
||||
/** Clé courte du fournisseur. Inconnue => aucun rendu. */
|
||||
@Input() key: ProviderIconKey | string | null | undefined;
|
||||
/** Taille en px (carré). */
|
||||
@Input() size = 18;
|
||||
|
||||
/** Clé normalisée ; seules les six clés connues dessinent quelque chose. */
|
||||
get normalized(): ProviderIconKey | null {
|
||||
const k = String(this.key || '').toLowerCase();
|
||||
return (['yt', 'dm', 'tw', 'pt', 'od', 'ru'] as const).includes(k as ProviderIconKey)
|
||||
? (k as ProviderIconKey)
|
||||
: null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user