Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Advanced Technical Breakdown of WebBuilder Rapid Dev Platform Button Library

Tech 1

WebBuilder leverages declarative JSON configuration to define UI components, separating interface structure from business logic to minimize code bloat and simplify long-term maintenance.

Core Module and Component Structure

Every WebBuilder UI module starts with a standardized root container:

{
  "name": "",
  "displayIcon": "",
  "assets": "",
  "metadata": "",
  "excludeNav": false,
  "label": "button-demo-module",
  "class": "Wb.Core.Module",
  "config": {
    "compId": "mainModule"
  },
  "_displayIcon": "layout",
  "_autoExpand": true
}

Each button within this module is an isolated element with a unique identifier, configurable properties, and a built-in event handling system, ensuring high reusability and extensibility.

Fundamental Button Variants and Behavior

The Button Showcase section highlights over 12 core button types with distinct use cases.

Icon and Text Display Options

Buttons support flexible visual content through multiple properties:

// Basic interaction button
{
  "compType": "actionButton",
  "compId": "stdActionBtn",
  "label": "Standard Action",
  "listeners": {
    "actionTriggered": function(evt, meta) {
      Wb.notice(this.compId + ' activated');
    }
  }
}

// Built-in icon button
{
  "compType": "actionButton",
  "compId": "nativeIconBtn",
  "label": "Gear Settings",
  "nativeIcon": "settings"
}

// Custom asset icon button
{
  "compType": "actionButton",
  "compId": "customAssetBtn",
  "label": "Custom Cut",
  "customIcon": "clip"
}

// Unicode/Emoji icon button
{
  "compType": "actionButton",
  "compId": "unicodeIconBtn",
  "label": "Nature",
  "nativeIcon": "🌿",
  "tooltip": "Any UTF-8 character works"
}

// Notification badge button
{
  "compType": "actionButton",
  "compId": "notificationBadgeBtn",
  "label": "37",
  "nativeIcon": "inbox",
  "useLabelAsBadge": true,
  "tooltip": "Unread messages"
}

Advanced Interaction Controls

WebBuilder provides granular interaction tuning for specialized scenarios:

// Icon alignment variants
[
  { "compType": "actionButton", "label": "Left Align", "nativeIcon": "arrow-left", "iconPosition": "left" },
  { "compType": "actionButton", "label": "Right Align", "nativeIcon": "arrow-right", "iconPosition": "right" },
  { "compType": "actionButton", "label": "Top Align", "nativeIcon": "arrow-up", "iconPosition": "top" },
  { "compType": "actionButton", "label": "Bottom Align", "nativeIcon": "arrow-down", "iconPosition": "bottom" }
]

// Keyboard shortcut trigger
{
  "compType": "actionButton",
  "compId": "shortcutActionBtn",
  "nativeIcon": "keyboard-alt",
  "label": "Ctrl+Alt+P",
  "hotkey": "Ctrl+Alt+P",
  "tooltip": "Press Ctrl+Alt+P to activate",
  "listeners": {
    "actionTriggered": function(evt, meta) {
      Wb.notice(this.compId + ' activated via hotkey');
    }
  }
}

// No-focus toolbar button
{
  "compType": "actionButton",
  "compId": "noFocusToolBtn",
  "label": "Quick Edit",
  "nativeIcon": "pencil",
  "skipTabIndex": true,
  "allowFocus": false
}

// Dropdown-only menu button
{
  "compType": "actionButton",
  "compId": "menuOnlyBtn",
  "label": "Tools Menu",
  "nativeIcon": "toolbox",
  "dropdown": { /* full menu config */ }
}

