DEV Community

Matias Trujillo
Matias Trujillo

Posted on

Create web components without using a class with Atomico

Web-components with Atomico

logo

Have you ever heard of Atomico? I do not think so, but I explain briefly, Atomico is a library for the creation of interfaces like React, Atomico is small only 2.7kB, which include Virtual-Dom, Hooks (useState, useEffect, useContext, useRef, useMemo) , manipulation of contexts and more ... Atomico is independent of web-components, but for this example we will see how it works in the creation of web-components

Hello world with Atomico.

First see the following example and then we will explain it by parts

// Part 1: import
import { h } from "@atomico/core";
import { register } from "@atomico/web-component";
// Part 2: creation of the web-component
function MyTag(props) {
    return (
        <host shadowDom>
            <style>{`
            :host{display:block;background:teal}
        `}</style>
            <h1>message</h1>
            {props.message}
        </host>
    );
}
// part 3: web-component registration
register(<my-tag message>{MyTag}</my-tag>);

if you understood the code means that Atomico is naturally expressive.

Part 1: import

We will use @atomico/web-components, this allows registering a web-component using the expressiveness of JSX.


import { h } from "@atomico/core"; // 2.7kB gzip
import { register } from "@atomico/web-component"; // 700B gzip

Part 2: creation of the web-component

the components in @atomico/core are functions, in Atomico you will never use classes with complicated life cycles and you will not have to deal withthis and the other problems of the classes.


function MyTag(props) {
    return (
        <host shadowDom>
            <style>{`
            :host{display:block;background:teal}
        `}</style>
            <h1>message</h1>
            {props.message}
        </host>
    );
}

Note part 2

I will stop to explain a concept within Atomico, if you know the shadowDom you will know that you can use inside the CSS of a selector called :host that points to the container, inside @atomico/ web-component you can use the tagName <host/> pointing to the same web-component, the advantage of this is that you can manipulate the state of the component declaratively, for example by using the property shadowDom we are enabling the use of shadowDom in the component.

<host shadowDom>

part 3: web-component registration

I hope you like this feature, as the author of Atomico I like the use of JSX over the template string, as it is highly declarative.

register(<my-tag message>{MyTag}</my-tag>)

with the register function we will use JSX highly expressive to define that we will register a web-component called my-tag, with an observable property called message

you can invoke this web-component from the document and our MyTag function will receive themessage property from the <my-tag> tag.

<body>
    <my-tag message="Hi! Atomico"></my-tag>
</body>

I almost forgot, you can use hooks inside your web-component 😎.

You can read the documentation of @atomico/core, to know in more detail the hooks, for the example we will use useEffect this hooks allows us for example to observe what happens after each render, we will use it to redefine the title of our site.


import { h, useEffect } from "@atomico/core";
import { register } from "@atomico/web-component";

function MyTag(props) {
    useEffect(() => {
        document.title = "mounted my-tag!";
        return () => {
            document.title = "unmounted my-tag!";
        };
    });
    return (
        <host shadowDom>
            <style>{`
            :host{display:block;background:teal}
        `}</style>
            <h1>message</h1>
            {props.message}
        </host>
    );
}

register(<my-tag message>{MyTag}</my-tag>);

Author's note 🤓

what I have shared is just a small example of how Atomico works when creating web-components, I hope that @atomico/core and @atomico/web-component is interesting as a project, as an author I value your opinion and contribution towards this project.

Additionally I want to comment that Atomico is for the development of complex web-components and applications, if you want to develop a button or something that does not require so much reactivity I recommend web-component without frame or library better.

Finally I appreciate the creativity of the React team to introduce the hooks, I was delighted with them for the ability to reuse logic and more.

Discussion (1)

Collapse
hoangng92357789 profile image
Hoang Nguyen

Hi Matias,
Thanks for your sharing of Atomico.
I love it as following latest React concepts.
I had started on using Atomico creating some web component as examples.

From the other side, I wonder how to wrap an existing React component as Atomico web component?
I think it could be in Atomico's useEffect we call ReactDOM.render (and unmountComponentAtNode when returning), but not sure how exactly to make it.
Would you please help with some simple working example?
Thanks Matias!