Plugin System API v1.0

Plugin System Overview

Extend WebVB Studio with custom controls and functions. Plugins are self-contained JSON packages that can be installed, shared, and distributed as .vbplugin files.

What Plugins Can Provide

🎨

Custom Controls

New visual controls that appear in the Toolbox, render in the Designer with live preview, and fully function at runtime. Star ratings, color pickers, progress bars—anything you can imagine.

{f}

Custom Functions

New functions available globally in VB and Python code. Add utility helpers, validators, formatters, or domain-specific operations your projects need.

🎭

Custom CSS Styles

Inject global CSS styles that your controls or the entire application can use. Define animations, keyframes, and styling that persists while the plugin is active.

📖

Help Documentation

Include rich HTML help content that describes your controls and functions. Users can view this documentation from the Plugin Manager.

Architecture Overview

The plugin system is built around a central PluginManager singleton that handles the entire lifecycle. Plugins are stored in localStorage and loaded on app startup.

📦
.vbplugin File
JSON package
🔧
PluginManager
Install & lifecycle
🏗️
Registration
Controls & functions
▶️
Runtime
Sandboxed execution
localStorage persistence CSS injection new Function() sandbox React subscription

Plugin Lifecycle

INSTALL
Plugin JSON is validated (metadata, API version, control/function integrity). If valid, stored in localStorage and styles are injected. Status set to active.
ACTIVE
Controls appear in the Toolbox under "Plugins" category. Functions are available in VB/Python code. CSS styles are injected into the document head.
DISABLE
Controls are removed from Toolbox, functions are unregistered, and CSS styles are removed from the DOM. The plugin definition stays in storage for re-enabling.
UNINSTALL
Everything is cleaned up: styles removed, plugin deleted from localStorage. Existing controls on forms that reference this plugin will show an error state.

Plugin File Format (.vbplugin)

A .vbplugin file is simply a JSON file containing a PluginDefinition object. Everything the plugin needs—code, metadata, styles, and documentation—is bundled into this single file.

Top-Level Structure
{
  "pluginApiVersion": "1.0",
  "metadata": { ... },
  "controls": [ ... ],
  "functions": [ ... ],
  "styles": "CSS string",
  "helpContent": "HTML string"
}

Key Design Decisions

  • Self-contained: No external dependencies or file references. Everything is inlined.
  • Code as strings: Renderer code and function implementations are JavaScript strings executed via new Function().
  • Human-readable: The JSON format is easy to edit by hand or generate programmatically.
  • Portable: Share plugins by sending a single file, pasting JSON, or hosting on any server.

Complete Type Reference

Below is the full TypeScript interface reference for every object in the plugin system. These types define the contract between your plugin and WebVB Studio.

interface PluginDefinition

The root object of every plugin. This is what gets serialized into the .vbplugin file.

interface PluginDefinition {
  pluginApiVersion: '1.0';       // Must be "1.0"
  metadata: PluginMetadata;       // Required: name, id, version, author
  controls?: PluginControlDef[];  // Optional: custom controls
  functions?: PluginFunctionDef[];// Optional: custom functions
  styles?: string;                // Optional: CSS to inject
  helpContent?: string;           // Optional: HTML documentation
}

interface PluginMetadata

Identifies and describes your plugin. The id, name, and version fields are required.

Property Type Required Description
id string Yes Unique identifier, e.g. "com.example.colorpicker"
name string Yes Human-readable display name
version string Yes Semantic version, e.g. "1.0.0"
description string Yes Short description shown in Plugin Manager
author PluginAuthor Yes Object with name, optional email and url
icon string No Emoji or data:image URI for the plugin icon
category string No Category for organizing, e.g. "Input", "Display", "Functions"
tags string[] No Searchable tags like ["rating", "input"]
license string No License identifier, e.g. "MIT", "Apache-2.0"
homepage string No Project URL or documentation link
minAppVersion string No Minimum WebVB Studio version required

interface PluginControlDef

Defines a custom visual control. Each control provides renderers for both designer preview and runtime execution.

