📖 Basic Plugin Development

The Basic Structure

Every plugin exports an object with a mount function:

export default {
    name: 'plugin-name',      // Plugin identifier
    displayName: 'My Plugin', // Optional: friendly name shown in UI
    version: '1.0.0',         // Version number
    
    mount: function(element, options) {
        // Your code here
        return {};
    }
};

The mount Function

This is the heart of your plugin. It runs for every element that uses your plugin.

mount: function(element, options) {
    // element = the HTML element (<div>, <button>, etc.)
    // options = settings from data-cb-* attributes or settings UI
    
    // Do your magic here...
    
    // Always return an object (or null on error)
    return { /* anything you want to track */ };
}

Key Points:

  • Gets called once per element
  • Receives the element and its options
  • Must return an object (can be empty {} or null on error)
  • Can be async if needed for complex initialization

Getting Options from HTML

Options come from data-cb-* attributes:

HTML:

<div data-cb-type="tooltip" 
     data-cb-text="Hello" 
     data-cb-position="top">
</div>

JavaScript:

mount: function(element, options) {
    var text = options.text;         // "Hello"
    var position = options.position; // "top"
}

Rules:

  • Attributes must start with data-cb-
  • Use lowercase with hyphens: data-cb-my-option
  • Access in code with camelCase: options.myOption

More Examples

Example 1: Simple Tooltip

Shows a tooltip when hovering over an element.

javascript

export default {
    name: 'tooltip',
    version: '1.0.0',
    
    mount: function(element, options) {
        var tooltipText = options.text || 'Tooltip';
        var tooltip = document.createElement('div');
        
        // Style the tooltip
        tooltip.textContent = tooltipText;
        tooltip.style.cssText = 'position:fixed; background:#333; color:#fff; ' +
                                'padding:5px 10px; border-radius:4px; ' +
                                'font-size:12px; display:none; z-index:9999;';
        document.body.appendChild(tooltip);
        
        // Show on hover
        element.addEventListener('mouseenter', function(e) {
            tooltip.style.display = 'block';
            tooltip.style.left = e.clientX + 10 + 'px';
            tooltip.style.top = e.clientY + 10 + 'px';
        });
        
        // Hide when mouse leaves
        element.addEventListener('mouseleave', function() {
            tooltip.style.display = 'none';
        });
        
        return { tooltip: tooltip };
    }
};

Usage:

html

<span data-cb-type="tooltip" data-cb-text="Helpful information">
    Hover me
</span>

Example 2: Toggle Visibility

Shows/hides another element when clicked.

javascript

export default {
    name: 'toggle',
    version: '1.0.0',
    
    mount: function(element, options) {
        var targetId = options.target;
        var target = document.getElementById(targetId);
        
        if (!target) {
            console.error('Target element not found:', targetId);
            return null;
        }
        
        element.addEventListener('click', function() {
            if (target.style.display === 'none') {
                target.style.display = 'block';
            } else {
                target.style.display = 'none';
            }
        });
        
        return { target: target };
    }
};

Usage:

html

<button data-cb-type="toggle" data-cb-target="myContent">
    Toggle Content
</button>

<div id="myContent">
    This content can be shown/hidden
</div>

Cleanup with unmount

If your plugin needs cleanup (remove event listeners, timers, etc.), add an unmount function:

export default {
    name: 'my-plugin',
    version: '1.0.0',
    
    mount: function(element, options) {
        var timer = setInterval(function() {
            console.log('Running...');
        }, 1000);
        
        return { 
            timer: timer,
            stop: function() {
                clearInterval(timer);
            }
        };
    },
    
    unmount: function(element, instance) {
        if (instance && instance.stop) {
            instance.stop();
        }
    }
};

Async Mount for Complex Plugins

For plugins that need complex initialization:

export default {
    name: 'complex-plugin',
    version: '1.0.0',
    
    async mount(element, options) {
        try {
            await someAsyncOperation();
            const instance = createComponent(element, options);
            return instance;
        } catch (error) {
            console.error('Plugin mount error:', error);
            return null;
        }
    }
};

Class-Based Pattern

For sophisticated plugins, use a class-based approach:

class MyComponent {
    constructor(element, options) {
        this.element = element;
        this.options = options;
        this.init();
    }
    
    init() {
        // Setup your component
    }
    
    destroy() {
        // Cleanup
    }
}

export default {
    name: 'my-plugin',
    version: '1.0.0',
    
    async mount(element, options) {
        try {
            const instance = new MyComponent(element, options);
            return instance;
        } catch (error) {
            console.error('Mount error:', error);
            return null;
        }
    },
    
    unmount(element, instance) {
        if (instance && typeof instance.destroy === 'function') {
            instance.destroy();
        }
    }
};

View this page on GitHub

© 2026 InnovaStudio

This site is built with Site Builder Kit