Zum Inhalt springen

Komponenten

Diese Seite sammelt die wiederkehrenden UI-Bausteine und legt fest, wie sie aussehen und sich verhalten. Die technische Basis ist Tailwind CSS mit shadcn/ui auf base-ui-Primitiven unter apps/web/components/ui/, die Icons stammen aus lucide-react. Es gilt eine einfache Grundregel: Bestehende Komponenten werden wiederverwendet, bevor neue Sonderlösungen entstehen. Die zugrunde liegenden Werte stehen in Farben & Typografie und Design-Tokens.

Buttons sind die zentralen Aktionsträger und folgen einer klaren Rangordnung. Eine Ansicht hebt höchstens eine primäre Aktion hervor, alles Übrige bleibt zurückhaltend. So ist immer erkennbar, was der nächste sinnvolle Schritt ist, ohne dass mehrere Flächen um Aufmerksamkeit konkurrieren.

  • Basis: apps/web/components/ui/button.tsx, ein base-ui-Button mit Varianten über cva.
  • Primär: variant="default" auf Primärrot. In einer farbigen Form-Card übernimmt .section-submit diese Rolle und erbt die Abschnittsfarbe.
  • Sekundär: variant="outline" oder ghost, nur Rahmen beziehungsweise eine dezente Hover-Fläche, ohne eigene Signalfarbe.
  • Destruktiv in zwei Stufen: Die Variante destructive ist getönt (bg-destructive/10 mit rotem Text) für alltägliche Lösch-Aktionen. Folgenschwere Bestätigungen tragen einen soliden roten Button (bg-red-600).
  • Größen: h-8 als Standard, h-7 und h-6 kompakt, h-9 prominent, dazu quadratische Icon-Buttons.
  • Verhalten: Hover verdunkelt die Fläche (color-mix(… 85%, #000)), beim Klick gibt der Button 1px nach (translate-y-px), siehe Bewegung.
  • Beschriftung: Kurze Verb- oder Nomen-Phrasen, siehe Tonalität.
Ruhezustand
Titel der Veranstaltung
Fokus · Abschnittsfarbe
Digitaler Vertrieb im Mittelstand
Fehler · destructive
Titel der Veranstaltung
Bitte einen Titel angeben.

Eingabefelder sind ruhig gestaltet und führen nur über Farbe, wenn etwas passiert. Im Ruhezustand tragen sie einen neutralen Rahmen, beim Fokus wechselt dieser auf die Abschnittsfarbe, im Fehlerfall auf das destructive-Rot. Die drei Zustände sind klar unterscheidbar, ohne grelle Flächen oder Unruhe.

  • Basis: apps/web/components/ui/input.tsx, Höhe h-8, Radius rounded-lg, Rahmen über das Theme-Token --input.
  • Fokus: Wechsel auf die Abschnittsfarbe mit einem weichen 2px-Halo (ring-2, 25 Prozent Deckung), außerhalb einer Section auf Primärrot.
  • Fehler: aria-invalid schaltet auf einen destructive-Rahmen samt Ring, darunter steht eine konkrete Meldung.
  • Pflichtfeld: <RequiredMark /> setzt ein rotes Sternchen in text-primary, rein dekorativ und für Screenreader ausgeblendet (aria-hidden). Niemals text-red-500 hartkodieren.
  • Volle Feld-Anatomie: Patterns → Formular-Design.
import { RequiredMark } from "@/components/ui/required-mark";
<label>Titel <RequiredMark /></label>

Natives <select> ist im Projekt verboten und wird per ESLint (no-restricted-syntax) unterbunden, damit Auswahlfelder überall gleich aussehen und gleich bedienbar bleiben. Stattdessen gibt es zwei abgestimmte Komponenten, je nachdem ob das Formular serverseitig oder mit Client-State arbeitet.

KontextKomponenteImport
Server-Formular (Form Action)<FormSelect>@/components/ui/form-select
Client-Komponente mit State<Select> + <SelectTrigger>@/components/ui/select

IconSelect ist die Popover-Variante mit einem Icon je Option. Die aktive Auswahl wird gedämpft hinterlegt, nicht solide eingefärbt:

CompanySizeSelect · accent=brand-blue · firstSeparator
Unternehmensgröße
10 bis 49
Keine Angabe
1 bis 9 Mitarbeitende
10 bis 49 Mitarbeitende
50 bis 249 Mitarbeitende
250 bis 499 Mitarbeitende
500+ Mitarbeitende
RoleSelect · accent=brand-amber
Rolle
Teilnehmende
Teilnehmende
Management
Format
Präsenz Online Hybrid

Direkt sichtbare Auswahl-Gruppen wie die Format- oder Statusauswahl zeigen ihren aktiven Zustand mit voller Farbe, damit er auf einen Blick erkennbar ist. Die Gruppe sitzt in einem farbigen Abschnitt und übernimmt dessen Farbe.

  • Aktiv: Solide Hintergrundfarbe in der Abschnittsfarbe plus text-white, Rahmen in derselben Farbe. Beispiel im blauen Abschnitt: border-brand-blue bg-brand-blue text-white.
  • Inaktiv: Nur ein grauer Rahmen mit gedämpftem Text, beim Überfahren wird der Rahmen etwas kräftiger.
  • Keine Opacity-Varianten: Kein bg-*/5 oder ähnlich blasser Ton für den aktiven Zustand, der Kontrast muss tragen.
  • Abgrenzung: In Popover-Panels gilt das Gegenteil, siehe Hinweis oben.

Badges kennzeichnen Zustände und Kategorien knapp und einheitlich. Sie sind immer pillenförmig, solide gefüllt und tragen weißen Text, unabhängig von der Fläche dahinter. Dadurch bleiben sie überall gleich lesbar.

  • Muster: Pillenform (rounded-4xl), solide Farbe, weißer Text.
  • Status-Badges: Globale Klassen badge-green, badge-amber und badge-slate, abgeleitet aus der Brand-Palette, siehe Status.
  • Typ- und Format-Badges: Brand-Farben direkt, zur Unterscheidung inhaltlicher Bereiche.

Die Audit-Ansicht färbt nach fachlichen Kategorien, nicht nach einzelnen Unterbereichen. Systemereignisse sind amber, und system.integration.* liegt bewusst innerhalb der System-Kategorie. Die vollständige Zuordnung steht unter Audit-Logging.