Files
MindSift/Doku/ui-patterns.md
T
sandrodachandClaude Opus 5.5 a62b204e14
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m30s
feat(ui): one CountBadge for all counters; counters on tab corners
- CountBadge component (accent / muted, inline / corner, 99+, showZero);
  used in the nav bar, task list and list tabs, admin organizations and
  numeric badges of the mobile menu; old badge-count removed
- Counters sit on the top right corner of tabs; "Alle Aufgaben" gets one
  (desktop tab and mobile menu)
- Open/done task counters include tasks in shared lists, matching what
  "Alle Aufgaben" shows (nav counter was too low)
- Theme template derives --accent-dim/--accent-border from the accent
- Docs: ui-patterns counters section

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 22:54:15 +01:00

4.2 KiB
Raw Blame History

UI-Muster

Wiederkehrende Bedienelemente, die überall gleich aussehen und sich gleich verhalten. Wer eines davon neu braucht, nimmt die vorhandene Komponente und baut keine eigene Variante.

Komponente: UserAutocomplete.tsx

Eingesetzt beim Teilen (UnifiedShareModal), beim Hinzufügen zu Gruppen (GroupsView) und beim Zuweisen von Aufgaben (TaskDetailModal).

  • Keine Liste vorab: Solange das Feld leer ist, erscheint nichts, auch nicht beim Reinklicken. Kein Dropdown mit allen Personen.
  • Erst beim Tippen erscheinen Treffer direkt unter dem Feld, höchstens 3 (MAX_RESULTS). Gesucht wird in Anzeigename, @Benutzername und E-Mail.
  • Der erste Treffer ist vorausgewählt: Tippen + Enter übernimmt ihn. Pfeiltasten wechseln, Escape schließt.
  • Bereits gewählte oder freigegebene Personen werden über excludeUserIds ausgeblendet.
  • Einzelauswahl (Teilen, Gruppen): selectedUser setzen; das Feld zeigt dann die gewählte Person mit ×.
  • Mehrfachauswahl (Aufgaben zuweisen): selectedUser={null} lassen und in onSelectUser zur Liste hinzufügen. Die Gewählten stehen als Chips (Avatar, Name, ×) über dem Feld, das Feld bleibt für die nächste Suche frei.

Profilbilder als Stapel

Komponente: AvatarStack.tsx (nutzt UserAvatar)

  • Kleine runde Profilbilder, leicht überlappend, höchstens 3. Weitere Personen erscheinen als monochromer Kreis „+n“.
  • Ohne Profilbild zeigt UserAvatar die Initialen.
  • ringClass bekommt die Farbe der Fläche dahinter (meist ring-[var(--bg-panel)] oder ring-[var(--bg-app)]), damit die Kreise sauber getrennt sind.
  • Größen: xxs (16 px) in Tabs, Kanban-Karten und Listeneinträgen, xs (20 px) in Aufgabenzeilen und Kopfzeilen.
  • Kein Hover-Effekt im Stapel selbst. Einzige Ausnahme ist die Anwesenheit in Notizen (PresenceAvatars.tsx): Dort zeigt Hover oder Tastaturfokus die Liste „Gerade online“.
Ort Wer wird gezeigt
Notiz-Kopfzeile wer die Notiz gerade geöffnet hat (Profilbilder aus /users/directory)
Tabs der Aufgabenlisten und Listen alle mit Zugriff außer mir (members)
Aufgabenzeile und Kanban-Karte zugewiesene Personen (nur in geteilten Listen)
Eintrag einer geteilten Liste wer ihn hinzugefügt hat (createdBy); ältere Einträge ohne Autor zeigen nichts

Schalter

Komponente: ToggleSwitch.tsx

  • Ein/Aus-Einstellungen sind immer Schalter, keine Checkbox-Haken (Einrichtung, Admin-Bereich).
  • Text links (Titel, darunter eine kurze Erklärung in text-muted), Schalter rechts.

Zähler

Komponente: CountBadge.tsx, CSS-Klassen count-badge* in index.css. Es gibt keine anderen Zähler-Stile mehr.

  • Form: runder Kreis, mindestens 16 px, ab 100 als „99+“ (der Screenreader liest die echte Zahl). Bei 0 ausgeblendet, außer mit showZero (z. B. Mitgliederzahl, mobiles Menü).
  • Farbe (variant):
    • accent: Hier wartet etwas auf dich. Navigationsleiste (Triage, Workspace, Aufgaben).
    • 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.
    • 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.