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 - Fix error ts(2589)

Published by UpperCod over 2 years ago

Fix circular reference bug( ts:2598 ) associated with type Component, when using it for type autocompletion.

atomico - Improve JS compression

Published by UpperCod over 2 years ago

  1. Removed use of const within core
  2. create-hooks code has been optimized
atomico - add callable ref and improve test-dom

Published by UpperCod over 2 years ago

callable ref

now the ref property accepts a callback that will receive the associated node instance as a parameter, example:

<button ref={(node)=>{
      console.log(node)
}}></button>

The purpose of this improvement

  1. Allow to create lists by exploring the references, this is ideal for test.
  2. Manipulate the DOM directly, atomico updates the dom based on comparisons as immutable and this blocks updates if the value between vnodes is equal, through callable ref you can apply direct updates on the DOM, skipping Atomico's diff optimization.

Considerations

  1. The callback will be executed every time it changes..
  2. The calllback is not used to clean effects like in React, for this use useEffect for these cases

Typescript support.

The node received by ref associates the type of the assigned node, so if Atomico is used, the interactions at the prop level will be strict and will be validated by typescript, allowing errors to be detected.

<button ref={(node)=>{
      console.log(node)
}}></button>

atomico/test-dom

fixture

Now fixture can return more than one node depending on the rendering case.

describe("fixture", () => {
  it("list", () => {
        const list = [];
        const children = fixture(html`
            <button ref=${(node) => list.push(node)}>button</button>
            <button ref=${(node) => list.push(node)}>button</button>
            <button ref=${(node) => list.push(node)}>button</button>
        `);
        expect(children).to.deep.equal(list);
    });
});
atomico - Fix types for render and h, when using null

Published by UpperCod over 2 years ago

atomico - Filtering of Types for properties has been improved.

Published by UpperCod over 2 years ago

This is an internal improvement, the algorithm that filters values based on types has been improved, now these cases are validated correctly:

new Number(NaN);  // if the input is of type number this will throw an error.
document.createElement("div");  // if the input is of type Element this is valid

This enhancement now allows per-instance validation

atomico - fix html function type

Published by UpperCod over 2 years ago

The html return is now any, to define a return type you should use the type parameter, example:

html<VNode<"host">>`<host></host>`

This is not required and is only useful when customizing the return.

atomico - Improved type detection

Published by UpperCod over 2 years ago

This improvement is at the type level for Typescript:

  1. Improve the strict validation of a webcomponent created with Atomico.
  2. Allows the use of all native browser constructors (+500), for example File, Date, RegExp and others.

browser native constructors: All Constructors other than String, Boolean, Number, Promise, Symbol, Object and Array. Native constructors cannot be mirrored and are only used through the use of properties.

Example:

function component(props: Props<typeof component>) {
  return (
    <host>
      <span>{props?.file?.type}</span>
      <span>{props?.pattern?.test("check!") ? "Yes" : "NO"}</span>
    </host>
  );
}

component.props = {
  file: File,
  pattern: RegExp,
};
atomico - New type-level behavior for function h

Published by UpperCod over 2 years ago

Now the function h infers the types of the props according to the first parameter type.

<host>
  {h("img", {
    src: "image",
    onclick() {},
  })}
</host>

This allows validating the props according to the associated tag as the type of the pragma, it also applies to CustomElement, but in case the type assigned to the HTMLElement is not inferred, example:

class E extends HTMLElement {
  myProp: number = 10;
}

<host>
  {h(E, {
    onclick({ currentTarget }) {
      currentTarget.myProp; // ✅
    },
  })}
</host>;

This feature helps instances through Elements or Custom Elements not created with Atomico to infer the types to be defined.

atomico - Add optional second parameter for type Props

Published by UpperCod over 2 years ago

When using the null declaration to define a prop as Any, the input type is not defined, through the second parameter you can replace the inferred type with props.

type myProps =  Props<typeof component, { myPropAny: Promise<any> | number }>

the above declaration allows you to replace the inferred prop myPropAny with one of type Promise<any> | number, this helps improve error detection when using Typescript.

atomico - Fix using native attributes for Typescript

Published by UpperCod almost 3 years ago

Example:

myComponent.props = {id: String}

Declarations targeting reactivity on native DOM attributes are now valid against Typescript, allowing CustomElement registration over customElement.defined.

atomico - Fix types for useHost and Ref

Published by UpperCod almost 3 years ago

useHost: Current is always defined for Typescript.
Ref: current is always Any unless specified.

atomico - Simplifies the use of the Props type and add Meta type

Published by UpperCod almost 3 years ago

Simplifies the use of the Props

Props now supports function typeof as webcomponent without the need to point to props

// Before
Props<typeof myComponent.props>;

// After
Props<typeof myComponent>;

Example

import { Props } from "atomico";

function component({ value }: Props<typeof component>) {
  return <host shadowDom>{value}</host>;
}

