Mall-OS UI (@mall-os/ui)
Das Dashboard und viele Tools bauen auf dem gemeinsamen Paket @mall-os/ui auf (Tailwind v4, Radix-Primitives, shadcn-artige Komponenten). Styling und Verhalten sollen zentral angepasst werden, nicht pro Seite dupliziert.
Theme & Farben
- Single Source of Truth:
packages/ui/src/cockpit-dashboard-theme.css— alle Design-Tokens als HSL-Komponenten (--background: 216 20% 97%…), damit Dashboard (Tailwind v3) und@mall-os/ui(Tailwind v4) dieselben Werte nutzen. - Dashboard: importiert die Datei in
apps/dashboard/src/app/globals.cssvia@import "@mall-os/ui/cockpit-dashboard-theme.css". - UI-Paket:
packages/ui/src/styles.cssimportiert dieselbe Datei und mappt@theme inlineaufhsl(var(--…)). - Seiten-Hintergrund (hell):
--backgroundentspricht etwa#f6f7f9; Karten (--card) und Sidebar bleiben weiß für klaren Kontrast. - Primärfarbe: klares Blau für CTAs, Fokus und aktive Sidebar-Elemente (hell/dunkel jeweils abgestimmt).
- Radius:
--radiussteuertrounded-*über die Theme-Skala (radius-sm…radius-xl). - Sekundärtext:
--muted-foreground(und verwandte Flächen wie--muted) sind so gesetzt, dass Hilfstext und Beschreibungen auf hellen Hintergründen lesbar bleiben (ausreichender Kontrast zu grauen Flächen).
Änderungen an der „globalen Optik“ gehören in cockpit-dashboard-theme.css (nicht doppelt in globals.css pflegen).
Dialog, AlertDialog & Sheet (Modals)
- Inhalt:
bg-card/text-card-foreground(nichtbg-background), damit das Fenster sich von der Seitenfläche abhebt. - Overlay: etwa
bg-black/55undbackdrop-blur-smfür eine klare Dim-Schicht. - Erhöhung:
shadow-2xlund dezenterringfür Tiefe. - z-index:
z-[10400]— über Dropdown-Popovern, die im Dashboard oft~9999nutzen; gleiche Schicht für Dialog, AlertDialog und Sheet.
Implementierung: packages/ui/src/components/ui/dialog.tsx, alert-dialog.tsx, sheet.tsx. Eigene „Fullscreen“-Overlays im Dashboard sollten dieselbe z-Schicht und ähnliche Card-Optik nutzen, statt z-[200] + Seiten-Hintergrundfarbe.
Dashboard-Audit (manuell): u. a. content/hot-picks, scheduling/videos, Galerie-Lightbox (gallery-block.plugin), wordpress/websites.old — Overlays auf z-[10400] + bg-black/55 / backdrop-blur-sm bzw. Lightbox bewusst dunkel. Weitere Apps (center-website-Template-Kopien von dialog.tsx, digital-signage, center-manager) nutzen noch eigene z-50-Varianten; dort bei Bedarf nachziehen oder auf @mall-os/ui umstellen.
- Form controls:
Input,SelectTriggerundTextareanutzen durchgängigbg-card,border-border,h-11(Input/Select default),shadow-smund gleiche Focus-Ringe — damit Suche und Dropdowns auf grauem Seitenhintergrund gleich wirken. Filter-Leisten: Icon links im Trigger überflex min-w-0 flex-1+SelectValue; Suche mit Lupen-Icon (Search), nicht mit Filter-Icon. - Select & DropdownMenu (kein Layout-Sprung): Beide nutzen in
@mall-os/uistandardmäßigmodal={false}(select.tsx,dropdown-menu.tsx). So setzt Radix keinen Body-Scroll-Lock; die Seite springt nicht horizontal, wenn ein Menü aufgeht. Zusätzlich verhindernSelectContent/DropdownMenuContentperonOpenAutoFocus→preventDefault()das browserseitige Scrollen zum fokussierten Portal (typisches „Zucken“ bei langen Seiten). Für Einzelfälle kannmodal={true}gesetzt werden (z. B. stärkere Fokus-Falle). Zusätzlich reserviert das Dashboard inglobals.cssmitscrollbar-gutter: stablePlatz für die Scrollbar.
Dashboard-Layout-Shell
Das feste Chrome (Sidebar-Inset, Sticky-Header, Content-Padding) liegt zentral in apps/dashboard/src/components/cockpit-dashboard-shell.tsx (CockpitDashboardShell, cockpitDashboardShellClasses). Das Dashboard-Layout bindet diese Komponente ein, statt Klassen zu duplizieren.
Action-Buttons
ActionButton / CreateButton / … in packages/ui/src/components/ui/action-button.tsx nutzen Button-Varianten (default, outline, destructive, ghost, success) und ergänzende className-Tokens (primary, success, muted, border …) statt fester Tailwind-Farben wie blue-600.
Bunny-Upload-Typen
BunnyUploadFolderTypewird inpackages/ui/src/hooks/use-bunny-upload.tsexportiert und beschreibt erlaubtetype-Werte für Uploads (inkl. Dashboard-spezifischer Ordner wietile,shop-chain,themes,dooh,wayfinding,videos,images).- Das Dashboard importiert diesen Typ für
apps/dashboard/src/hooks/use-bunny-upload.tsundbunny-upload.tsx, damit Props und Hook dieselbe Union nutzen.
Button & Dashboard-@/components/ui/*
- Primitives: Formular-, Layout- und Overlay-Komponenten (Input, Card, Dialog, Tabs, Sidebar, Toast, …) werden im Dashboard als Re-Export aus
@mall-os/uigeführt — eine Implementierung unterpackages/ui/src/components/ui/, Pfade wie@/components/ui/inputbleiben gültig. - Ausnahmen (lokal im Dashboard):
bunny-upload.tsx(erweiterte Upload-Typen + Dashboard-Hook),simple-rich-text-editor.tsx,rich-text-editor.tsx,safe-html-content.tsx. - Button:
packages/ui/src/components/ui/button.tsx(Button,buttonVariants); Dashboard-Datei re-exportiert. - Tailwind: Dashboard-
contententhält../../packages/ui/src/**, damit Klassen aus dem Paket im JIT ankommen.
Kernkomponenten (Auszug)
| Bereich | Datei unter packages/ui/src/components/ui/ |
|---|---|
| Buttons, Inputs, Textarea | button.tsx, input.tsx, textarea.tsx |
| Auswahl | select.tsx, checkbox.tsx, radio-group.tsx, switch.tsx |
| Überlagerungen | dialog.tsx, alert-dialog.tsx, sheet.tsx, popover.tsx |
| Menüs & Toasts | dropdown-menu.tsx, sonner.tsx, toast.tsx |
| Tabs | tabs.tsx |
| Karten & Layout | card.tsx, separator.tsx, page-layout.tsx |
| Avatar | avatar.tsx |
| Hinweise | alert.tsx |
Avatar
- Datei:
packages/ui/src/components/ui/avatar.tsx(Radix Avatar). - Darstellung: Root als
inline-flexmititems-center,justify-center,leading-none,overflow-hidden,rounded-full— vermeidet Layout-Lücken durchinline-IMG-Baseline. - Bild:
AvatarImagemitblock,h-full,w-full,object-cover,object-center— Kreis wird zuverlässig gefüllt;max-h-full/max-w-fullgegen Konflikte mit globalen IMG-Regeln (z. B. Preflight).
Switch (Toggle)
- Datei:
packages/ui/src/components/ui/switch.tsx. - Aus: Schiene
bg-muted-foreground/25(hell) bzw./40im Dark-Mode,border-muted-foreground/45— klar grauer „Graben“; Daumenbg-white(bzw.zinc-100dark) mitborder-2,shadow-md. - An: Schiene
bg-primary, Daumenbg-primary-foreground; etwas größere Hitbox (h-7,w-[3.25rem], Daumenh-6 w-6) für bessere Erkennbarkeit von links/rechts.
Tabs: Varianten
<Tabs> unterstützt optional variant:
segmented(Standard): Leiste mitbg-muted, Rand und leichtem Innenschatten; inaktiv explizittext-muted-foreground(statttext-foreground/65, damit der Zustand überall zuverlässig lesbar ist); der aktive Tab:bg-card,text-foreground,shadow-md,ring-1 ring-primary/40.underline: Leiste mitbg-muted/60und unterem Rand; inaktivtext-muted-foreground, aktivbg-card,text-primary, fetter Text und 3px Primär-Balken (insetshadow) plus Ring — gut für horizontale Center-/Detail-Reiter. Wichtig: keineTabsList-Overrides mitbg-transparent, sonst wirkt die Leiste wie reine Links ohne aktiven Zustand.
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@mall-os/ui";
<Tabs defaultValue="a" variant="underline">
<TabsList className="w-full">
<TabsTrigger value="a">Eins</TabsTrigger>
<TabsTrigger value="b">Zwei</TabsTrigger>
</TabsList>
…
</Tabs>
TabsList / TabsTrigger können wie gewohnt per className ergänzt werden (z. B. flex-1 für gleich breite Reiter).
Wo nicht anpacken
- Center-Website-Templates können eigene Kopien unter
apps/center-website/.../components/ui/haben — dort gelten nicht automatisch alle Änderungen an@mall-os/ui. - Einmalige Layout-Sonderfälle im Dashboard: lieber
classNameauf der Seite setzen als neue Varianten ohne Bedarf duplizieren.
Siehe auch
packages/ui/src/components/ui/index.ts— Exportlistepackages/ui/src/cockpit-dashboard-theme.css— Design-Tokens (SSoT)packages/ui/src/styles.css— Tailwind v4 +@theme(importiert das Theme)
Nutzungsstatistik: Seitenaufrufe werden anonymisiert erfasst. Im Umami-Dashboard nach diesem Pfad filtern: /developer-guide/mall-os-ui