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

Link button
<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.

Default Primary Success Warning Danger Info
<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.

Record saved successfully.
An error occurred. Please try again.
Your plan will expire in 3 days.
A new version is available.
<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

You have 3 unread notifications.
<div class="wb-alert wb-alert-info">
  You have 3 unread notifications.
  <button class="wb-alert-close" data-wb-dismiss="alert" aria-label="Close">&times;</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.

Total Users
12,480
+8.4% this month
Revenue
$94,200
−2.1% this month
Open Tickets
37
No change
<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

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">&times;</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>

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.

Popover title
Some helpful info here.
Bottom popover
Opens below the trigger.
<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.

JD AB CD EF User
<!-- 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>

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.

or continue with
<!-- 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.

All Active Pending Inactive
<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>

Action Menu

Toolbar of action buttons and status pills for table rows or headers.

Active Pending Inactive Error
<div class="wb-action-group">
  <button class="wb-action-btn">Edit</button>
  <button class="wb-action-btn">Preview</button>
  <button class="wb-action-btn wb-action-btn-danger">Delete</button>
</div>

<!-- Status pills -->
<span class="wb-status-pill wb-status-active">Active</span>
<span class="wb-status-pill wb-status-pending">Pending</span>
<span class="wb-status-pill wb-status-inactive">Inactive</span>

Demo modal

This is a live demo modal. Close it with the button, the backdrop, or the Escape key.

Right drawer

Right-side drawer panel. Close with Escape or the backdrop.

Left drawer

Left-side drawer panel.