Das Kit enthält 50 vorkonfigurierte shadcn/ui-Komponenten, die auf Radix UI-Primitiven aufbauen, mit Class Variance Authority (CVA) für typsichere Varianten-Verwaltung und Tailwind CSS für das Styling. Die Komponenten befinden sich in einem gemeinsamen
packages/ui/-Paket und werden über abgegrenzte Einstiegspunkte importiert, um unerwünschte App-übergreifende Abhängigkeiten zu verhindern.Diese Seite behandelt die Komponentenarchitektur, abgegrenzte Importe, verfügbare Komponenten und das Hinzufügen neuer Komponenten. Für Farbthemen, siehe Farbthemen & Dark Mode. Für die Tailwind-Konfiguration, siehe Anpassung.
Komponentenarchitektur
Das Komponentensystem wird über
components.json konfiguriert, das der shadcn/ui-CLI mitteilt, wie neue Komponenten installiert werden sollen:components.json — shadcn/ui-Konfiguration
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "tailwind.config.js",
"css": "src/app/globals.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
"iconLibrary": "lucide",
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"registries": {}
}
Wichtige Konfigurationsentscheidungen:
style: "new-york"— Verwendet die New-York-Variante von shadcn/ui (eigenwilliger, etwas anderes Standard-Styling als der "default"-Stil)rsc: true— Komponenten sind standardmäßig mit React Server Components kompatibelcssVariables: true— Farben referenzieren CSS Custom Properties (das Theme-System) statt hartkodierter Tailwind-FarbenbaseColor: "neutral"— Neutrale Grau-Skala als Basisfarbe
Wie Komponenten funktionieren
Jede Komponente folgt dem gleichen Muster: Ein Radix-UI-Primitiv liefert barrierefreies, unstyltes Verhalten, CVA definiert die Variantenklassen, und Tailwind wendet die eigentlichen Stile an. Das
cn()-Utility (aus @nextsaasai/utils) kombiniert Klassen mit korrekter Konfliktauflösung via tailwind-merge.Radix-UI-Primitiv (Barrierefreiheit, Tastaturnavigation, ARIA)
|
v
CVA-Varianten (variant="default" | "destructive" | "outline", size="sm" | "default" | "lg")
|
v
Tailwind-Klassen (bg-primary, text-sm, h-10, px-6, ...)
|
v
cn()-Merge (className-Prop-Überschreibungen + tailwind-merge-Konfliktauflösung)
Abgegrenzte Importe
Komponenten sind in zwei Bereiche aufgeteilt, um Importe übersichtlich und Bundle-Größen klein zu halten:
| Import-Pfad | Inhalt | Verwendet von |
|---|---|---|
@nextsaasai/ui/shared | Nur geteilte Komponenten | Jede App |
@nextsaasai/ui/boilerplate | Geteilt + nur für Boilerplate | apps/boilerplate/ |
Der Shared-Bereich exportiert die grundlegenden Komponenten, die von allen Anwendungen genutzt werden:
packages/ui/src/shared-index.ts — Geteilte Exports
/**
* @nextsaasai/ui - Shared Components
*
* Components available to ALL applications in the monorepo.
* These are foundational UI elements used across both boilerplate and marketing apps.
*
* @scope shared
*/
// Core Form Components
export * from './button'
export * from './checkbox'
export * from './input'
export * from './label'
export * from './radio-group'
export * from './select'
export * from './slider'
export * from './switch'
export * from './textarea'
export * from './toggle'
export * from './toggle-group'
// Layout Components
export * from './accordion'
export * from './aspect-ratio'
export * from './card'
export * from './collapsible'
export * from './separator'
export * from './sheet'
export * from './tabs'
export * from './table'
// Navigation Components
export * from './breadcrumb'
export * from './pagination'
export * from './scroll-area'
// Data Display Components
export * from './avatar'
export * from './badge'
export * from './typography'
// Overlay Components
export * from './popover'
export * from './tooltip'
// Feedback Components
export * from './sonner'
// Theme Components
export * from './theme-toggle'
// Internationalization Components
export * from './flag-icon'
Importiere aus
@nextsaasai/ui/boilerplate (nicht aus @nextsaasai/ui oder direkten Dateipfaden). Abgegrenzte Importe stellen sicher, dass du nur die für deine App vorgesehenen Komponenten einbindest, halten Bundle-Größen klein und verhindern unbeabsichtigte App-übergreifende Abhängigkeiten.Komponentenkategorien
Geteilte Komponenten
Für alle Anwendungen über
@nextsaasai/ui/shared verfügbar (auch im Boilerplate-Bereich enthalten):| Komponente | Datei | Beschreibung |
|---|---|---|
| Button | button.tsx | Primäres Aktionselement mit 8 Varianten und 5 Größen |
| Input | input.tsx | Texteingabe mit einheitlichem Rahmen- und Fokus-Styling |
| Label | label.tsx | Formular-Label mit Unterstützung für deaktivierten Zustand |
| Select | select.tsx | Dropdown-Auswahl mit Radix-Primitiven |
| Textarea | textarea.tsx | Mehrzeilige Texteingabe |
| Card | card.tsx | Container mit Header-, Content- und Footer-Slots |
| Sheet | sheet.tsx | Ausklappbares Panel (mobile Navigation, Seitenleisten) |
| Badge | badge.tsx | Statusanzeige mit Variantenfarben |
| Sonner | sonner.tsx | Toast-Benachrichtigungssystem |
| ThemeToggle | theme-toggle.tsx | Umschalter für Dark/Light Mode |
| FlagIcon | flag-icon.tsx | Länder-Flaggen-Icons für i18n |
Nur-Boilerplate-Komponenten
Zusätzliche Komponenten, verfügbar über
@nextsaasai/ui/boilerplate:packages/ui/src/boilerplate-index.ts — Boilerplate-Bereich
// ============================================================================
// Alert Components (error messages, notifications in app)
export * from './alert'
export * from './alert-dialog'
// Form Utilities (react-hook-form integration)
export * from './form'
// Modal Components (app modals, confirmations)
export * from './dialog'
export * from './drawer'
// Navigation Components (user menu in dashboard)
export * from './dropdown-menu'
export * from './context-menu'
export * from './menubar'
export * from './command'
// Progress & Loading Components
export * from './progress'
export * from './skeleton'
// Overlay Components (popovers, tooltips)
export * from './popover'
// Data Display Components
export * from './calendar'
export * from './carousel'
export * from './hover-card'
export * from './resizable'
// Input Components
export * from './input-otp'
// Toast Notifications (in-app feedback)
export * from './toast'
export * from './use-toast'
// Note: toaster.tsx available but not exported to avoid conflict with sonner
| Komponente | Beschreibung |
|---|---|
| Alert / AlertDialog | Fehlermeldungen, Bestätigungsdialoge |
| Form | react-hook-form-Integration mit Zod-Validierung |
| Dialog | Modale Fenster für In-App-Interaktionen |
| DropdownMenu | Benutzermenü, Aktionsmenüs im Dashboard |
| Progress | Ladebalken, Upload-Fortschrittsanzeigen |
| Skeleton | Lade-Platzhalter-Animationen |
| Toast / useToast | Legacy-Toast-System (Sonner wird für neuen Code bevorzugt) |
Button im Detail
Die Button-Komponente demonstriert das CVA-Muster, das in allen Komponenten verwendet wird:
packages/ui/src/button.tsx — Button mit CVA-Varianten
import * as React from 'react'
import { Slot } from '@radix-ui/react-slot'
import { cva, type VariantProps } from 'class-variance-authority'
import { cn } from '@nextsaasai/utils'
const buttonVariants = cva(
'inline-flex items-center justify-center gap-1.5 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-3.5 [&_svg]:shrink-0',
{
variants: {
variant: {
default: 'bg-primary text-background dark:text-foreground/90 hover:text-white',
destructive: 'bg-red-600 text-white hover:bg-red-700 dark:bg-red-600 dark:hover:bg-red-700',
secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/90',
accent: 'bg-accent text-accent-foreground hover:bg-accent/90',
uncolored: 'bg-card text-card-muted-foreground hover:text-card-foreground',
outline: 'border hover:border-foreground/75',
ghost: 'border border-transparent bg-primary bg-clip-text text-transparent hover:border-foreground/75 hover:text-foreground',
link: 'bg-primary bg-clip-text text-transparent underline-offset-8 hover:text-foreground inline flex-none !px-0 !h-auto !w-auto',
},
size: {
sm: 'h-9 px-5 text-xs',
default: 'h-10 px-6 text-sm',
md: 'h-11 px-7 text-base',
lg: 'h-12 px-8 text-base',
xl: 'h-14 px-11 text-lg',
icon: 'h-10 w-10',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
}
)
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean
}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : 'button'
// Ensure data-testid is passed through properly
return (
<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
)
}
)
Button.displayName = 'Button'
export { Button, buttonVariants }
Varianten-Referenz
| Variante | Erscheinungsbild | Anwendungsfall |
|---|---|---|
default | Solid primärer Hintergrund | Primäre Aktionen (Speichern, Erstellen) |
destructive | Roter Hintergrund | Gefährliche Aktionen (Löschen, Entfernen) |
secondary | Gedämpfter Hintergrund | Sekundäre Aktionen (Abbrechen, Zurück) |
accent | Akzent-Hintergrund | Hervorgehobene sekundäre Aktionen |
outline | Nur Rahmen | Tertiäre Aktionen, Umschalter |
ghost | Verlaufstext, Rahmen beim Hover | Dezente Aktionen, Navigationslinks |
link | Verlaufstext, Unterstrich-Offset | Inline-Textlinks |
uncolored | Karten-Hintergrund | Neutrale Aktionen in Karten-Kontexten |
Verwendungsbeispiele
tsx
import { Button } from '@nextsaasai/ui/boilerplate'
// Primäre Aktion
<Button>Save Changes</Button>
// Destructive mit Größe
<Button variant="destructive" size="sm">Delete Account</Button>
// Als Link (rendert <a> statt <button>)
<Button asChild variant="link">
<a href="/docs">Read the Docs</a>
</Button>
// Icon-Button
<Button variant="ghost" size="icon">
<SearchIcon />
</Button>
Die
asChild-Prop verwendet Radix' Slot-Komponente, um das Styling des Buttons auf das Kind-Element zu übertragen — nützlich für das Rendern von gestylten <a>-Tags oder Next.js-<Link>-Komponenten.Card-Muster
Die Card-Komponente verwendet ein Compound-Component-Muster mit separaten Unterkomponenten für jeden Bereich:
packages/ui/src/card.tsx — Card-Komponente
const Card = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn(
'rounded-md border border-border bg-card text-card-foreground',
className
)}
{...props}
/>
))
Card.displayName = 'Card'
Jeder Teil (Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter) ist eine
forwardRef-Komponente mit cn() für das Zusammenführen von Klassen. Verwende sie gemeinsam:tsx
import { Card, CardHeader, CardTitle, CardContent } from '@nextsaasai/ui/boilerplate'
<Card>
<CardHeader>
<CardTitle>Monthly Usage</CardTitle>
</CardHeader>
<CardContent>
<p>You have used 1,234 of 5,000 credits this month.</p>
</CardContent>
</Card>
Neue Komponenten hinzufügen
1
Komponente installieren
Verwende die shadcn/ui-CLI, um eine neue Komponente zu generieren. Führe dies aus dem Boilerplate-App-Verzeichnis aus:
bash
cd apps/boilerplate
npx shadcn@latest add accordion
Dies generiert die Komponentendatei im konfigurierten
ui-Alias-Pfad.2
In das packages/ui-Verzeichnis verschieben
Verschiebe die generierte Komponente aus dem lokalen
components/ui/-Verzeichnis nach packages/ui/src/:bash
mv src/components/ui/accordion.tsx ../../packages/ui/src/accordion.tsx
3
Den cn-Import aktualisieren
Die generierte Komponente importiert
cn aus dem lokalen Pfad. Aktualisiere ihn auf das gemeinsame Paket:typescript
// Vorher (generiert von der shadcn/ui-CLI)
import { cn } from '@/lib/utils'
// Nachher (gemeinsames Monorepo-Utility)
import { cn } from '@nextsaasai/utils'
4
Im Bereich registrieren
Exportiere die Komponente aus der passenden Bereich-Index-Datei. Für die meisten Boilerplate-Komponenten füge sie zu
packages/ui/src/boilerplate-index.ts hinzu:typescript
// Accordion-Komponente
export * from './accordion'
Für Komponenten, die in allen Apps verwendet werden, füge sie stattdessen zu
shared-index.ts hinzu.Die shadcn/ui-CLI generiert Komponenten mit
import { cn } from '@/lib/utils'. Dieser Pfad existiert im packages/ui/-Paket nicht. Ändere ihn nach dem Verschieben der Komponente immer zu import { cn } from '@nextsaasai/utils'.Projekt-Komponenten
Neben den gemeinsamen
packages/ui/-Komponenten hat die Boilerplate-App eigene Komponenten, die nach Features organisiert sind:src/components/
├── about/ # About-Seite (Hero, Team, Werte, Timeline)
├── ai/ # KI-Chat-Interface (Chat, Nachrichten, Eingabe, RAG/LLM)
├── auth/ # Authentifizierung (Login-Formulare, Benutzer-Button)
├── blog/ # Blog-UI (Seitenleiste, Tags, Like/Share-Buttons)
├── contact/ # Kontaktseite (Hero, Info, Formular)
├── credits/ # Credit-System (Niedrigstand-Banner, Nutzungszähler)
├── dashboard/ # Dashboard-UI (Seitenleiste, Header, Analytics, Abonnements)
├── demo/ # Demo-Modus (Nav-Item, Demo-Provider)
├── forms/ # Formular-Komponenten (Kontaktformular)
├── home/ # Landingpage (Hero, Features, Newsletter)
├── layout/ # App-Layout (Navbar, Footer)
├── modals/ # Modale Dialoge (Credits erschöpft)
├── payments/ # Zahlungs-UI (Plan-Wechsel-Dialog, Zahlungsfehler)
├── shared/ # Übergreifendes (Hero-Hintergrund)
├── test/ # Test-Utilities (No-Clerk-Script, Konfigurationsfehler)
└── upload/ # Datei-Upload (Drop-Zone, Vorschau, Hooks)
Das sind app-spezifische Komponenten — sie importieren aus
@nextsaasai/ui/boilerplate für grundlegende UI-Elemente und ergänzen diese um Business-Logik.Wichtige Dateien
| Datei | Zweck |
|---|---|
components.json | shadcn/ui-CLI-Konfiguration (Stil, Pfade, Aliase) |
packages/ui/src/shared-index.ts | Geteilte Komponentenexporte (30 Komponenten) |
packages/ui/src/boilerplate-index.ts | Boilerplate-Bereich-Exports (geteilt + 18 zusätzliche) |
packages/ui/src/button.tsx | Button-Komponente mit 8 CVA-Varianten |
packages/ui/src/card.tsx | Card-Compound-Komponente (6 Unterkomponenten) |
packages/utils/src/index.ts | cn()-Utility (clsx + tailwind-merge) |