// Split button with dual actions
{
  "compType": "splitActionButton",
  "compId": "splitSaveBtn",
  "label": "Save",
  "dropdown": {
    "compType": "contextMenu",
    "isNestedConfig": true,
    "items": [
      { "compType": "menuItem", "label": "Save Draft", "nativeIcon": "floppy-disk" },
      { "compType": "menuItem", "label": "Save & Publish", "nativeIcon": "publish" },
      { "compType": "menuItem", "label": "Save As Template", "nativeIcon": "copy" }
    ]
  },
  "listeners": {
    "actionTriggered": function(evt, meta) {
      Wb.notice(this.compId + ' main action: Quick Save');
    }
  }
}

// Mousedown-triggered button
{
  "compType": "actionButton",
  "compId": "mousedownActionBtn",
  "triggerOnPress": true,
  "label": "Instant Action",
  "listeners": {
    "actionTriggered": function(evt, meta) {
      Wb.notice(this.compId + ' activated on press');
    }
  }
}

// Repeat-click increment button
{
  "compType": "actionButton",
  "compId": "repeatIncrementBtn",
  "label": "Increment Count",
  "enableRepeatClick": true,
  "listeners": {
    "actionTriggered": function(evt, meta) {
      app.tempIncrement ??= 0;
      Wb.toast(this.compId + ' activated ' + (++app.tempIncrement) + 'x');
    }
  }
}

// Disabled state button
{
  "compType": "actionButton",
  "compId": "disabledRemoveBtn",
  "nativeIcon": "trash",
  "label": "Remove Selected",
  "isDisabled": true
}

Visual Customization System

Buttons can be styled rapidly using pre-built themes, shapes, and sizing.

Predefined Theme Presets

Preset Name Visual Trait Primary Use Case
accent Highlighted colored background Critical operations (Confirm, Finalize, Save)
borderless No background, light border only Secondary actions (Cancel, Back, Clear)
compactTool Minimal padding and height Dense toolbars
iconOnly No visible label, just icon Ultra-compact navigation
subtle Lowest visual weight Tertiary auxiliary actions
// Accent button
{ "compType": "actionButton", "preset": "accent", "label": "Confirm Purchase", "nativeIcon": "checkout" },

// Borderless button
{ "compType": "actionButton", "preset": "borderless", "nativeIcon": "undo", "tooltip": "Undo Last Change" },

// Compact Tool button
{ "compType": "actionButton", "preset": "compactTool", "label": "Copy", "nativeIcon": "copy" },

// IconOnly button
{ "compType": "iconOnly", "nativeIcon": "settings", "tooltip": "Open Settings" },

// Subtle button
{ "compType": "subtle", "nativeIcon": "help-circle", "tooltip": "Show Help" }

Button Shape Controls

Three shape options are available via the shape property:

Shape Value Appearance Ideal Scenario
round Circular (for icon-only) Floating action buttons, compact icon tools
sharp Right-angled corners Traditional enterprise dashboards, data grids
soft Rounded corners (default) Modern general-purpose interfaces
// Circular icon button
{ "compType": "actionButton", "nativeIcon": "settings", "shape": "round", "tooltip": "Quick Settings" },

// Sharp-edged button
{ "compType": "actionButton", "nativeIcon": "settings", "shape": "sharp", "label": "Adjust Settings" },

// Soft-edged default button
{ "compType": "actionButton", "nativeIcon": "settings", "shape": "soft", "label": "Configure" }

Toggle and Group Selection

Buttons can act as toggle switches or grouped radio-like controls:

// Group 1: Color mode selection
[
  { "compType": "actionButton", "label": "Light", "group": "colorModeGroup", "isActive": false },
  { "compType": "actionButton", "label": "Dark", "group": "colorModeGroup", "isActive": true },
  { "compType": "actionButton", "label": "System", "group": "colorModeGroup", "isActive": false }
],

// Group 2: Font size presets
[
  { "compType": "actionButton", "label": "Small", "group": "fontSizeGroup", "isActive": false },
  { "compType": "actionButton", "label": "Medium", "group": "fontSizeGroup", "isActive": false },
  { "compType": "actionButton", "label": "Large", "group": "fontSizeGroup", "isActive": true }
],

