JavaScript API
13 Vanilla-JS-Module — alle als IIFE, ohne Abhängigkeiten, jedes mit einer window.WB*-API. Eingebunden über ein einziges <script>-Tag.
Modulübersicht
| Modul | window.* | Wichtige Methoden |
|---|---|---|
| theme.js | WBTheme | setMode, setAccent, setPreset, setRadius, setDensity |
| modal.js | WBModal | open(id), close(id) |
| drawer.js | WBDrawer | open(id), close(id) |
| dropdown.js | WBDropdown | open(el), close(el) |
| tabs.js | WBTabs | activate(tabEl) |
| accordion.js | WBAccordion | open(itemEl), close(itemEl) |
| sidebar.js | WBSidebar | open(), close() |
| nav-group.js | WBNavGroup | open(groupEl), close(groupEl), init() |
| toast.js | WBToast | show(msg, opts), dismiss(toastEl) |
| popover.js | WBPopover | open(wrapperEl), close(wrapperEl), closeAll() |
| tooltip.js | WBTooltip | show(el), hide(el), hideAll() |
| dismiss.js | WBDismiss | dismiss(el) |
| command-palette.js | WBCommandPalette | open(id), close(id), register(id, opts) |
| ajax-toggle.js | WBAjaxToggle | handle(checkboxEl) — automatisch via change-Event |
WBTheme
theme.jsVerwaltet alle Theme-Achsen — setzt data-*-Attribute auf <html> und speichert Werte im localStorage.
// Dunkelmodus aktivieren
WBTheme.setMode('dark');
// Akzentfarbe wechseln
WBTheme.setAccent('forest');
// Preset anwenden (bündelt Radius/Shadow/Density/Font/Border)
WBTheme.setPreset('rounded');
// Einzelne Achsen feinjustieren
WBTheme.setRadius('sharp');
WBTheme.setDensity('compact');
Data-Attribut-Trigger (kein JS erforderlich)
<!-- Zyklus: light → dark → auto --> <button data-wb-mode-cycle>Modus wechseln</button> <!-- Bestimmten Modus setzen --> <button data-wb-mode-set="dark">Dunkel</button> <button data-wb-mode-set="light">Hell</button> <button data-wb-mode-set="auto">Auto</button> <!-- Akzentfarbe setzen --> <button data-wb-accent-set="ocean">Ocean</button> <button data-wb-accent-set="forest">Forest</button>
wb-mode, wb-accent, wb-preset, wb-radius, wb-density.
Werte werden beim Seitenaufruf automatisch wiederhergestellt. Zum Zurücksetzen diese Schlüssel löschen.
WBModal
modal.jsÖffnet und schließt Dialog-Overlays. Verwaltet is-open/is-leaving-Zustände, Scroll-Sperre, Escape-Taste und Klick auf den Hintergrund.
WBModal.open('my-modal');
WBModal.close('my-modal');
Data-Attribut-Trigger
<!-- Öffnen --> <button data-wb-toggle="modal" data-wb-target="#my-modal">Öffnen</button> <!-- Schließen (innerhalb des Modals) --> <button data-wb-dismiss="modal">Schließen</button> <div class="wb-modal-backdrop" data-wb-dismiss="modal"></div>
Bestätigungsdialog (wb-confirm)
<div class="wb-modal wb-confirm" id="confirm-delete">
<div class="wb-modal-backdrop" data-wb-dismiss="modal"></div>
<div class="wb-modal-dialog">
<div class="wb-confirm-icon wb-confirm-danger">!</div>
<h4 class="wb-confirm-title">Eintrag löschen?</h4>
<p class="wb-confirm-desc">Diese Aktion kann nicht rückgängig gemacht werden.</p>
<div class="wb-confirm-actions">
<button class="wb-btn wb-btn-ghost" data-wb-dismiss="modal">Abbrechen</button>
<button class="wb-btn wb-btn-danger" id="confirm-btn">Löschen</button>
</div>
</div>
</div>
WBDrawer
drawer.jsEingleitendes Seitenpanel mit vollständiger Fokus-Falle. Tastatur: Escape schließt; Tab wechselt innerhalb des Panels.
WBDrawer.open('my-drawer');
WBDrawer.close('my-drawer');
Data-Attribut-Trigger
<button data-wb-toggle="drawer" data-wb-target="#my-drawer">Öffnen</button> <button data-wb-dismiss="drawer">Schließen</button>
WBDropdown
dropdown.jsSchaltet is-open auf einem wb-dropdown-Wrapper. Schließt bei Klick außerhalb und Escape.
var wrapper = document.querySelector('.wb-dropdown');
WBDropdown.open(wrapper);
WBDropdown.close(wrapper);
Data-Attribut-Trigger
<div class="wb-dropdown"> <button data-wb-toggle="dropdown">Menü öffnen</button> <div class="wb-dropdown-menu">...</div> </div>
WBTabs
tabs.jsAktiviert Tab-Elemente und die zugehörigen Panels.
var tab = document.querySelector('[data-wb-tab="tab2"]');
WBTabs.activate(tab);
HTML-Struktur
<div class="wb-tabs">
<div class="wb-tab-list">
<button class="wb-tab-item is-active" data-wb-tab="panel1">Tab 1</button>
<button class="wb-tab-item" data-wb-tab="panel2">Tab 2</button>
</div>
<div class="wb-tab-panels">
<div class="wb-tab-panel is-active" id="panel1">Inhalt 1</div>
<div class="wb-tab-panel" id="panel2">Inhalt 2</div>
</div>
</div>
WBAccordion
accordion.jsSchaltet is-open auf Accordion-Einträgen. Klicks auf wb-accordion-trigger werden automatisch verdrahtet.
var item = document.querySelector('.wb-accordion-item');
WBAccordion.open(item);
WBAccordion.close(item);
WBSidebar
sidebar.jsÖffnet und schließt das mobile Sidebar-Overlay. Fügt is-open zu .wb-sidebar und .wb-dashboard-shell hinzu bzw. entfernt es.
WBSidebar.open(); WBSidebar.close();
Data-Attribut-Trigger
<button data-wb-toggle="sidebar">☰ Menü</button>
WBToast
toast.jsZeigt Benachrichtigungs-Toasts programmatisch an. Erstellt den Container beim ersten Aufruf automatisch.
Optionen
| Option | Typ | Standard | Beschreibung |
|---|---|---|---|
| type | string | 'default' | 'default' · 'success' · 'error' · 'warning' · 'info' |
| duration | number | 4000 | Verzögerung vor automatischem Ausblenden in ms. 0 = deaktiviert. |
| position | string | 'top-right' | 'top-right' · 'top-center' · 'top-left' · 'bottom-center' · 'bottom-left' |
| dismissible | boolean | true | Schließen-Schaltfläche auf dem Toast anzeigen |
// Einfach
WBToast.show('Einstellungen gespeichert.');
// Mit Typ
WBToast.show('Eintrag gelöscht!', { type: 'success' });
WBToast.show('Upload fehlgeschlagen.', { type: 'error' });
// Benutzerdefinierte Dauer + Position
WBToast.show('Wird verarbeitet…', {
type: 'info',
duration: 0, // bleibt bis zum manuellen Schließen
position: 'bottom-center'
});
// Programmatisches Schließen
var toast = WBToast.show('Lange Nachricht');
WBToast.dismiss(toast);
WBPopover
popover.jsSchaltet is-open auf einem wb-popover-wrapper. Schließt bei Klick außerhalb und Escape.
<div class="wb-popover-wrapper">
<button data-wb-toggle="popover">Klicken</button>
<div class="wb-popover wb-popover-top">
<div class="wb-popover-title">Titel</div>
<div class="wb-popover-body">Inhalt hier.</div>
</div>
</div>
<!-- Positionen: wb-popover-top / -right / -bottom / -left -->
WBTooltip
tooltip.jsZeigt/versteckt Tooltips, die über data-wb-tooltip definiert sind. Wird bei Hover und Fokus ausgelöst. Standardmäßig 300ms Anzeigeverzögerung.
<!-- HTML -->
<button data-wb-tooltip="Zum Speichern klicken"
data-wb-tooltip-placement="top">
Speichern
</button>
<!-- Positionen: top (Standard) / right / bottom / left -->
<!-- JS -->
var el = document.querySelector('[data-wb-tooltip]');
WBTooltip.show(el);
WBTooltip.hide(el);
WBDismiss
dismiss.jsBlendet Alerts und Banner mit einer is-leaving-Animation aus, bevor sie entfernt werden.
<!-- HTML -->
<div class="wb-alert wb-alert-info" id="my-alert">
Nachrichtentext.
<button data-wb-dismiss="alert" class="wb-alert-close">×</button>
</div>
<!-- JS -->
WBDismiss.dismiss(document.getElementById('my-alert'));
Das Attribut data-wb-dismiss="alert" verdrahtet das Schließen automatisch.
Programmatische Verwendung ist für Fälle gedacht, in denen von externem Code geschlossen werden muss.
WBCommandPalette
command-palette.jsVollbild-Befehlspaletten-Overlay mit Tastaturnavigation. Geöffnet über Cmd+K / Ctrl+K.
Optionen
| Option | Typ | Beschreibung |
|---|---|---|
| onSearch | function(query, results) | Bei jedem Tastendruck aufgerufen. Erhält Suchbegriff und gefilterte NodeList der Ergebnisse. |
// Einfache Registrierung (eingebaute Textsuche)
WBCommandPalette.register('#my-cmd');
// Mit benutzerdefiniertem Such-Handler
WBCommandPalette.register('#my-cmd', {
onSearch: function(query, results) {
// results ist eine NodeList von .wb-cmd-result-Elementen, die zur Suche passen
console.log(query, results.length + ' Ergebnisse');
}
});
// Programmatisch öffnen/schließen
WBCommandPalette.open('#my-cmd');
WBCommandPalette.close('#my-cmd');
Tastaturkürzel
| Taste | Aktion |
|---|---|
| Cmd/Ctrl+K | Erste registrierte Palette öffnen |
| ↑ / ↓ | Ergebnisse navigieren |
| Enter | Ausgewähltes Ergebnis aktivieren |
| Escape | Palette schließen |
WBAjaxToggle
ajax-toggle.jsSendet eine AJAX-POST-Anfrage, wenn eine Checkbox ihren Zustand ändert. Liest das CSRF-Token aus dem meta[name=csrf-token]-Tag. Kehrt bei Fehler um und zeigt einen Toast.
Data-Attribute
| Attribut | Pflicht | Beschreibung |
|---|---|---|
| data-wb-ajax-toggle | Ja | Markiert die Checkbox für AJAX-Toggle-Verhalten |
| data-wb-url | Ja | POST-URL für die Toggle-Anfrage |
| data-wb-field | Nein | JSON-Feldname zum Senden ({ field: checked }). Standard: value |
| data-wb-success | Nein | Toast-Nachricht bei Erfolg |
| data-wb-error | Nein | Toast-Nachricht bei Fehler (Standard: 'Error occurred') |
<!-- HTML -->
<input
type="checkbox"
class="wb-switch"
data-wb-ajax-toggle
data-wb-url="/api/users/42/toggle-active"
data-wb-field="is_active"
data-wb-success="Status aktualisiert"
data-wb-error="Status konnte nicht aktualisiert werden"
checked
>
<!-- Laravel Blade Beispiel -->
<input
type="checkbox"
class="wb-switch"
data-wb-ajax-toggle
data-wb-url="{{ route('users.toggle', $user) }}"
data-wb-field="is_active"
data-wb-success="Status aktualisiert"
{{ $user->is_active ? 'checked' : '' }}
>
<!-- CSRF-Meta-Tag (erforderlich im <head>) -->
<meta name="csrf-token" content="{{ csrf_token() }}">
Anfrageformat
// POST an data-wb-url
// Header: Content-Type: application/json, X-CSRF-TOKEN: ...
// Body: { "is_active": true }
// Bei Erfolg: WBToast(data-wb-success, { type: 'success' }) anzeigen
// Bei Fehler: Checkbox-Zustand zurücksetzen + WBToast(data-wb-error, { type: 'error' }) anzeigen
JS-Konventionen
Gemeinsame Muster, die in allen Modulen verwendet werden.
Zustandsklassen
| Klasse | Verwendung |
|---|---|
| is-open | Element ist sichtbar/aktiv (Modal, Drawer, Dropdown, Sidebar) |
| is-active | Ausgewählter Zustand (Tabs, Nav-Links, Filter-Chips) |
| is-selected | Auswahlzustand (Tabellenzeilen, Listenelemente) |
| is-leaving | Schließanimation läuft — wird vor dem Entfernen von is-open hinzugefügt |
is-leaving-Animationsmuster
Alle Schließanimationen folgen dieser Abfolge, um ein abruptes Verschwinden zu verhindern:
// 1. is-leaving hinzufügen (löst CSS-Schließtransition aus)
element.classList.add('is-leaving');
// 2. Auf transitionend warten (mit 300ms-Fallback)
element.addEventListener('transitionend', function handler() {
element.classList.remove('is-open', 'is-leaving');
element.removeEventListener('transitionend', handler);
}, { once: true });
// Fallback, falls transitionend nicht ausgelöst wird
setTimeout(function() {
element.classList.remove('is-open', 'is-leaving');
}, 300);
Universelle Data-Attribut-Verdrahtung
<!-- Jede umschaltbare Komponente öffnen -->
<button data-wb-toggle="modal|drawer|dropdown|sidebar|cmd"
data-wb-target="#target-id">Öffnen</button>
<!-- Von innen schließen -->
<button data-wb-dismiss="modal|drawer|alert">Schließen</button>
(function(){ 'use strict'; … })() —
und stellen ihre API auf window bereit.
Es gibt keine globale Namespace-Verschmutzung; jedes Modul ist vollständig eigenständig.