Skip to main content

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.css via @import "@mall-os/ui/cockpit-dashboard-theme.css".
  • UI-Paket: packages/ui/src/styles.css importiert dieselbe Datei und mappt @theme inline auf hsl(var(--…)).
  • Seiten-Hintergrund (hell): --background entspricht 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: --radius steuert rounded-* über die Theme-Skala (radius-smradius-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 (nicht bg-background), damit das Fenster sich von der Seitenfläche abhebt.
  • Overlay: etwa bg-black/55 und backdrop-blur-sm für eine klare Dim-Schicht.
  • Erhöhung: shadow-2xl und dezenter ring für Tiefe.
  • z-index: z-[10400] — über Dropdown-Popovern, die im Dashboard oft ~9999 nutzen; 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, SelectTrigger und Textarea nutzen durchgängig bg-card, border-border, h-11 (Input/Select default), shadow-sm und gleiche Focus-Ringe — damit Suche und Dropdowns auf grauem Seitenhintergrund gleich wirken. Filter-Leisten: Icon links im Trigger über flex 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/ui standardmäßig modal={false} (select.tsx, dropdown-menu.tsx). So setzt Radix keinen Body-Scroll-Lock; die Seite springt nicht horizontal, wenn ein Menü aufgeht. Zusätzlich verhindern SelectContent / DropdownMenuContent per onOpenAutoFocuspreventDefault() das browserseitige Scrollen zum fokussierten Portal (typisches „Zucken“ bei langen Seiten). Für Einzelfälle kann modal={true} gesetzt werden (z. B. stärkere Fokus-Falle). Zusätzlich reserviert das Dashboard in globals.css mit scrollbar-gutter: stable Platz 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

  • BunnyUploadFolderType wird in packages/ui/src/hooks/use-bunny-upload.ts exportiert und beschreibt erlaubte type-Werte für Uploads (inkl. Dashboard-spezifischer Ordner wie tile, shop-chain, themes, dooh, wayfinding, videos, images).
  • Das Dashboard importiert diesen Typ für apps/dashboard/src/hooks/use-bunny-upload.ts und bunny-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/ui geführt — eine Implementierung unter packages/ui/src/components/ui/, Pfade wie @/components/ui/input bleiben 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-content enthält ../../packages/ui/src/**, damit Klassen aus dem Paket im JIT ankommen.

Kernkomponenten (Auszug)

BereichDatei unter packages/ui/src/components/ui/
Buttons, Inputs, Textareabutton.tsx, input.tsx, textarea.tsx
Auswahlselect.tsx, checkbox.tsx, radio-group.tsx, switch.tsx
Überlagerungendialog.tsx, alert-dialog.tsx, sheet.tsx, popover.tsx
Menüs & Toastsdropdown-menu.tsx, sonner.tsx, toast.tsx
Tabstabs.tsx
Karten & Layoutcard.tsx, separator.tsx, page-layout.tsx
Avataravatar.tsx
Hinweisealert.tsx

Avatar

  • Datei: packages/ui/src/components/ui/avatar.tsx (Radix Avatar).
  • Darstellung: Root als inline-flex mit items-center, justify-center, leading-none, overflow-hidden, rounded-full — vermeidet Layout-Lücken durch inline-IMG-Baseline.
  • Bild: AvatarImage mit block, h-full, w-full, object-cover, object-center — Kreis wird zuverlässig gefüllt; max-h-full / max-w-full gegen 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. /40 im Dark-Mode, border-muted-foreground/45 — klar grauer „Graben“; Daumen bg-white (bzw. zinc-100 dark) mit border-2, shadow-md.
  • An: Schiene bg-primary, Daumen bg-primary-foreground; etwas größere Hitbox (h-7, w-[3.25rem], Daumen h-6 w-6) für bessere Erkennbarkeit von links/rechts.

Tabs: Varianten

<Tabs> unterstützt optional variant:

  • segmented (Standard): Leiste mit bg-muted, Rand und leichtem Innenschatten; inaktiv explizit text-muted-foreground (statt text-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 mit bg-muted/60 und unterem Rand; inaktiv text-muted-foreground, aktiv bg-card, text-primary, fetter Text und 3px Primär-Balken (inset shadow) plus Ring — gut für horizontale Center-/Detail-Reiter. Wichtig: keine TabsList-Overrides mit bg-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 className auf der Seite setzen als neue Varianten ohne Bedarf duplizieren.

Siehe auch

  • packages/ui/src/components/ui/index.ts — Exportliste
  • packages/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: /en/developer-guide/mall-os-ui