fix(ui): tab counters sit on the label like in the nav bar

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
sandrodachandClaude Opus 5.5 committed 2026-10-28 23:21:20 +01:00
1 parent e509f685c1
commit b07a7acf42
3 files changed
+19 -11

No files matched your search

+1 -1
View File
@@ -49,7 +49,7 @@ Komponente: [CountBadge.tsx](../frontend/src/components/CountBadge.tsx), CSS-Kla
- `muted` (Standard): reine Anzahl. Tabs der Aufgabenlisten und Listen, Organisationen, mobiles Menü.
- Beide kommen aus den Theme-Variablen (`--accent-primary`/`--text-on-accent` bzw. `--text-muted`/`--bg-panel`) und passen sich damit jedem Theme an.
- **Position (`position`):**
- `corner`: Benachrichtigungs-Badge oben rechts am nächsten `relative` Elternelement, mit Ring in der Seitenfarbe. So in der Navigation und an den Tabs. Zeilen mit solchen Tabs brauchen etwas Abstand (`gap-x-3`, `pt-2`), damit der Kreis nicht in den Nachbar-Tab ragt.
- `corner`: Benachrichtigungs-Badge oben rechts am nächsten `relative` Elternelement, mit Ring in der Seitenfarbe. In der Navigation und an den Tabs sitzt er **auf dem Text**: der Text steht in einem `relative inline-flex`-Span (mit `pr-2`, solange ein Zähler da ist), der Kreis bekommt `-top-1.5 -right-1`.
- `inline`: im Textfluss.
- Zahlen im mobilen Menü (`MobileActionContext`, `badge: number`) werden automatisch als `CountBadge` gezeigt; Text-Badges wie „2 aktiv“ bleiben Textmarken.
- **Wichtig für neue Klassen:** Tailwind entfernt Klassen aus `@layer components`, die nicht wörtlich im Code stehen. Klassennamen deshalb nie zusammensetzen (`count-badge-${variant}`), sondern ausschreiben.
@@ -843,8 +843,8 @@ export const SharedListsView: React.FC<SharedListsViewProps> = ({ onRefreshGloba
<div className="w-full space-y-3">
{/* Top Header: List Tabs & Actions (Desktop) */}
<div className="hidden sm:flex flex-wrap items-center justify-between gap-2 border-b border-border pb-2 !mt-0">
{/* List Tabs (counters sit on the top right corner, hence the extra gap) */}
<div className="flex flex-wrap items-center gap-x-3 gap-y-3 pt-2">
{/* List Tabs */}
<div className="flex flex-wrap items-center gap-1">
{lists.map((lst) => {
const openCount = deduplicateItems(lst.items || []).filter((i) => !i.isCompleted).length;
const isSelected = activeList?.id === lst.id;
@@ -860,7 +860,11 @@ export const SharedListsView: React.FC<SharedListsViewProps> = ({ onRefreshGloba
className="h-full px-3 text-xs font-medium flex items-center gap-1.5 rounded-btn"
>
<span>{lst.icon}</span>
<span>{lst.title}</span>
{/* Counter on the label, like in the nav bar */}
<span className={`relative inline-flex items-center ${openCount > 0 ? 'pr-2' : ''}`}>
{lst.title}
<CountBadge count={openCount} position="corner" className="-top-1.5 -right-1" />
</span>
<AvatarStack
people={otherMembers(lst)}
size="xxs"
@@ -868,7 +872,6 @@ export const SharedListsView: React.FC<SharedListsViewProps> = ({ onRefreshGloba
className="ml-0.5"
/>
</button>
<CountBadge count={openCount} position="corner" />
{isSelected && lists.length > 1 && (
<button
onClick={() => handleDeleteList(lst.id)}
+11 -6
View File
@@ -1373,18 +1373,21 @@ export const TasksView: React.FC<TasksViewProps> = ({
<div className="w-full space-y-3">
{/* Top Header: Task Lists Tabs & View Mode Switcher (Desktop) */}
<div className="hidden sm:flex flex-wrap items-center justify-between gap-2 border-b border-border pb-2 !mt-0">
{/* Task Lists selector tabs (counters sit on the top right corner, hence the extra gap) */}
<div className="flex flex-wrap items-center gap-x-3 gap-y-3 pt-2">
{/* Task Lists selector tabs */}
<div className="flex flex-wrap items-center gap-1">
<button
onClick={() => setSelectedListId('all')}
className={`relative h-8 px-3 text-xs font-medium border rounded-btn transition-colors ${
className={`h-8 px-3 text-xs font-medium border rounded-btn transition-colors ${
selectedListId === 'all'
? 'bg-panel border-accent text-main'
: 'bg-canvas border-border text-muted hover:text-main'
}`}
>
{/* Counter on the label, like in the nav bar */}
<span className={`relative inline-flex items-center ${openTasksCount ? 'pr-2' : ''}`}>
Alle Aufgaben
<CountBadge count={openTasksCount} position="corner" />
<CountBadge count={openTasksCount} position="corner" className="-top-1.5 -right-1" />
</span>
</button>
{safeTaskLists.map((tl) => (
@@ -1399,7 +1402,10 @@ export const TasksView: React.FC<TasksViewProps> = ({
className="h-full px-3 text-xs font-medium flex items-center gap-1.5 rounded-btn"
>
<span>{tl.icon}</span>
<span>{tl.title}</span>
<span className={`relative inline-flex items-center ${tl.tasksCount ? 'pr-2' : ''}`}>
{tl.title}
<CountBadge count={tl.tasksCount} position="corner" className="-top-1.5 -right-1" />
</span>
{(() => {
const isShared = (tl.shares && tl.shares.length > 0) || (tl.members && tl.members.length > 1);
@@ -1422,7 +1428,6 @@ export const TasksView: React.FC<TasksViewProps> = ({
);
})()}
</button>
<CountBadge count={tl.tasksCount} position="corner" />
{selectedListId === tl.id && (
<button
onClick={() => handleDeleteTaskList(tl.id)}