// Independent toggle button
{ "compType": "actionButton", "label": "Show Grid", "isActive": false },

// Borderless toggle (no active background)
{ "compType": "actionButton", "label": "Auto-Save", "isActive": true, "preset": "borderless", "hideActiveBackground": true }

A parent container can listen to all toggle changes within its scope:

{
  "compType": "flexContainer",
  "listeners": {
    "buttonStateChanged": function(btn, active, meta) {
      Wb.notice(btn.compId + ' is now ' + (active ? 'active' : 'inactive'));
    }
  }
}

Sizing and Scaling

Buttons can be resized globally or per-element:

Property Purpose Example Values
scale Global button scaling factor "0.75rem", "1.25em", "18px"
iconScale Independent icon size adjustment "1.5em", "28px"
// Small scaled button
{ "compType": "actionButton", "label": "Small", "nativeIcon": "gift", "scale": "0.75em" },

// Large scaled button
{ "compType": "actionButton", "label": "Large", "nativeIcon": "gift", "scale": "1.25em" },

// Button with oversized icon
{ "compType": "actionButton", "label": "Big Icon", "nativeIcon": "gift", "iconScale": "2em", "iconPosition": "top" }

Complex Layout Composition

The Button Layout section demonstrates nested and multi-button configurations using WebBuilder's container system.

Container Layout Presets

Layout Type Behavior Common Use
columnSingle Single-column vertical grid Stacked content, form sections
formStandard Label-control paired layout Data entry forms
formTight Minimal padding form layout Space-constrained input areas
flexRow Responsive horizontal arrangement Toolbars, button groups
flexColumn Responsive vertical arrangement Sidebars, navigation menus
{
  "layout": "flexRow",
  "items": [
    { "compType": "compactTool", "label": "Preferences", "iconScale": "2.6em" },
    { "compType": "divider" },
    {
      "layout": "flexRow",
      "items": [
        { "compType": "compactTool", "label": "Paste", "iconScale": "2.6em" },
        {
          "layout": "flexColumn",
          "items": [
            { "compType": "compactTool", "label": "Cut" },
            { "compType": "compactTool", "label": "Copy" },
            { "compType": "compactTool", "label": "Delete" }
          ]
        }
      ]
    },
    { "compType": "divider" },
    {
      "layout": "flexColumn",
      "items": [
        { "compType": "compactTool", "label": "Add" },
        { "compType": "compactTool", "label": "Modify" },
        {
          "layout": "flexRow",
          "items": [
            { "compType": "compactTool", "nativeIcon": "arrow-up", "shape": "round" },
            { "compType": "compactTool", "nativeIcon": "arrow-right", "shape": "round" },
            { "compType": "compactTool", "nativeIcon": "arrow-down", "shape": "round" },
            { "compType": "compactTool", "nativeIcon": "arrow-left", "shape": "round" }
          ]
        }
      ]
    },
    { "compType": "splitActionButton", "nativeIcon": "settings", "dropdown": {...} }
  ]
}

Layout Auxiliary Components

Component Type Function Example
divider Visual separator between elements { "compType": "divider" }
spacer Flexible whitespace filler { "compType": "spacer" }
sectionHeader Divider with optional title { "compType": "sectionHeader", "title": "Editor Tools", "dashed": true }
sectionTitle Standalone section heading { "compType": "sectionTitle", "title": "Button Examples" }

Event System and Lifecycle

WebBuilder buttons expose a full set of lifecycle and interaction events.

Standard Interaction Events

Event Name Trigger Condition Parameters
actionTriggered Button clicked/pressed (per triggerOnPress) evt, meta
activated Toggle/group button enters active state meta
deactivated Toggle/group button leaves active state meta
stateChanged Toggle/group button switches state (combined) active, meta
// Action-triggered button
{
  "compType": "actionButton",
  "label": "Trigger Action",
  "listeners": {
    "actionTriggered": function(evt, meta) {
      Wb.notice('action fired');
    }
  }
}