component.props = {
  value: String,
};

Add Meta type

Meta aims to add meta-types to the component instance, for now the support allows only the use of Events.

Example

import { Meta, DOMEvent } from "atomico";

function component(): Meta<DOMEvent<"MyEvent">> {
  return <host shadowDom>{value}</host>;
}

component.props = {
  value: String,
};
atomico - Fix inferring types when using Component with boolean and null values

Published by UpperCod almost 3 years ago

Error only when using TSX with the new type Component, this version corrects the structure rules of the props when interpreting null and boolean type values.

atomico - Fix this by inferring the event for webcomponents

Published by UpperCod almost 3 years ago

atomico - Fix types for TSX

Published by UpperCod almost 3 years ago

Fix use of null

<img  onload={null}/>

defining null before a property will not throw an error when using JSX.

Fix access to currentTarget

<img  onload={(event)=>{
    event.currentTarget.src // ✅
}}/>

Every native HTML or SVG tag correctly accesses its currentTarget when defining the event from JSX, this will happen in the same way with the instance of the CustomElement within the JSX.

<MyComponent  onMyCustomEvent={(event)=>{
    event.currentTarget.myProp // ✅
}}/>

Fix Atomico inheritance

fix Atomico inheritance when extending a class to modify style

import { css } from "atomico";
import { MyComponent } from "./my-component";

class NewComponent extends MyComponent{
    get styles(){
       return [
              super.styles,
              css`:host{ --color: red;}`
       ]
    }
}
atomico - Add functionality to retrieve events with DOMEvent

Published by UpperCod almost 3 years ago

The objective of this functionality is to be able to build the parameter of an exclusive customEvent of a webcomponent, example:

import { DOMEvent } from "atomico";
import { MyComponent } from "./my-component";

export function handlerCustomEventShow (event: DOMEvent<"Show", typeof MyComponent>){
    console.log(event.currentTarget.show)
}

type DOMEvent<"Show", typeof MyComponent> extracts the Show event from the customElement MyComponent.

atomico - New functionality for the DOMEvent type

Published by UpperCod almost 3 years ago

This improved feature is oriented to environments based on Types and JSX, now Atomico allows you to declare Events to be shared through JSX, example:

import { Component, DOMEvent, c } from "atomico";

const props = {
  myProp: String,
};

type Events = DOMEvent<"MyCustomEvent", CustomEvent<{ id: string }>>;

const myComponent: Component<typeof props & Events> = ({ myProp }) => {
  return (
    <host>
      <h1>{myProp}</h1>
    </host>
  );
};

myComponent.props = props;

export const MyComponent = c(myComponent);

Thanks to this declaration DOMEvent<"MyCustomEvent", CustomEvent<{ id: string }>> we are creating an event to listen to from JSX, example:

<MyComponent
  onMyCustomEvent={(event) => {
    event.currentTarget.myProp; // ✅
    event.detail.id; // ✅
  }}
></MyComponent>;

This greatly improves the association of events, since now Typescript will encounter errors if an event of its webcomponent is not valid in declaration.

atomico - Type improvement for TS

Published by UpperCod almost 3 years ago

the changes in this version only affect JSX and TSX

Improvement in the props for JSX

Methods and properties inaccessible from JSX are eliminated, example appendChild, this improves the autocompletion since it reduces the list of recommendations.

Elimination of types

DOMCustomEvent: Now DOMEvent allows creating a custom event from a CustomEvent, example:

DOMEvent<HTMLElement, CustomEvent<{myData:any}>>

The types are renamed for better consistency when generating static types

  1. AtomBase renamed to AtomicoThis
  2. Atom renamed to Atomico
atomico - Fix type for ts slot

Published by UpperCod almost 3 years ago

Atomic allows props to declare the slot property, example

myComponent.props = {slot: { type: String, value: "my-slot" }};

In order to observe the slot and define a default one, although before using Typescript it did not generate type errors, after the last Typescript updates this began to generate a type error.

this version fixes it, allowing type-level behavior.

atomico - add template

Published by UpperCod almost 3 years ago

template

Core function that allows rendering html content within a template tag, example:

import { template } from "atomico";

const node = template(<div>i am template!</div>);

The objective of this is to enhance the use of the new cloneNode property, example:

import { template, useRef } from "atomico";
import { useSlot } from "@atomico/hooks/use-slot";

const DefaultContent = template(<div>i am template!</div>);

function component() {
  const ref = useRef();
  const [Content = DefaultContent] = useSlot();

  return (
    <host>
      <slot name="template" ref={ref} style="display:none" />
      <Content cloneNode />
      <Content cloneNode />
      <Content cloneNode />
      <Content cloneNode />
    </host>
  );
}

As you will notice, Content looks for the existence of the [template] slot, but when not finding it replaces it with DefaultContent, thanks to this feature you will be able to have nodes within your webcomponents that can be consumed as templates for your logic.