atomico

Atomico a micro-library for creating webcomponents using only functions, hooks and virtual-dom.

MIT License

Downloads
22.9K
Stars
1.1K
Committers
7

Bot releases are hidden (Show)

atomico - Delete the previous change 1.28.2 (tsx types for the form tag)

Published by UpperCod about 3 years ago

Typescript does not infer the events for the form tag in JSX and TSX, when autocompleting the fields.
TODO: Find a solution to this.

This version fixes the previous change, but the form tag continues with the TS bug.

The autocomplete did not attach the native events available in the DOM in the form tag, this fixes it

atomico - Fix type for TS when using JSX or TSX

Published by UpperCod about 3 years ago

Fix the style type in typescript when using the custom element as a constructor in JSX or TSX.

Now this will not generate an error in the style property

<Image style="width: 200px">

Minor changes in this version.

Better typing experience for TSX and JSX.

Native Events

Before Atomico directly reflected the event properties of Lib.dom.d.ts of Typescript, now atomic improves this, adding a proxy type that completes target and currentTarget without breaking the behavior of the event, example:

<input oninput={(event)=>{
    event.target.value
}}/>

Improved autocompletion for SVG and its elements

Property map svg.

Now always the slot attribute will be defined by setAttribute.

atomico - Execute parent class connectedCallback and disconectedCallback

Published by UpperCod about 3 years ago

This improvement helps to reuse classes that depend on the execution of connectedCallback and disconnectedCallback. Atomico will execute these methods routinely when calling each method.

Example

import { c, css, html } from "../core.js";

function a(props) {
    console.log(props)
    return html`<host shadowDom>a</host>`;
}

a.props = {
    b: Number
}

a.styles = css`
    :host {
        font-size: 200px;
    }
`;

const F = c(a,class extends HTMLElement{
    constructor(){
        super();
        console.log("create")
    }
    attributeChangedCallback(...args){
        console.log(args)
    }
    static get observedAttributes(){
        return ['a'];
    }
    connectedCallback(){
        console.log("...")
    }
})

customElements.define("my-wc", F);

This enhancement is guaranteed to reflect the execution of the following methods

  1. constructor: native
  2. connectedCallback: native
  3. disconnectedCallback: native
  4. observedAttributes: native, Atomico performs a merge of the attributes to observe and distributes them according to listener
  5. attributeChangedCallback: native
  6. styles: internal Atomico to inherit css
atomico - improves SSR options

Published by UpperCod over 3 years ago

In version 1.25, options.ssr is of the Boolean type, in this version it is of the function type, thus allowing the capture of the components to render

atomico - New features Hydration and SSR

Published by UpperCod over 3 years ago

New features Hydration and SSR

Hydration

This support is based on recovering the DOM already defined in the node used by the render function, avoiding the need to recreate the DOM tree, this functionality is compatible with the render function and the webcomponents generated by Atomico.

hydration with webcomponents

For all purposes Atomico only hydrates the DOM, it must consider a parallel strategy to inject the live DOM into the shadowRoot of a webcomponent.

Example of hydration with render

import { render, html } from "atomico";

const div = document.createElement("div");

div.innerHTML = "<h1>...</h1>";

render(html`<host><h1>...</h1></host>`, div, undefined, true)

The fourth parameter of the render represents the hydration of the DOM.

Example of hydration with webcomponents