// State-change toggle button
{
  "compType": "actionButton",
  "isActive": true,
  "label": "Toggle State",
  "listeners": {
    "activated": function(meta) { Wb.notice('button activated'); },
    "deactivated": function(meta) { Wb.notice('button deactivated'); },
    "stateChanged": function(active, meta) { Wb.notice('state changed to: ' + active); }
  }
}

Event Registration Methods

Events can be attached declaratively or imperatively:

// Declarative (static config)
"listeners": {
  "actionTriggered": function(evt, meta) {
    Wb.notice('static listener');
  }
}

// Imperative (runtime)
demoButton.on('actionTriggered', handlerFunc);
demoButton.off('actionTriggered', handlerFunc);

// One-time listener
demoButton.once('actionTriggered', function(evt, meta) {
  Wb.notice('this listener runs only once');
});

Module Lifecycle Events

{
  "compType": "coreModule",
  "listeners": {
    "moduleReady": function(configs, meta) {
      console.log('Module initialization complete');
    },
    "moduleCleanup": function(meta) {
      app.highlightField.reset();
    }
  }
}

Runtime Component Manipulation

The Interactive Coding section demonstrates live API operations on button components.

// Dynamically add a new button
app.demoContainer.add({ 
  "compType": "actionButton", 
  "nativeIcon": "settings", 
  "label": "Dynamic Button" 
});

// Modify existing button properties
targetBtn.label = 'Updated Label';
targetBtn.nativeIcon = 'globe';
targetBtn.isDisabled = true;

// Destroy a component
targetBtn.destroy();

// Toggle visibility
targetBtn.hide();
targetBtn.show();

Managed vs. Unmanaged Event Listeners

WebBuilder differentiates between component-level (business) and raw DOM events:

// Component-level event (auto-managed lifecycle)
app.demoBtnHandler ??= () => Wb.notice('managed action triggered');
app.demoButton?.on('actionTriggered', app.demoBtnHandler);
app.demoButton?.off('actionTriggered', app.demoBtnHandler);

// Managed raw DOM event (auto-cleanup on destroy)
app.demoMouseEnterHandler ??= () => Wb.notice('mouse entered button');
app.demoButton?.manageDomListener('mouseenter', app.demoMouseEnterHandler);
app.demoButton?.unmanageDomListener('mouseenter', app.demoMouseEnterHandler);

Direct Component Reference

Components can be accessed directly via app.compId without DOM queries:

// Direct property modification (recommended)
app.demoButton.label = 'New Label';
app.demoButton.isDisabled = true;

// Unified setter method
app.demoButton.setProp('isDisabled', true);
app.demoButton.setProp('label', 'Updated Text');

// Safe optional chaining access
app.demoButton?.destroy();
app.demoButton?.hide();

Quick Component Decision Tree

Need a button?
β”œβ”€ Need a dropdown?
β”‚  β”œβ”€ Main action + dropdown β†’ splitActionButton
β”‚  └─ Dropdown only β†’ actionButton + dropdown
β”œβ”€ Need radio-like grouping?
β”‚  β”œβ”€ Yes β†’ add "group" property
β”‚  └─ No β†’ skip
β”œβ”€ Need toggle state?
β”‚  β”œβ”€ Yes β†’ add "isActive" property
β”‚  └─ No β†’ skip
β”œβ”€ Choose visual preset
β”‚  β”œβ”€ Critical action β†’ preset: "accent"
β”‚  β”œβ”€ Secondary action β†’ preset: "borderless"
β”‚  β”œβ”€ Dense toolbar β†’ preset: "compactTool"
β”‚  β”œβ”€ Ultra-compact β†’ compType: "iconOnly"
β”‚  └─ Tertiary β†’ compType: "subtle"
β”œβ”€ Choose shape
β”‚  β”œβ”€ Circular icon β†’ shape: "round"
β”‚  β”œβ”€ Traditional β†’ shape: "sharp"
β”‚  └─ Default modern β†’ shape: "soft"
β”œβ”€ Need hotkey?
β”‚  └─ Yes β†’ add "hotkey" (e.g., "Ctrl+Alt+S")
└─ Need icon?
   └─ Yes β†’ set nativeIcon/customIcon, iconPosition, iconScale

