Filtrer la frise par tag
Les tags s'affichent en pastilles colorées dans la colonne des libellés, et une barre de filtres apparaît sous la barre d'outils dès qu'un tag existe. Cliquer un tag — dans cette barre ou directement sur la pastille d'un projet — restreint la frise ; recliquer le retire. Le filtre est conjonctif : un projet doit porter tous les tags cochés. Cocher un tag de plus resserre donc toujours la sélection, sans jamais faire se repeupler la frise. Un message dédié prend la place de la frise quand plus rien ne passe le filtre, sans quoi elle laisserait croire que les projets ont disparu. Le filtre est un état de vue, jamais enregistré, au même titre que la fenêtre temporelle. Il ne fait pas le même travail que le masquage par l'œil, qui reste enregistré : le filtre retire le projet de la vue entière, l'œil garde son libellé grisé et n'ôte que les barres. Deux ajustements de confort : créer un projet sous filtre actif préremplit ses tags avec ceux du filtre, sinon le nouveau venu naîtrait invisible ; et un tag que plus aucun projet ne porte est retiré du filtre, sinon il masquerait tout. Le dialogue d'un projet gagne un champ de saisie et propose en un clic les tags déjà employés ailleurs, seul garde-fou contre la dérive orthographique. Dans la colonne des libellés, les pastilles rognent le nom du projet mais lui laissent quatre caractères, et s'effacent à leur tour plutôt que de repousser l'œil et le menu hors de la colonne. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
105
css/style.css
105
css/style.css
@@ -140,6 +140,101 @@ button[aria-pressed="true"] {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* --- barre de filtres ----------------------------------------------------- */
|
||||
|
||||
.filtres {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 7px 16px;
|
||||
background: var(--surface);
|
||||
border-bottom: 1px solid var(--bordure);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.filtres__titre {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: var(--texte-doux);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.filtres button:not(.tag) {
|
||||
font-size: 12px;
|
||||
padding: 3px 9px;
|
||||
margin-left: auto;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* --- tags ----------------------------------------------------------------- */
|
||||
|
||||
/* Chaque pastille porte sa teinte dans `--teinte-tag`, calculée par hachage du
|
||||
nom du tag (model.js). La saturation et la clarté restent fixes, elles : ce
|
||||
sont elles qui garantissent le contraste, quelle que soit la teinte tirée. */
|
||||
.tags {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.tags--filtres,
|
||||
.tags--suggestions {
|
||||
flex-wrap: wrap;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.tag {
|
||||
font: inherit;
|
||||
font-size: 10px;
|
||||
font-weight: 500;
|
||||
line-height: 1.6;
|
||||
padding: 0 6px;
|
||||
max-width: 84px;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 9px;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
background: hsl(var(--teinte-tag) 62% 92%);
|
||||
color: hsl(var(--teinte-tag) 55% 27%);
|
||||
}
|
||||
|
||||
.tags--filtres .tag,
|
||||
.tags--suggestions .tag {
|
||||
font-size: 11px;
|
||||
padding: 1px 9px;
|
||||
max-width: none;
|
||||
border-radius: 11px;
|
||||
}
|
||||
|
||||
.tag:hover {
|
||||
border-color: hsl(var(--teinte-tag) 45% 55%);
|
||||
}
|
||||
|
||||
/* Un tag actif s'inverse : le fond prend la teinte pleine. Il faut donc
|
||||
neutraliser la règle générale `button[aria-pressed="true"]`, qui repeindrait
|
||||
toutes les pastilles de la même couleur d'accent. */
|
||||
.tag[aria-pressed="true"] {
|
||||
background: hsl(var(--teinte-tag) 52% 38%);
|
||||
border-color: hsl(var(--teinte-tag) 52% 38%);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.tag {
|
||||
background: hsl(var(--teinte-tag) 34% 24%);
|
||||
color: hsl(var(--teinte-tag) 62% 76%);
|
||||
}
|
||||
|
||||
.tag[aria-pressed="true"] {
|
||||
background: hsl(var(--teinte-tag) 58% 62%);
|
||||
border-color: hsl(var(--teinte-tag) 58% 62%);
|
||||
color: #0f172a;
|
||||
}
|
||||
}
|
||||
|
||||
/* --- structure de la frise ------------------------------------------------ */
|
||||
|
||||
/* Un seul conteneur défilant, sur les deux axes. L'en-tête et la colonne des
|
||||
@@ -286,12 +381,22 @@ button[aria-pressed="true"] {
|
||||
|
||||
.libelle-projet__nom {
|
||||
flex: 1;
|
||||
/* Le nom cède la place aux pastilles, mais jamais entièrement : sous quatre
|
||||
caractères il ne resterait qu'un « … » qui n'identifie plus rien. */
|
||||
min-width: 4em;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Les pastilles rognent le nom, pas l'inverse — mais elles s'effacent à leur
|
||||
tour plutôt que de repousser l'œil et le menu hors de la colonne. */
|
||||
.libelle-projet .tags {
|
||||
flex: 0 1 auto;
|
||||
max-width: 45%;
|
||||
}
|
||||
|
||||
.libelle-projet__derive {
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
|
||||
Reference in New Issue
Block a user