Components
All UI components with live previews and copy-ready HTML snippets. Every component uses the wb- prefix and responds to the active theme.
Buttons
Core action component. Combine wb-btn with a variant and optional size modifier.
Variants
<button class="wb-btn wb-btn-primary">Primary</button> <button class="wb-btn wb-btn-secondary">Secondary</button> <button class="wb-btn wb-btn-outline">Outline</button> <button class="wb-btn wb-btn-ghost">Ghost</button> <button class="wb-btn wb-btn-danger">Danger</button> <button class="wb-btn wb-btn-success">Success</button>
Sizes
<button class="wb-btn wb-btn-primary wb-btn-sm">Small</button> <button class="wb-btn wb-btn-primary">Default</button> <button class="wb-btn wb-btn-primary wb-btn-lg">Large</button>
States
<button class="wb-btn wb-btn-primary" disabled>Disabled</button> <button class="wb-btn wb-btn-primary wb-btn-loading">Loading</button> <a href="#" class="wb-btn wb-btn-outline">Link button</a>
Badges
Small status indicators and labels.
<span class="wb-badge">Default</span> <span class="wb-badge wb-badge-primary">Primary</span> <span class="wb-badge wb-badge-success">Success</span> <span class="wb-badge wb-badge-warning">Warning</span> <span class="wb-badge wb-badge-danger">Danger</span> <span class="wb-badge wb-badge-info">Info</span>
Alerts
Inline feedback messages. Add data-wb-dismiss="alert" to make them dismissible.
<div class="wb-alert wb-alert-success">Record saved successfully.</div> <div class="wb-alert wb-alert-danger">An error occurred. Please try again.</div> <div class="wb-alert wb-alert-warning">Your plan will expire in 3 days.</div> <div class="wb-alert wb-alert-info">A new version is available.</div>
Dismissible alert
<div class="wb-alert wb-alert-info"> You have 3 unread notifications. <button class="wb-alert-close" data-wb-dismiss="alert" aria-label="Close">×</button> </div>
Cards
General-purpose content container with optional header, body, and footer.
Card title
Optional subtitle
Card content and body text goes here. Add anything inside.
<div class="wb-card">
<div class="wb-card-header">
<h3 class="wb-card-title">Card title</h3>
<p class="wb-card-subtitle">Optional subtitle</p>
</div>
<div class="wb-card-body">
Card content goes here.
</div>
<div class="wb-card-footer">
<button class="wb-btn wb-btn-primary wb-btn-sm">Save</button>
<button class="wb-btn wb-btn-ghost wb-btn-sm">Cancel</button>
</div>
</div>
Stat Cards
Dashboard KPI cards — use wb-stat inside a wb-card.
<div class="wb-card wb-stat"> <div class="wb-stat-label">Total Users</div> <div class="wb-stat-value">12,480</div> <div class="wb-stat-change wb-stat-up">+8.4% this month</div> </div>
Forms
Input fields, selects, checkboxes, radios, switches, and textarea.
Text inputs
We'll never share your email.
This field is required.
<div class="wb-field"> <label class="wb-label">Full name</label> <input type="text" class="wb-input" placeholder="Jane Smith"> </div> <div class="wb-field"> <label class="wb-label">Email</label> <input type="email" class="wb-input" placeholder="jane@example.com"> <p class="wb-field-hint">We'll never share your email.</p> </div> <!-- Error state --> <div class="wb-field"> <label class="wb-label">Invalid field</label> <input type="text" class="wb-input is-invalid" value="bad value"> <p class="wb-field-error">This field is required.</p> </div>
Select & Textarea
<div class="wb-field">
<label class="wb-label">Status</label>
<select class="wb-select">
<option>Active</option>
<option>Inactive</option>
</select>
</div>
<div class="wb-field">
<label class="wb-label">Notes</label>
<textarea class="wb-textarea" rows="3"></textarea>
</div>
Checkboxes, Radios & Switch
<label class="wb-check"><input type="checkbox"> Enable notifications</label> <label class="wb-radio"><input type="radio" name="r1"> Option A</label> <!-- Toggle switch --> <label class="wb-switch-label"> <input type="checkbox" class="wb-switch" checked> <span>Active</span> </label>
Tables
Responsive data tables with optional striped and hover modifiers.
| Name | Role | Status |
|---|---|---|
| Alice Chen | Admin | Active |
| Bob Ross | Editor | Pending |
| Carol White | Viewer | Inactive |
<table class="wb-table wb-table-striped">
<thead>
<tr><th>Name</th><th>Role</th><th>Status</th></tr>
</thead>
<tbody>
<tr>
<td>Alice Chen</td>
<td>Admin</td>
<td><span class="wb-badge wb-badge-success">Active</span></td>
</tr>
</tbody>
</table>
Modifiers: wb-table-striped · wb-table-hover · wb-table-bordered · wb-table-sm
Modal
Dialog overlay. Opened via WBModal.open(id) or data-wb-toggle="modal".
<!-- Trigger -->
<button class="wb-btn wb-btn-primary"
data-wb-toggle="modal"
data-wb-target="#my-modal">Open modal</button>
<!-- Modal -->
<div class="wb-modal" id="my-modal">
<div class="wb-modal-backdrop" data-wb-dismiss="modal"></div>
<div class="wb-modal-dialog">
<div class="wb-modal-header">
<h4 class="wb-modal-title">Confirm action</h4>
<button class="wb-modal-close" data-wb-dismiss="modal">×</button>
</div>
<div class="wb-modal-body">
Are you sure you want to proceed?
</div>
<div class="wb-modal-footer">
<button class="wb-btn wb-btn-ghost" data-wb-dismiss="modal">Cancel</button>
<button class="wb-btn wb-btn-primary">Confirm</button>
</div>
</div>
</div>
JS API
WBModal.open('my-modal');
WBModal.close('my-modal');
Drawer
Side panel overlay with focus trap. Supports right, left, top, and bottom placements.
<!-- Trigger -->
<button data-wb-toggle="drawer" data-wb-target="#my-drawer">Open</button>
<!-- Drawer (right by default) -->
<div class="wb-drawer wb-drawer-right" id="my-drawer">
<div class="wb-drawer-backdrop" data-wb-dismiss="drawer"></div>
<div class="wb-drawer-panel">
<div class="wb-drawer-header">
<h4 class="wb-drawer-title">Panel title</h4>
<button class="wb-drawer-close" data-wb-dismiss="drawer">×</button>
</div>
<div class="wb-drawer-body">
Drawer content here.
</div>
</div>
</div>
<!-- Placement variants -->
<div class="wb-drawer wb-drawer-left" id="left-drawer">...</div>
<div class="wb-drawer wb-drawer-top" id="top-drawer">...</div>
<div class="wb-drawer wb-drawer-bottom" id="btm-drawer">...</div>
<!-- Width variants -->
<div class="wb-drawer wb-drawer-right wb-drawer-sm">...</div>
<div class="wb-drawer wb-drawer-right wb-drawer-lg">...</div>
<div class="wb-drawer wb-drawer-right wb-drawer-xl">...</div>
Dropdown
Click-triggered menu. Closes on outside click and Escape key.
<div class="wb-dropdown">
<button class="wb-btn wb-btn-outline" data-wb-toggle="dropdown">
Actions ▾
</button>
<div class="wb-dropdown-menu">
<a href="#" class="wb-dropdown-item">Edit</a>
<a href="#" class="wb-dropdown-item">Duplicate</a>
<div class="wb-dropdown-divider"></div>
<a href="#" class="wb-dropdown-item wb-dropdown-item-danger">Delete</a>
</div>
</div>
Tabs
Tabbed content panel. JS handles switching; is-active marks the current tab and panel.
Overview panel content.
Activity panel content.
Settings panel content.
<div class="wb-tabs" id="my-tabs">
<div class="wb-tab-list">
<button class="wb-tab-item is-active" data-wb-tab="tab1">Overview</button>
<button class="wb-tab-item" data-wb-tab="tab2">Activity</button>
</div>
<div class="wb-tab-panels">
<div class="wb-tab-panel is-active" id="tab1">Overview content</div>
<div class="wb-tab-panel" id="tab2">Activity content</div>
</div>
</div>
Accordion
Collapsible content sections.
A zero-dependency UI kit for admin panels and dashboards.
No. Drop two script tags and you're done.
Yes — works with any template engine. HTML stays HTML.
<div class="wb-accordion">
<div class="wb-accordion-item is-open">
<button class="wb-accordion-trigger">Question one?</button>
<div class="wb-accordion-body">Answer text here.</div>
</div>
<div class="wb-accordion-item">
<button class="wb-accordion-trigger">Question two?</button>
<div class="wb-accordion-body">Answer text here.</div>
</div>
</div>
Toast
Programmatic notification messages. Shown via WBToast.show().
// Basic
WBToast.show('Settings saved.');
// With type
WBToast.show('Record created!', { type: 'success' });
WBToast.show('Something went wrong.', { type: 'error' });
WBToast.show('Please review.', { type: 'warning' });
// With custom duration (ms)
WBToast.show('Auto-closes in 2s.', { duration: 2000 });
// With position (default: top-right)
WBToast.show('Bottom center!', { position: 'bottom-center' });
Position values: top-right · top-center · top-left · bottom-center · bottom-left
Popover
Anchored overlay with rich content. Supports four placement variants.
<div class="wb-popover-wrapper">
<button class="wb-btn wb-btn-outline" data-wb-toggle="popover">
Click me
</button>
<div class="wb-popover wb-popover-top">
<div class="wb-popover-title">Popover title</div>
<div class="wb-popover-body">Popover content goes here.</div>
</div>
</div>
<!-- Placements: wb-popover-top / -right / -bottom / -left -->
Tooltip
Simple hover/focus tooltip via the data-wb-tooltip attribute.
<button data-wb-tooltip="Saves your work"
data-wb-tooltip-placement="top">
Save
</button>
<!-- Placements: top (default) / right / bottom / left -->
Avatar
User picture placeholder with size variants and initials fallback.
<!-- Initials --> <span class="wb-avatar wb-avatar-xl">JD</span> <span class="wb-avatar wb-avatar-lg">AB</span> <span class="wb-avatar">CD</span> <span class="wb-avatar wb-avatar-sm">EF</span> <!-- Image --> <img src="user.jpg" class="wb-avatar" alt="User">
Pagination
Page navigation links.
<nav class="wb-pagination"> <a href="#" class="wb-page-item wb-page-prev">← Prev</a> <a href="#" class="wb-page-item">1</a> <a href="#" class="wb-page-item is-active">2</a> <a href="#" class="wb-page-item">3</a> <span class="wb-page-item wb-page-ellipsis">…</span> <a href="#" class="wb-page-item wb-page-next">Next →</a> </nav>
Breadcrumb
Hierarchical navigation trail.
<nav class="wb-breadcrumb"> <a href="#" class="wb-crumb">Home</a> <span class="wb-crumb-sep">/</span> <a href="#" class="wb-crumb">Users</a> <span class="wb-crumb-sep">/</span> <span class="wb-crumb is-active">Alice Chen</span> </nav>
Skeleton
Loading placeholder for content areas.
<div class="wb-skeleton" style="height:1rem; width:60%"></div> <div class="wb-skeleton" style="height:1rem; width:90%"></div> <div class="wb-skeleton" style="height:1rem; width:75%"></div> <div class="wb-skeleton" style="height:2.5rem; width:120px; border-radius:var(--wb-r-md)"></div>
Empty State
Placeholder shown when a list or table has no data.
No results found
Try adjusting your search or filter.
<div class="wb-empty"> <div class="wb-empty-icon">📭</div> <h4 class="wb-empty-title">No results found</h4> <p class="wb-empty-desc">Try adjusting your search or filter.</p> <button class="wb-btn wb-btn-primary wb-btn-sm">Clear filters</button> </div>
Spinner & Loading
Inline spinner, progress bar, and loading bar for page-level transitions.
Spinner
<div class="wb-spinner wb-spinner-sm"></div> <div class="wb-spinner"></div> <div class="wb-spinner wb-spinner-lg"></div>
Progress bar
<div class="wb-progress-bar"> <div class="wb-progress-fill" style="width:65%"></div> </div> <!-- Semantic variants --> <div class="wb-progress-bar"> <div class="wb-progress-fill wb-progress-success" style="width:40%"></div> </div>
Divider
Horizontal, vertical, or labeled separator lines.
<!-- Simple --> <div class="wb-divider"></div> <!-- Labeled --> <div class="wb-divider wb-divider-labeled"> <span>or continue with</span> </div> <!-- Vertical (in a flex container) --> <div class="wb-divider wb-divider-vertical"></div>
List Group
Vertically stacked list of items.
- Dashboard
- Users
- Reports
- Settings
<ul class="wb-list"> <li class="wb-list-item is-active">Dashboard</li> <li class="wb-list-item">Users</li> <li class="wb-list-item">Reports</li> </ul> <!-- Modifiers: wb-list-flush · wb-list-compact · wb-list-numbered -->
Filter Bar
Search and filter row for data tables.
<div class="wb-filter-bar">
<div class="wb-search-bar">
<svg class="wb-search-icon">...</svg>
<input type="search" class="wb-search-input" placeholder="Search…">
</div>
<select class="wb-select">...</select>
<button class="wb-btn wb-btn-outline wb-btn-sm">Export</button>
</div>
<!-- Filter chips -->
<span class="wb-filter-chip is-active">All</span>
<span class="wb-filter-chip">Active</span>
<span class="wb-filter-chip">Pending</span>