Common Reusable Templates

Confirmation-required Delete Button

{
  "compType": "actionButton",
  "label": "Remove",
  "nativeIcon": "trash",
  "preset": "borderless",
  "listeners": {
    "actionTriggered": function(evt, meta) {
      Wb.confirm('Are you sure you want to delete this item?', (confirmed) => {
        if(confirmed) { /* Execute deletion logic */ }
      });
    }
  }
}

Asynchronous Loading Submit Button

{
  "compType": "actionButton",
  "label": "Submit Order",
  "preset": "accent",
  "listeners": {
    "actionTriggered": async function(evt, meta) {
      this.isDisabled = true;
      this.label = 'Processing...';
      try {
        await Wb.httpRequest(requestConfig);
        Wb.notice('Order submitted successfully');
      } catch(err) {
        Wb.error('Order failed: ' + err.message);
      } finally {
        this.isDisabled = false;
        this.label = 'Submit Order';
      }
    }
  }
}

View Mode Toggle Group

{
  "compType": "flexContainer",
  "layout": "flexRow",
  "listeners": {
    "buttonStateChanged": function(btn, active, meta) {
      if(active) app.switchViewMode(btn.compId);
    }
  },
  "items": [
    { "compType": "actionButton", "compId": "gridView", "label": "Grid", "group": "viewModeGroup", "isActive": true },
    { "compType": "actionButton", "compId": "listView", "label": "List", "group": "viewModeGroup", "isActive": false },
    { "compType": "actionButton", "compId": "cardView", "label": "Cards", "group": "viewModeGroup", "isActive": false }
  ]
}

Hotkey-enabled Save Button

{
  "compType": "actionButton",
  "label": "Save",
  "nativeIcon": "floppy-disk",
  "preset": "accent",
  "hotkey": "Ctrl+Alt+S",
  "tooltip": "Save current changes (Ctrl+Alt+S)",
  "listeners": {
    "actionTriggered": function(evt, meta) {
      persistCurrentData();
    }
  }
}

Complete Property Reference

Property Type Required Default Description
compType string Yes - Component type (actionButton/splitActionButton/compactTool/iconOnly/subtle)
compId string No Auto-generated Unique identifier for app.compId access
label string No - Visible button text
nativeIcon string No - Built-in icon name or UTF-8 character
customIcon string No - Custom asset path for button icon
iconPosition string No "left" Icon position: left/right/top/bottom
iconScale string No - Independent icon size (e.g., "1.5em", "24px")
preset string No - Visual theme preset: accent/borderless/compactTool
shape string No "soft" Button shape: round/sharp/soft
isDisabled boolean No false Disables button interaction and grays it out
isActive boolean No false Sets toggle/group button active state
group string No - Groups buttons for radio-like mutual exclusion
hideActiveBackground boolean No false Hides background color when toggle/group button is active
hotkey string No - Keyboard shortcut combination (e.g., "Ctrl+Alt+P")
triggerOnPress boolean No false Triggers action on mousedown/touchstart instead of mouseup/touchend
enableRepeatClick boolean No false Enables repeated action triggering while button is held
skipTabIndex boolean No false Excludes button from tab navigation
allowFocus boolean No true Allows button to receive keyboard focus
tooltip string No - Text displayed on mouse hover
useLabelAsBadge boolean No false Displays button text as a notification badge
scale string No - Global button scaling factor (e.g., "0.75em", "18px")
dropdown object No - Dropdown menu configuration (requires isNestedConfig: true)
className string No - Custom CSS class name for additional styling
isVisible boolean No true Controls button visibility

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

β—ŽFeel free to join the discussion and share your thoughts.