Property Type Description
typeName string Unique name, e.g. "StarRating". Registered as "plugin:com.example/StarRating"
displayName string Label shown in the Toolbox panel
icon string Emoji or data URI for the Toolbox icon
description string Tooltip shown when hovering in the Toolbox
toolboxCategory string? Toolbox section (defaults to "Plugins")
defaultWidth number Width in pixels when first placed on a form
defaultHeight number Height in pixels when first placed on a form
properties PluginPropertyDef[] Property schema for the Properties panel
events PluginEventDef[] Events the control can fire
designerRenderHtml string Required. JS function body receiving (props), must return HTML string
runtimeRenderHtml string Required. JS function body receiving (props, controlId), returns HTML
runtimeInitCode string? Runs after mount. Receives (element, props, controlId, fireEvent)
runtimeCleanupCode string? Runs on unmount. Clean up intervals, listeners, etc.
runtimePropertyChangeCode string? Called when property changes. Receives (element, propName, newValue, oldValue, props)

interface PluginPropertyDef

Defines a property that appears in the Properties panel when the control is selected in the designer.

interface PluginPropertyDef {
  id: string;            // Property key, e.g. "Value", "MaxStars"
  label: string;         // Display label in Properties panel
  type: 'text' | 'number' | 'boolean' | 'color' | 'select' | 'textarea';
  defaultValue?: any;    // Default when control is first created
  options?: string[];    // Choices for 'select' type
  description?: string;  // Tooltip text
  category?: string;     // Group heading, e.g. "Appearance", "Behavior"
}

Supported Property Types

text
Single-line text input
number
Numeric spinner input
boolean
Checkbox toggle
color
Color picker control
select
Dropdown with options[]
textarea
Multi-line text area

interface PluginEventDef

Declares an event that the control can fire. Users write event handlers for these in VB/Python code.

interface PluginEventDef {
  name: string;          // Event name, e.g. "Change", "Click", "ColorSelected"
  description?: string;  // Explains when this event fires
  params?: string[];     // Parameters passed to the handler, e.g. ["NewValue"]
}

Example: If your control defines an event Change with params ["NewValue"], users write:

VB6:
Sub StarRating1_Change(NewValue)
  MsgBox "Rating: " & NewValue
End Sub
Python:
def StarRating1_Change(NewValue):
  MsgBox(f"Rating: {'{'}NewValue{'}'}")

interface PluginFunctionDef

Defines a custom function available in VB and/or Python code. Functions are registered globally when the plugin is active.

Property Type Description
name string Function name, callable in VB/Python code
description string Description for help and IntelliSense autocomplete
params PluginFunctionParam[] Parameter definitions (name, type, description, optional, defaultValue)
returnType string? Return type description for documentation
jsCode string Required. JavaScript function body. Parameters are available as named variables.
isAsync boolean? Whether the function returns a Promise
category string? Category for help grouping, e.g. "String", "Math"

interface InstalledPlugin

Wraps a PluginDefinition with runtime state. This is what the PluginManager stores and tracks.

interface InstalledPlugin {
  definition: PluginDefinition;
  status: 'active' | 'disabled' | 'error';
  installedAt: string;     // ISO 8601 date string
  error?: string;          // Error message if status is 'error'
}

Control Type Namespacing

To avoid collisions between plugins, all plugin control types are automatically namespaced. When you define a control with typeName: "StarRating" in a plugin with id: "com.webvb.starrating", the control is registered internally as:

plugin:com.webvb.starrating/StarRating

The format is plugin:{pluginId}/{typeName}. This ensures two plugins can both define a "ColorPicker" control without conflict. Helper functions are provided:

// Build a namespaced type string
getPluginControlType("com.webvb.starrating", "StarRating")
// → "plugin:com.webvb.starrating/StarRating"

// Check if a type is from a plugin
isPluginControlType("plugin:com.webvb.starrating/StarRating")
// → true

// Parse back to components
parsePluginControlType("plugin:com.webvb.starrating/StarRating")
// → { pluginId: "com.webvb.starrating", typeName: "StarRating" }

PluginManager API

The pluginManager singleton provides the full API for managing plugins. Import it from services/PluginManager.

Installation

install(definition: PluginDefinition): { success: boolean; error?: string }
Validates and installs a plugin. Checks for required metadata, valid API version, and control/function integrity. On success, injects CSS and persists to localStorage.
uninstall(pluginId: string): boolean
Completely removes a plugin. Cleans up injected styles, deletes from storage, and notifies subscribers.

Enable / Disable

setEnabled(pluginId: string, enabled: boolean): boolean
Toggles a plugin between active and disabled states. Enabling re-injects CSS styles; disabling removes them.

Query APIs

getPlugin(pluginId): InstalledPlugin | undefined

Get a specific plugin by ID.

getAllPlugins(): InstalledPlugin[]

Get all installed plugins (active, disabled, and error).

getActivePlugins(): InstalledPlugin[]

