565 lines
No EOL
14 KiB
Markdown
565 lines
No EOL
14 KiB
Markdown
# Komponenten-Referenz
|
||
|
||
Vollständige Dokumentation aller opt-in Klassen aus `components.css`.
|
||
|
||
---
|
||
|
||
## Navigation
|
||
|
||
### Top Navigation (`.topnav`)
|
||
|
||
Sticky Navigationsleiste mit Branding, Links und optionalem User-Dropdown.
|
||
|
||
```html
|
||
<nav class="topnav">
|
||
<div class="topnav-inner">
|
||
<a class="topnav-brand" href="/">Brand</a>
|
||
|
||
<ul class="topnav-links">
|
||
<li><a href="/" class="active">Dashboard</a></li>
|
||
<li>
|
||
<button data-action="nav-dropdown">
|
||
Mehr <svg class="nav-chevron"><!-- Chevron SVG --></svg>
|
||
</button>
|
||
<div class="topnav-dropdown">
|
||
<a href="/settings">Einstellungen</a>
|
||
<a href="/profile">Profil</a>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
|
||
<div class="topnav-end">
|
||
<!-- Buttons, User-Dropdown, Theme-Toggle -->
|
||
</div>
|
||
|
||
<button class="topnav-burger" aria-label="Menü öffnen">☰</button>
|
||
</div>
|
||
<div class="topnav-mobile">
|
||
<!-- Mobile Links -->
|
||
</div>
|
||
</nav>
|
||
```
|
||
|
||
**Modifier:** `.topnav-static` — nicht sticky
|
||
|
||
### Sidebar (`.sidebar`)
|
||
|
||
Feste Seitenleiste für App-Layouts. Wird mit `.with-sidebar` kombiniert.
|
||
|
||
```html
|
||
<!-- Vor dem with-sidebar-Container -->
|
||
<div class="mobile-topbar">
|
||
<button id="sidebar-toggle" aria-label="Menü öffnen">☰</button>
|
||
<span>App Name</span>
|
||
</div>
|
||
<div id="sidebar-backdrop" class="sidebar-backdrop"></div>
|
||
|
||
<div class="with-sidebar">
|
||
<aside class="sidebar">
|
||
<div class="sidebar-header">
|
||
<a href="/" class="sidebar-brand">Brand</a>
|
||
</div>
|
||
|
||
<nav class="sidebar-nav">
|
||
<div class="sidebar-section">Hauptmenü</div>
|
||
<a href="/" class="active">
|
||
<svg><!-- Icon --></svg>
|
||
Dashboard
|
||
<span class="nav-count">4</span>
|
||
</a>
|
||
|
||
<details class="sidebar-group">
|
||
<summary><svg><!-- Icon --></svg> Gruppe</summary>
|
||
<div class="sidebar-group-items">
|
||
<a href="/unterseite">Unterseite</a>
|
||
</div>
|
||
</details>
|
||
</nav>
|
||
|
||
<div class="sidebar-footer">
|
||
<a href="/profil" class="sidebar-user">
|
||
<div class="avatar avatar-sm">AM</div>
|
||
<div class="sidebar-user-info">
|
||
<div class="sidebar-user-name">Anna Müller</div>
|
||
<div class="sidebar-user-role">Admin</div>
|
||
</div>
|
||
</a>
|
||
</div>
|
||
</aside>
|
||
|
||
<main class="stack stack-lg">
|
||
<!-- Seiteninhalt -->
|
||
</main>
|
||
</div>
|
||
```
|
||
|
||
### Footer (`.footer`)
|
||
|
||
```html
|
||
<!-- Einfach -->
|
||
<footer class="footer">
|
||
<div class="footer-inner">
|
||
<a class="footer-brand" href="/">Brand</a>
|
||
<ul class="footer-links">
|
||
<li><a href="/impressum">Impressum</a></li>
|
||
<li><a href="/datenschutz">Datenschutz</a></li>
|
||
</ul>
|
||
<p class="footer-copy">© 2025 Acme GmbH</p>
|
||
</div>
|
||
</footer>
|
||
|
||
<!-- Mehrspaltig -->
|
||
<footer class="footer footer-full">
|
||
<div class="footer-inner">
|
||
<div class="footer-col">
|
||
<p class="footer-col-title">Produkt</p>
|
||
<a href="/features">Features</a>
|
||
<a href="/pricing">Preise</a>
|
||
</div>
|
||
<div class="footer-col">
|
||
<p class="footer-col-title">Rechtliches</p>
|
||
<a href="/impressum">Impressum</a>
|
||
</div>
|
||
</div>
|
||
<div class="footer-bottom">
|
||
<span>© 2025 Acme GmbH</span>
|
||
<ul class="footer-social">
|
||
<li><a href="https://github.com/..."><svg><!-- GitHub Icon --></svg></a></li>
|
||
</ul>
|
||
</div>
|
||
</footer>
|
||
```
|
||
|
||
---
|
||
|
||
## Breadcrumbs (`.breadcrumbs`)
|
||
|
||
```html
|
||
<nav class="breadcrumbs" aria-label="Breadcrumb">
|
||
<ol>
|
||
<li><a href="/dashboard">Dashboard</a></li>
|
||
<li><a href="/projekte">Projekte</a></li>
|
||
<li><span aria-current="page">Einstellungen</span></li>
|
||
</ol>
|
||
</nav>
|
||
```
|
||
|
||
Horizontaler Navigationspfad. Auf schmalen Viewports horizontal scrollbar.
|
||
|
||
---
|
||
|
||
## Buttons (`.btn`)
|
||
|
||
Alle Buttons benötigen `.btn` als Basisklasse plus eine Variante.
|
||
|
||
```html
|
||
<!-- Varianten -->
|
||
<button class="btn btn-primary">Primary</button>
|
||
<button class="btn btn-secondary">Secondary</button>
|
||
<button class="btn btn-ghost">Ghost</button>
|
||
<button class="btn btn-danger">Danger</button>
|
||
<button class="btn btn-success">Success</button>
|
||
|
||
<!-- Größen (Standardgröße ist keine Größenklasse = medium) -->
|
||
<button class="btn btn-primary btn-xs">XSmall</button>
|
||
<button class="btn btn-primary btn-sm">Small</button>
|
||
<button class="btn btn-primary btn-lg">Large</button>
|
||
<button class="btn btn-primary btn-xl">XLarge</button>
|
||
|
||
<!-- Modifiers -->
|
||
<button class="btn btn-primary btn-full">Volle Breite</button>
|
||
<button class="btn btn-ghost btn-icon"><svg><!-- Icon --></svg></button>
|
||
|
||
<!-- Als Link -->
|
||
<a href="/ziel" class="btn btn-primary">Link-Button</a>
|
||
|
||
<!-- Disabled -->
|
||
<button class="btn btn-primary" disabled>Gesperrt</button>
|
||
|
||
<!-- Button Group -->
|
||
<div class="button-group" role="group">
|
||
<button class="btn btn-secondary">Liste</button>
|
||
<button class="btn btn-secondary">Board</button>
|
||
<button class="btn btn-secondary">Kalender</button>
|
||
</div>
|
||
|
||
<!-- Segmented Control (Radio-Basis, kein JS) -->
|
||
<div class="segmented" role="radiogroup">
|
||
<label class="segmented-option" for="r-tag">
|
||
<input class="segmented-input" type="radio" name="range" id="r-tag">
|
||
<span class="segmented-button">Tag</span>
|
||
</label>
|
||
<label class="segmented-option" for="r-woche">
|
||
<input class="segmented-input" type="radio" name="range" id="r-woche" checked>
|
||
<span class="segmented-button">Woche</span>
|
||
</label>
|
||
<label class="segmented-option" for="r-monat">
|
||
<input class="segmented-input" type="radio" name="range" id="r-monat">
|
||
<span class="segmented-button">Monat</span>
|
||
</label>
|
||
</div>
|
||
```
|
||
|
||
---
|
||
|
||
## Badges (`.badge`)
|
||
|
||
```html
|
||
<span class="badge badge-default">Standard</span>
|
||
<span class="badge badge-primary">Primär</span>
|
||
<span class="badge badge-success">Erfolg</span>
|
||
<span class="badge badge-warning">Warnung</span>
|
||
<span class="badge badge-danger">Fehler</span>
|
||
<span class="badge badge-info">Info</span>
|
||
<span class="badge badge-outline">Outline</span>
|
||
|
||
<!-- Mit Dot-Indikator -->
|
||
<span class="badge badge-success badge-dot">Live</span>
|
||
```
|
||
|
||
---
|
||
|
||
## Cards (`.card`)
|
||
|
||
```html
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<h3>Titel</h3>
|
||
<span class="badge badge-success">Aktiv</span>
|
||
</div>
|
||
<div class="card-body">
|
||
Inhalt der Karte
|
||
</div>
|
||
<div class="card-footer">
|
||
<button class="btn btn-ghost btn-sm">Abbrechen</button>
|
||
<button class="btn btn-primary btn-sm">Aktion</button>
|
||
</div>
|
||
</div>
|
||
```
|
||
|
||
**Varianten:** `.card-flat`, `.card-raised`, `.card-ghost`
|
||
**Hover-Effekt:** `.card.card-hover`
|
||
|
||
**Image Card:**
|
||
```html
|
||
<div class="card">
|
||
<div class="card-media">
|
||
<img src="..." alt="...">
|
||
</div>
|
||
<div class="card-body">
|
||
<h3>Titel</h3>
|
||
<p>Beschreibung</p>
|
||
</div>
|
||
</div>
|
||
```
|
||
|
||
---
|
||
|
||
## Formulare
|
||
|
||
Basis-Eingabeelemente (`input`, `select`, `textarea`) werden classless gestylt.
|
||
Opt-in Klassen für Gruppierung und Zustände:
|
||
|
||
```html
|
||
<div class="form-group">
|
||
<label for="email">E-Mail</label>
|
||
<input type="email" id="email" name="email">
|
||
<span class="form-hint">Wird für Login genutzt.</span>
|
||
</div>
|
||
|
||
<!-- Fehler-State -->
|
||
<div class="form-group">
|
||
<label for="pwd">Passwort</label>
|
||
<input type="password" id="pwd" class="error">
|
||
<span class="form-error">Mindestens 8 Zeichen.</span>
|
||
</div>
|
||
|
||
<!-- Mehrere Felder nebeneinander -->
|
||
<div class="form-row">
|
||
<div class="form-group">
|
||
<label for="vorname">Vorname</label>
|
||
<input type="text" id="vorname">
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="nachname">Nachname</label>
|
||
<input type="text" id="nachname">
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Input mit Prefix/Suffix -->
|
||
<div class="input-group">
|
||
<span class="input-group-prefix">https://</span>
|
||
<input type="text" placeholder="beispiel.de">
|
||
</div>
|
||
<div class="input-group">
|
||
<input type="text" placeholder="Betrag">
|
||
<span class="input-group-suffix">EUR</span>
|
||
</div>
|
||
```
|
||
|
||
---
|
||
|
||
## Tabellen
|
||
|
||
Classless gestylt — kein Wrapper nötig für einfache Tabellen:
|
||
|
||
```html
|
||
<table>
|
||
<thead>
|
||
<tr><th>Name</th><th>Status</th><th>Datum</th></tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr><td>Anna Müller</td><td><span class="badge badge-success">Aktiv</span></td><td>2025-01-15</td></tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<!-- Mit Rahmen und horizontalem Scroll (z.B. auf Mobile) -->
|
||
<div class="table-wrap">
|
||
<table>...</table>
|
||
</div>
|
||
|
||
<!-- Modifier -->
|
||
<table class="table-striped">...</table>
|
||
<table class="table-compact">...</table>
|
||
```
|
||
|
||
---
|
||
|
||
## Alerts
|
||
|
||
```html
|
||
<div class="alert alert-info">
|
||
<svg class="alert-icon"><!-- Icon --></svg>
|
||
<div class="alert-content">
|
||
<p class="alert-title">Hinweis</p>
|
||
<p>Deine Änderungen werden gespeichert.</p>
|
||
</div>
|
||
</div>
|
||
```
|
||
|
||
**Varianten:** `alert-info`, `alert-success`, `alert-warning`, `alert-danger`
|
||
|
||
---
|
||
|
||
## Modals
|
||
|
||
```html
|
||
<!-- Struktur -->
|
||
<div class="modal-backdrop" id="mein-modal"
|
||
data-action="modal-backdrop">
|
||
<div class="modal">
|
||
<div class="modal-header">
|
||
<h3>Titel</h3>
|
||
<button class="btn btn-ghost btn-icon btn-sm"
|
||
data-action="modal-close" data-target="mein-modal">✕</button>
|
||
</div>
|
||
<div class="modal-body">Inhalt</div>
|
||
<div class="modal-footer">
|
||
<button class="btn btn-ghost" data-action="modal-close" data-target="mein-modal">Abbrechen</button>
|
||
<button class="btn btn-primary">Bestätigen</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<button data-action="modal-open" data-target="mein-modal">Modal öffnen</button>
|
||
```
|
||
|
||
**Größen:** `.modal-sm`, `.modal-lg`, `.modal-xl`
|
||
|
||
---
|
||
|
||
## Tabs
|
||
|
||
```html
|
||
<div class="tabs">
|
||
<ul class="tab-list" role="tablist">
|
||
<li>
|
||
<button class="active" role="tab"
|
||
data-action="tab" data-target="panel-1">Tab 1</button>
|
||
</li>
|
||
<li>
|
||
<button role="tab"
|
||
data-action="tab" data-target="panel-2">Tab 2</button>
|
||
</li>
|
||
</ul>
|
||
<div id="panel-1" class="tab-panel active">Inhalt Tab 1</div>
|
||
<div id="panel-2" class="tab-panel">Inhalt Tab 2</div>
|
||
</div>
|
||
```
|
||
|
||
---
|
||
|
||
## Dropdowns
|
||
|
||
```html
|
||
<div class="dropdown" id="dd-aktionen">
|
||
<button class="btn btn-secondary" data-action="dropdown" data-target="dd-aktionen">
|
||
Aktionen
|
||
</button>
|
||
<div class="dropdown-menu">
|
||
<div class="dropdown-label">Aktionen</div>
|
||
<button class="dropdown-item">Bearbeiten</button>
|
||
<div class="dropdown-divider"></div>
|
||
<button class="dropdown-item danger">Löschen</button>
|
||
</div>
|
||
</div>
|
||
```
|
||
|
||
**Positionierung:** `.dropdown-menu-left`, `.dropdown-menu-top`
|
||
**Breite:** `.dropdown-wide`
|
||
|
||
**Spezielle Item-Typen:**
|
||
```html
|
||
<!-- Mit Beschreibung -->
|
||
<button class="dropdown-item dropdown-item-rich">
|
||
<div class="dropdown-item-title">Projekt</div>
|
||
<div class="dropdown-item-desc">Neue Projektmappe erstellen</div>
|
||
</button>
|
||
|
||
<!-- Checkbox/Filter -->
|
||
<button class="dropdown-item dropdown-item-check checked"
|
||
data-action="toggle-class" data-class="checked">
|
||
Aktiv
|
||
</button>
|
||
|
||
<!-- User-Header -->
|
||
<div class="dropdown-header">
|
||
<div class="avatar">AM</div>
|
||
<div>
|
||
<div class="dropdown-header-name">Anna Müller</div>
|
||
<div class="dropdown-header-sub">anna@beispiel.de</div>
|
||
</div>
|
||
</div>
|
||
```
|
||
|
||
---
|
||
|
||
## Pagination
|
||
|
||
```html
|
||
<ul class="pagination">
|
||
<li class="disabled"><a>←</a></li>
|
||
<li><a class="active" href="?page=1">1</a></li>
|
||
<li><a href="?page=2">2</a></li>
|
||
<li><a href="?page=3">3</a></li>
|
||
<li><a href="?page=2">→</a></li>
|
||
</ul>
|
||
```
|
||
|
||
---
|
||
|
||
## Feedback & Status-Komponenten
|
||
|
||
### Spinner
|
||
|
||
```html
|
||
<div class="spinner spinner-sm"></div>
|
||
<div class="spinner"></div> <!-- default -->
|
||
<div class="spinner spinner-lg"></div>
|
||
```
|
||
|
||
### Fortschrittsbalken
|
||
|
||
```html
|
||
<div class="progress">
|
||
<div class="progress-bar" data-progress="75"></div>
|
||
</div>
|
||
<div class="progress">
|
||
<div class="progress-bar success" data-progress="100"></div>
|
||
</div>
|
||
```
|
||
|
||
### Skeleton (Lade-Platzhalter)
|
||
|
||
```html
|
||
<div class="skeleton skeleton-line is-short"></div>
|
||
<div class="skeleton skeleton-title"></div>
|
||
<div class="skeleton skeleton-block"></div>
|
||
```
|
||
|
||
### KPI / Stat
|
||
|
||
```html
|
||
<div class="stat">
|
||
<span class="stat-label">Umsatz</span>
|
||
<span class="stat-value">€ 48.291</span>
|
||
<span class="stat-change up">↑ +12.4%</span>
|
||
</div>
|
||
|
||
<!-- Trend-basierte Einfärbung des Hauptwerts -->
|
||
<div class="stat" data-trend="positive">
|
||
<span class="stat-label">Saldo</span>
|
||
<span class="stat-value">+ € 1.240</span>
|
||
</div>
|
||
<div class="stat" data-trend="negative">
|
||
<span class="stat-label">Saldo</span>
|
||
<span class="stat-value">− € 320</span>
|
||
</div>
|
||
```
|
||
|
||
### Avatar
|
||
|
||
```html
|
||
<div class="avatar">AM</div>
|
||
<div class="avatar avatar-sm">AM</div>
|
||
<div class="avatar avatar-lg"><img src="..." alt="Profilbild"></div>
|
||
|
||
<!-- Avatar Group -->
|
||
<div class="avatar-group">
|
||
<div class="avatar avatar-sm">AM</div>
|
||
<div class="avatar avatar-sm">BS</div>
|
||
<div class="avatar avatar-sm">CK</div>
|
||
</div>
|
||
```
|
||
|
||
### Empty State
|
||
|
||
```html
|
||
<div class="empty">
|
||
<svg class="empty-icon"><!-- Illustration/Icon --></svg>
|
||
<p class="empty-title">Keine Einträge</p>
|
||
<p class="empty-description">Erstelle deinen ersten Eintrag, um loszulegen.</p>
|
||
<button class="btn btn-primary btn-sm">Erstellen</button>
|
||
</div>
|
||
```
|
||
|
||
### Toasts
|
||
|
||
```html
|
||
<div class="toast-container" id="toast-container"></div>
|
||
|
||
<!-- Aus einem Button heraus -->
|
||
<button class="btn" data-action="toast" data-message="Gespeichert!" data-type="success">Speichern</button>
|
||
|
||
<!-- Nach einer HTMX-Antwort: Server setzt HX-Trigger, eigenes Skript (als Datei) reagiert -->
|
||
<!-- Response-Header: HX-Trigger: {"toast": {"message": "Gespeichert!", "type": "success"}} -->
|
||
<!-- static/js/app.js: document.body.addEventListener('toast', e => showToast(e.detail.message, e.detail.type)); -->
|
||
```
|
||
|
||
### Divider mit Label
|
||
|
||
```html
|
||
<div class="divider">oder</div>
|
||
```
|
||
|
||
### Filter-Leiste
|
||
|
||
```html
|
||
<!-- Flex-Row, auf Mobile gestapelt (< 40rem) -->
|
||
<div class="filter-bar">
|
||
<div class="form-group">
|
||
<label>Monat</label>
|
||
<input type="month">
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Typ</label>
|
||
<select>
|
||
<option>Alle</option>
|
||
<option>Einnahme</option>
|
||
</select>
|
||
</div>
|
||
<button class="btn btn-secondary btn-sm">Filtern</button>
|
||
</div>
|
||
```
|
||
|
||
--- |