The following example shows a template-based hydration strategy, the data-hydrate attribute is relevant to this strategy but defines whether the component will reuse the existing DOM.`

<web-component data-hydrate>
    <template shadowroot="open"><h1>...</h1></template>
<web-component>

SSR

Atomico's SSR support allows avoiding the execution of the effects that normally defend asynchronous processes. Another point to consider is that the client to render must make use of the following options.

Server

import {options}  from "atomico";

options.sheet = false;
options.ssr = true;
  1. the sheet property equal to false avoids the use of CSSStyleSheet, this will inject a style tag with the CSS.
  2. the ssr property equal to true prevents the execution of the component's secondary effects.

Browser

import {options}  from "atomico";

options.sheet = false;
  1. the sheet property equal to false avoids the use of CSSStyleSheet, this reuses the style tag defined from the server.
atomico - new renderOnce property

Published by UpperCod over 3 years ago

Improve

new renderOnce property

This property can be used in any virtual node other than host and allows to define if a node is static, this prevents the diff from being applied 2 times if the type of the node is equal to the previous one, example:

import { html, c, useProp } from "../core.js";

function component() {
    const [count, setCount] = useProp("count");
    const increment = () => setCount((count) => count + 1);
    return html`<host>
        ${count}
        <div renderOnce>
            <button onclick=${increment}>click</button>
            <button onclick=${increment}>click</button>
            <button onclick=${increment}>click</button>
            <button onclick=${increment}>click</button>
        </div>
    </host>`;
}

component.props = {
    count: { type: Number, value: 0 },
};

customElements.define("my-wc", c(component));

<div renderOnce>...</div>: The DOM and its properties will be defined only once.

Atom.symbolId

Atomico internally creates an id for each render, this is stored in the symbolId property of the webcomponent, now Atomico searches if this property has already been defined, giving space for the future for SSR

atomico - fix useLayoutEffect bug when requesting an update

Published by UpperCod over 3 years ago

This bug prevented the loop collector from executing effects callback, example:

useLayoutEffect(() => {
    setState("any..");
, [ anyParam ] ):

useEffect(()=>{
    console.log("Run...")
}, [] ):

the update request of useLayoutEffect when using useState, and mermorize parameters produced the bug, since the default cycle will allow to dispatch updates before the collection of effects is finished.

Now every update is subject to a single task queue of each webcomponent.

atomico - fix package.json#exports for /test-dom

Published by UpperCod over 3 years ago

atomico - add atomico/test-dom with fixture

Published by UpperCod over 3 years ago

atomico/test-dom

fixture

Create a div that fills with the virtual-dom and then inject it into the document, fixture is persistent between tests so each execution within the test recycles the host, allowing to evaluate the update cycles correctly.

Example

import { html } from "atomico";
import { fixture } from "atomico/test-dom";
import { expect } from "@esm-bundle/chai";
 
describe("test DOM", ()=>{
     it("example",()=>{
         const img = fixture(html`<img src="./image"/>`);
         expect(img.src).to.equal("./image");
     })
})
atomico - Update the main readme

Published by UpperCod over 3 years ago

atomico - fix circular dependency

Published by UpperCod over 3 years ago

atomico - fix inheritance of styles when using vanilla classes

Published by UpperCod over 3 years ago

atomico - fix prototype manipulation bug

Published by UpperCod over 3 years ago

This fixes previous versions 1.21

atomico - fix update on new instances in typescript

Published by UpperCod over 3 years ago

atomico - new update behavior and migration to @web/test-runner

Published by UpperCod over 3 years ago

update

Now update allows updating and creating properties manually, this to achieve an integration outside Atomico with webcomponents that dispatch updates through the update method, example:

import { c } from "atomico";

class ConsumeContext extends HTMLElement {
  connectedCallback() {
    this.dispatchEvent(
      new CustomEvent("ConsumeContext", {
        detail: (context) => this.update({ context }),
      })
    );
  }
  update() {}
}

function component({ context }) {
  console.log(context);
  return <host />;
}

customElements.define("my-component", c(component, ConsumeContext));

This approach allows you to use utility classes outside Atomico, consider this valid if you share utilities already created in inheritance format, since if you work only with Atomico the ideal is to use Hooks

atomico - new centralized export and features

Published by UpperCod over 3 years ago

new features

centralized export

import { `
  html, // atomico/html still works but now you can import it from the main module
  css,   // css is for the generation of CSSStyleSheet for the component.styles property,
  ...core
} from "atomico";

this version 1.21.0 breaks with the atomico/ocss model, this version 1.21.0 breaks with the atomic / css model

components.styles

Version 1.21. * Has internal improvements in processing the life cycle of the customElement, now allowing sharing inheritance inside and outside Atomic, this new form of inheritance allows associating a new property for functional components and new techniques ideal for design systems

Why components.styles?

Antes de la version 1.21.* el estilo era manejado por el render, por lo que mantener extensibilidad a un webcomponent dependería directamente del autor. el nuevo formato se inspira en lit para añadir soporte heredable de la propiedad estatica component.style, ejemplo:

before : although this form is not invalid, it prevents your component from modifying its style when extending it. consider this option only if you require dynamic css

function component() {
  return (
    <host shadowDom>
      <style>{`:host{font-size:100px}`}</style>
    </host>
  );
}

1.21.*: The css association is optimized and will only occur synchronously after the first render.

import { css } from "atomico";

function component() {
  return <host shadowDom></host>;
}

components.styles = css`
  :host {
    font-size: 100px;
  }
`;

another improvement is extensibility outside of Atomico

import { css } from "atomico";
import Component from "./component.js";

class MyComponent extends Component {
  static styles = css`
    :host {
      color: red;
    }
  `;
}

You don't need to use super.styles as this happens by default

atomico - Fix the behavior of the prop href, now it is processed as an attribute

Published by UpperCod over 3 years ago

The WITH_ATTR object, defines which prop should be processed as an attribute, now href is in this list, avoiding the href(unknow) generated by the native use ( HTMLAnchorElement | HTMLLinkElement ).href.