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

Modulwindow.*Wichtige Methoden
theme.jsWBThemesetMode, setAccent, setPreset, setRadius, setDensity
modal.jsWBModalopen(id), close(id)
drawer.jsWBDraweropen(id), close(id)
dropdown.jsWBDropdownopen(el), close(el)
tabs.jsWBTabsactivate(tabEl)
accordion.jsWBAccordionopen(itemEl), close(itemEl)
sidebar.jsWBSidebaropen(), close()
nav-group.jsWBNavGroupopen(groupEl), close(groupEl), init()
toast.jsWBToastshow(msg, opts), dismiss(toastEl)
popover.jsWBPopoveropen(wrapperEl), close(wrapperEl), closeAll()
tooltip.jsWBTooltipshow(el), hide(el), hideAll()
dismiss.jsWBDismissdismiss(el)
command-palette.jsWBCommandPaletteopen(id), close(id), register(id, opts)
ajax-toggle.jsWBAjaxTogglehandle(checkboxEl) — automatisch via change-Event

WBTheme

theme.js

Verwaltet alle Theme-Achsen — setzt data-*-Attribute auf <html> und speichert Werte im localStorage.

WBTheme.setMode(value: 'light' | 'dark' | 'auto')
WBTheme.setAccent(value: string)
WBTheme.setPreset(value: string)
WBTheme.setRadius(value: 'sharp' | 'soft')
WBTheme.setDensity(value: 'compact' | 'comfortable')
// 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>
localStorage-Schlüssel: 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(id: string)
WBModal.close(id: string)
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.js

Eingleitendes Seitenpanel mit vollständiger Fokus-Falle. Tastatur: Escape schließt; Tab wechselt innerhalb des Panels.

WBDrawer.open(id: string)
WBDrawer.close(id: string)
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.js

Schaltet is-open auf einem wb-dropdown-Wrapper. Schließt bei Klick außerhalb und Escape.

WBDropdown.open(wrapperEl: Element)
WBDropdown.close(wrapperEl: Element)
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.js

Aktiviert Tab-Elemente und die zugehörigen Panels.

WBTabs.activate(tabEl: Element)
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.js

Schaltet is-open auf Accordion-Einträgen. Klicks auf wb-accordion-trigger werden automatisch verdrahtet.

WBAccordion.open(itemEl: Element)
WBAccordion.close(itemEl: Element)
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()
WBSidebar.open();
WBSidebar.close();

Data-Attribut-Trigger

<button data-wb-toggle="sidebar">☰ Menü</button>

WBNavGroup

nav-group.js

Ausklappbare Navigationsgruppen in der Sidebar. Unterstützt optionalen Accordion-Modus.

WBNavGroup.open(groupEl: Element)
WBNavGroup.close(groupEl: Element)
WBNavGroup.init() Nach dynamischen DOM-Änderungen aufrufen
<!-- Einfache Gruppe -->
<div class="wb-nav-group">
  <button class="wb-nav-group-trigger">
    Benutzer
    <svg class="wb-nav-group-chevron" width="12" height="12" viewBox="0 0 24 24"
         fill="none" stroke="currentColor" stroke-width="2">
      <path d="m6 9 6 6 6-6"/>
    </svg>
  </button>
  <div class="wb-nav-group-body">
    <a href="#" class="wb-sidebar-link">Alle Benutzer</a>
    <a href="#" class="wb-sidebar-link">Rollen</a>
  </div>
</div>

<!-- Accordion-Modus: schließt andere Gruppen beim Öffnen einer neuen -->
<nav class="wb-sidebar-nav" data-wb-nav-group-accordion>
  <!-- nav groups here -->
</nav>

WBToast

toast.js

Zeigt Benachrichtigungs-Toasts programmatisch an. Erstellt den Container beim ersten Aufruf automatisch.

WBToast.show(message: string, options?: object) → Element
WBToast.dismiss(toastEl: Element)

Optionen

OptionTypStandardBeschreibung
typestring'default''default' · 'success' · 'error' · 'warning' · 'info'
durationnumber4000Verzögerung vor automatischem Ausblenden in ms. 0 = deaktiviert.
positionstring'top-right''top-right' · 'top-center' · 'top-left' · 'bottom-center' · 'bottom-left'
dismissiblebooleantrueSchließ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.js

Schaltet is-open auf einem wb-popover-wrapper. Schließt bei Klick außerhalb und Escape.

WBPopover.open(wrapperEl: Element)
WBPopover.close(wrapperEl: Element)
WBPopover.closeAll()
<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.js

Zeigt/versteckt Tooltips, die über data-wb-tooltip definiert sind. Wird bei Hover und Fokus ausgelöst. Standardmäßig 300ms Anzeigeverzögerung.

WBTooltip.show(el: Element)
WBTooltip.hide(el: Element)
WBTooltip.hideAll()
<!-- 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.js

Blendet Alerts und Banner mit einer is-leaving-Animation aus, bevor sie entfernt werden.

WBDismiss.dismiss(el: Element)
<!-- HTML -->
<div class="wb-alert wb-alert-info" id="my-alert">
  Nachrichtentext.
  <button data-wb-dismiss="alert" class="wb-alert-close">&times;</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.js

Vollbild-Befehlspaletten-Overlay mit Tastaturnavigation. Geöffnet über Cmd+K / Ctrl+K.

WBCommandPalette.register(id: string, options?: object)
WBCommandPalette.open(id: string)
WBCommandPalette.close(id: string)

Optionen

OptionTypBeschreibung
onSearchfunction(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

TasteAktion
Cmd/Ctrl+KErste registrierte Palette öffnen
↑ / ↓Ergebnisse navigieren
EnterAusgewähltes Ergebnis aktivieren
EscapePalette schließen

WBAjaxToggle

ajax-toggle.js

Sendet 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.

WBAjaxToggle.handle(checkboxEl: Element) Automatisch via change-Event aufgerufen

Data-Attribute

AttributPflichtBeschreibung
data-wb-ajax-toggleJaMarkiert die Checkbox für AJAX-Toggle-Verhalten
data-wb-urlJaPOST-URL für die Toggle-Anfrage
data-wb-fieldNeinJSON-Feldname zum Senden ({ field: checked }). Standard: value
data-wb-successNeinToast-Nachricht bei Erfolg
data-wb-errorNeinToast-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

KlasseVerwendung
is-openElement ist sichtbar/aktiv (Modal, Drawer, Dropdown, Sidebar)
is-activeAusgewählter Zustand (Tabs, Nav-Links, Filter-Chips)
is-selectedAuswahlzustand (Tabellenzeilen, Listenelemente)
is-leavingSchließ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>
Modulmuster: Alle Module verwenden ein IIFE — (function(){ 'use strict'; … })() — und stellen ihre API auf window bereit. Es gibt keine globale Namespace-Verschmutzung; jedes Modul ist vollständig eigenständig.