npm

@citizendev/assorted-input

0.0.1 • Public • Published

Bubble Plugin: ${REPO_NAME}

About:

${REPO_DESCRIPTION}

Features:

  • Basic template for building Preact based elements.
  • Basic template for building functional elements.

How does it work?

For Preact based element, we register a Preact component as a web component. This resolve the issue of race-condition between Bubble element initialization and code loading.

For Functional elements, we would register a retry pattern until the plugin's code is fully loaded.

How to set up:

Clone and prepare:

Clone this repository, run yarn to install dependencies.

Add plugin & setup glue code:

Create a Bubble plugin. You can also fork this plugin for a basic template. Remember that you will still have to review and replace the appropriate variables.

For Preact based elements:

  1. Create a new Bubble plugin element

  2. Add this piece of code into the element header

    <script src="https://www.unpkg.com/preact@^10.19.3/dist/preact.umd.js"></script>
    <script src="https://www.unpkg.com/preact@^10.19.3/hooks/dist/hooks.umd.js"></script>
    <script src="https://www.unpkg.com/preact@^10.19.3/compat/dist/compat.umd.js"></script>
    <script src="https://www.unpkg.com/preact-custom-element@^4.3.0/dist/preact-custom-element.umd.js"></script>
    <script src="https://www.unpkg.com/@preact/signals-core@^1.5.1/dist/signals-core.min.js"></script>
    <script src="https://www.unpkg.com/@preact/signals@^1.2.2/dist/signals.min.js"></script>
    
    <!-- Uncomment this section when you want to develop the plugin. 
         Add a space in between the next arrow to quickly comment the section below -->
    <script src="http://localhost:5173/@vite/client" type="module"></script>
    <script src="http://localhost:5173/src/index.ts" type="module"></script>
    <!-- END_DEV_SCRIPT -->
    
    <!-- Uncomment the next lines when you want to deploy to live. 
         Also make sure to update the version of the library. 
         Add a space in between the next arrow to quickly comment the section below -- >
    <script src="https://www.unpkg.com/@citizendev/${REPO_NAME}@0.0.1/dist/index.umd.js"></script>
    <link href="https://www.unpkg.com/@citizendev/${REPO_NAME}@0.0.1/dist/style.css" rel="stylesheet" />
    <!-- END_PROD_SCRIPT -->
  3. Set the initialize function content. You would want to match this with the web component names. The example file has this as counter, as shown in PasswordInput.tsx

    function(instance, context) {
     /* SETUP: replace this variable accordingly. Make sure this matches the other instances. */
     const ELEMENT_NAME = "counter";
     instance.data._elementReady = false;
     instance.data._element = document.createElement(ELEMENT_NAME);
     instance.canvas.append(instance.data._element);
    
     instance.data._tryInject = function tryInject(retryLeft, properties) {
         const element = instance.data._element;
         if (!retryLeft || retryLeft <= 0 || !element) {
             return;
         }
         if (!element._vdom) {
             setTimeout(() => tryInject(retryLeft - 1, properties), 200);
             return;
         }
    
         element.properties = properties;
    
         if (!element.instance) {
             element.instance = instance;
         }
         if (!element.bubbleContext) {
             element.bubbleContext = context;
         }
    }
  4. Set the update function content.

    function(instance, properties, context) {
        instance.data._tryInject(50, properties);
    }
  5. Set the preview function content. Because the preview environment is isolated from the Bubble Editor environment, we have to do a full in script loading of the resources

    function(instance, properties) {
        function loadJS(url, module = false) {
            return new Promise((resolve, reject) => {
                let scriptEle = document.createElement("script");
                document.head.appendChild(scriptEle);
                scriptEle.onload = function () {
                    resolve();
                }
                scriptEle.setAttribute("type", module ? "module" : "text/javascript" );
                scriptEle.setAttribute("src", url);
            });
        }
    
        /* Make the appropriate changes to the following lines */
        const DEV = false;
        const ELEMENT_NAME = "counter";
        const PACKAGE_LINK = "https://www.unpkg.com/@citizendev/bubble-file-uploader@0.1.2";
    
        let jsLink, cssLink;
    
        if (DEV) {
            cssLink = "http://localhost:5173/src/style.css"
            jsLink = "http://localhost:5173/src/index.ts";
        } else {
            cssLink = `${PACKAGE_LINK}/dist/style.css`;
            jsLink = `${PACKAGE_LINK}/dist/index.umd.js`;
        }
    
    
    
        jQuery("html").height("100%");
        jQuery("body").height("100%");
    
        jQuery("head").append(`<link rel="stylesheet" href="${cssLink}" />`);
    
        (async () => {
            if (DEV) {
                await loadJS("http://localhost:5173/@vite/client", true);
            }
            await loadJS("https://www.unpkg.com/preact@^10.19.3/dist/preact.umd.js");
            await loadJS("https://www.unpkg.com/preact@^10.19.3/hooks/dist/hooks.umd.js");
            await loadJS("https://www.unpkg.com/preact@^10.19.3/compat/dist/compat.umd.js");
            await loadJS("https://www.unpkg.com/preact-custom-element@^4.3.0/dist/preact-custom-element.umd.js");
            await loadJS("https://www.unpkg.com/@preact/signals-core@^1.5.1/dist/signals-core.min.js");
            await loadJS("https://www.unpkg.com/@preact/signals@^1.2.2/dist/signals.min.js");
    
            await loadJS(jsLink, DEV);
            const element = document.createElement(ELEMENT_NAME);
            instance.canvas.append(element);
    
            function tryInject(retryLeft, properties) {
                if (!retryLeft || retryLeft <= 0 || !element) {
                    return;
                }
                if (!element._vdom) {
                    setTimeout(() => tryInject(retryLeft - 1, properties), 200);
                    return;
                }
    
                element.properties = properties;
    
                if (!element.instance) {
                    element.instance = instance;
                    element.isPreview = true;
                }
            }
    
            tryInject(25, properties);
        })();
    }
  6. Open test app.

Readme

Keywords

none

Package Sidebar

Install

npm i @citizendev/assorted-input

Weekly Downloads

1,153

Version

0.0.1

License

none

Unpacked Size

36.4 kB

Total Files

6

Last publish

Collaborators

  • trung-nh
  • antran22