Get only plugins with 'active' status.

getPluginControls(): Array<{ controlType, control, pluginId, pluginName }>

Get all controls from active plugins, with their namespaced types.

getPluginFunctions(): Array<{ fn, pluginId, pluginName }>

Get all functions from active plugins.

getDefaultProperties(controlType): Record<string, any>

Get default property values for a plugin control type.

getPropertySchema(controlType): PluginPropertyDef[]

Get the property schema for the Properties panel.

Import / Export

exportPlugin(pluginId: string): string | null
Returns the plugin definition as a formatted JSON string. Returns null if plugin is not found. Use this to generate .vbplugin files for distribution.
importPlugin(jsonString: string): { success: boolean; error?: string; pluginId?: string }
Parses a JSON string and installs the plugin. Returns success status and the plugin ID on success, or an error message on failure.

React Subscriptions

subscribe(listener: () => void): () => void
Register a listener that fires whenever plugins change (install, uninstall, enable, disable). Returns an unsubscribe function. Use this in React components to trigger re-renders.
React Hook Example
function usePlugins() {
  const [plugins, setPlugins] = useState(
    pluginManager.getAllPlugins()
  );
  
  useEffect(() => {
    return pluginManager.subscribe(() => {
      setPlugins(pluginManager.getAllPlugins());
    });
  }, []);
  
  return plugins;
}

Runtime Helpers

createRendererFunction(codeString): (props, controlId?) => string
Creates a sandboxed function from a renderer code string using new Function(). Returns a fallback error renderer if compilation fails. Used internally for designerRenderHtml and runtimeRenderHtml.
createPluginFunction(fn: PluginFunctionDef): (...args) => any
Compiles a plugin function definition into a callable JavaScript function. Parameter names are extracted and used as new Function() arguments. Supports async functions when isAsync: true.
getStdLibFunctions(): Record<string, Function>
Returns all active plugin functions as a name→function map, ready to merge into the interpreter's standard library. Function names are lowercased for case-insensitive lookup.

Code Execution Model

Plugin code runs in a semi-sandboxed environment. Both renderer functions and custom functions are compiled using new Function(), which provides separation from the main application scope.

Designer Renderer

The designerRenderHtml code string becomes:

new Function('props', 'controlId', yourCodeString);

Receives the current property values. Must return an HTML string for the designer preview.

Runtime Renderer

The runtimeRenderHtml code works identically but typically includes interactive elements (event handlers, hover effects, etc.).

Runtime Init Code

The runtimeInitCode runs once after the control is mounted to the DOM. It has access to these variables:

element
The DOM element containing the control's HTML
props
Current property values object
controlId
Unique ID of this control instance
fireEvent(name, data)
Fires an event to the VB/Python handler
setProperty(name, value)
Programmatically updates a control property and triggers re-render

Custom Functions

Function code becomes:

new Function('param1', 'param2', ..., yourJsCode);

Parameters are injected as named arguments. The code should use return to produce a value.

Built-in Example Plugins

WebVB Studio includes four example plugins in the Gallery tab of the Plugin Manager. These demonstrate different plugin capabilities and serve as templates for your own plugins.

Star Rating

com.webvb.starrating

Interactive star rating with configurable max stars, colors, and sizes. Click to set value.

Control Events Properties
📊

Progress Bar

com.webvb.progressbar

Animated progress bar with stripes, labels, and multiple visual styles (flat, rounded, pill).

Control CSS Animation Select Property
🎨

Color Picker

com.webvb.colorpicker

Visual color palette with preset swatches, native picker integration, and editable hex input.

Control Complex Init Multiple Inputs
🔧

Utility Functions

com.webvb.utilities

7 helper functions: Slugify, Truncate, Capitalize, RandomRange, Clamp, IsEmail, IsURL.

Functions Only No Controls String/Math/Validation

Managing Plugins (UI)

The Plugin Manager dialog (accessible from the toolbar) provides a full UI for managing plugins with four tabs:

1

Installed

View all installed plugins with their status. Enable/disable plugins with a toggle, export them as .vbplugin files, or uninstall them completely.

2

Gallery

Browse and install built-in example plugins with one click. See descriptions, categories, and tags before installing. Already installed plugins show their current status.

3

Import

Load plugins from external .vbplugin files using a file picker, or paste raw JSON directly into the text area and click Install.

4

Create

A built-in JSON editor with a starter template. Write your plugin definition directly in the browser, validate it, and install immediately. Great for prototyping new plugins.

Next Steps