Nighttime Possum Meandering
Learn about our RFC process, Open RFC meetings & more.Join in the discussion! »

atomico

0.12.4 • Public • Published

Atomico

CircleCI npm gzip

Atomico is a small 3kb library for creating interfaces based on web-components, hooks, props and virtual-dom.

If you want to try Atomico and you need help tell me in Twitter Uppercod🤓.

read in Spanish

  1. Overview
  2. Installation
  3. Creating a web-component
    1. Jsx
    2. Template string
    3. Virtual-dom
  4. Defining a web-component
  5. Properties and attributes of the web-component
    1. Props
    2. Types
  6. Hooks
    1. Hook guide
  7. Examples
    1. Calculator
    2. Watch

Overview

import { h, customElement } from "atomico";
 
function WebComponent({ value }) {
    return <host>Hi! {value}!</host>;
}
 
WebComponent.props = {
    value: String
};
 
customElement("any-name", WebComponent);

Where:

  • h: pragma that builds virtual-dom using JSX using a compiler like babel.
  • customElement: function that registers the web component in the browser, eg <any-name></any-name>.
  • WebComponent: function used to represent the state of the web component's DOM.
  • WebComponent.props: represents the props that build the properties and attributes that are responsible for communicating the state to the web-component

Installation

npm install atomico

Creating a web-component

The interface of a web-component is defined in atomico thanks to the virtual-dom declared by using Jsx, Template string or a Declarative object.

Jsx

import { h } from "atomico";
 
function WebComponent() {
    return (
        <host>
            <button onclick={() => console.log("click")}>
                my web-component
            </button>
        </host>
    );
}

Template string

Thanks to htm you can build the virtual-dom using the html function, eg:

import html from "atomico/html";
 
function MyTag() {
    return html`
        <host>
            <button onclick=${() => console.log("click")}>
                my web-component
            </button>
        </host>
    `;
}

Virtual dom

The output of the previous exercise either using Jsx or Template string is equivalent to a declarative object known as virtual-dom, eg:

function MyTag() {
    return {
        nodeType: "host",
        children: {
            nodeType: "button",
            onclick() {
                console.log("click");
            },
            children: "my web-component"
        }
    };
}

Atomico allows the manipulation of the web-component through the virtual-dom by declaring the tag <host />, eg:

let styleSheet = `
    :host{
        display:flex;
        flex-flow:row wrap;
    }
    button{
        border:none;
    }
`;
 
function MyTag() {
    return (
        <host
            shadowDom
            styleSheet={styleSheet}
            onclick={() => console.log("click!")}
        >
            inside web-component
            <button>1</button>
            <button>2</button>
            <button>3</button>
        </host>
    );
}

The use of the shadowDom must be declared as part of the virtual-dom.

Defining a web-component

import { h, customElement } from "atomico";
 
function MyCustomButton() {
    return (
        <host>
            <button>🤓 my custom button</button>
        </host>
    );
}
 
customElement("my-custom-button", MyCustomButton);

Where :

  • h: pragma that generates the virtual-dom, for the jsx compiler
  • customElement: function that registers the web-component in the browser, this transforms the function to a class that extends HTMLElement

Alternatively you can export the class to later define the name of your web-component, eg:

let HTMLWebComponent = customElement(WebComponent);
 
customElements.define("my-custom-name", HTMLWebComponent);

Where :

  • HTMLWebComponent: WebComponent function that already extended the HTMLElement, making it a valid constructor to be declared by customElements.define

Properties and attributes of the web-component

The web-component reaction to external states, previously defined and accessible as properties or attributes, eg:

<!--case attributo-->
<web-component my-field="./my-source">
    <!--case property-->
    <script>
        document.querySelector("web-component").myField = "./my-source";
    </script> 
</web-component>

The definition of properties or attributes in the web-component created with atomico is through the props property associated with the function declared by the component, eg:

function WebComponent({ myField }) {
    return (
        <host>
            <h1>{myField}</h1>
        </host>
    );
}
 
WebComponent.props = {
    myField: {
        type: String,
        value: "hi!"
    }
};

Props

Props can be simple to complex configurations, eg

Just declaring the type

WebComponent.props = {
    fieldObject: Object
};

Type statement and additional behavior

WebComponent.props = {
    fieldObject: {
        type: Object,
        reflect: true,
        dispatchEvent: true,
        get value() {
            return { ...initialObject };
        }
    }
};

Where :

  • fieldObject.type: defines the type of data to be supported by the property or attribute.
  • fieldObject.reflect:it allows to reflect the state in the web-component as an attribute.
  • fieldObject.dispatchEvent: allows dispatching a custom event in each change associated with the property.
  • fieldObject.value:It is the value that the property will take by default when initializing.

Property types

These are declared by the index type.

Type Description
String the type of prop must be a String
Number the type of prop must be a Number
Boolean the type of prop must be a Boolean, it is considered valid Boolean [1, 0,"true","false", true, false].
Object the type of prop must be a Object, if it is a string, apply JSON.parse for a type analysis
Array the type of prop must be a Array, if it is a string, apply JSON.parse for a type analysis
Function the type of prop must be a Function, if string you will get the global function in execution
Date the type of prop must be a Date, if a string applies new Date for a type analysis

There are types that are only supported as property and not as an attribute being these: Promise,Symbol or any global constructor whose type is defined by [Object <Type>]

Hooks

The potential hooks even more the creation of web-components, being able to create states and effects that do not fit the context of the props, this is very useful for the creation of reusable custom processes that do not depend on the context of the web-component .

In a regular cycle every time a property associated with the web-components changes, a rendering of the new state of the DOM associated with the web-components is generated, the hooks for example can force this rendering without the need to go through the update of the props maintaining local states, they can even subscribe to the rendering process, for example useEffect is executed after rendering asynchronously, for this I invite you to see the hooks guide

Install

npm i [email protected]

Version

0.12.4

License

ISC

Unpacked Size

154 kB

Total Files

49

Last publish

Collaborators

  • avatar