Only this pageAll pages
Powered by GitBook
Couldn't generate the PDF for 142 pages, generation stopped at 100.
Extend with 50 more pages.
1 of 100

English

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

API

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Guides

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

packages

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Getting started with Atomico for React users

Hi, I'm Atomico js and I bring you the React syntax for webcomponents, I think you and I get along very well 😊.

First let's say that Atomico is light since it has a size close to 3kB vs React + ReactDOM that have a size close to 60kB, now if your project is already written in React I can integrate Atomico progressively since a component created can be instantiated as a component for React thanks to @atomico/react, example:

import { Button } from "@formas/button/react";

function App(){
   return <>
      <h1>React App!</h1>
      <Button onClick={()=>console.log("Click!")}>
         Submit
      </Button>
   </>
}

Magical 🪄, isn't it?... well now let's speed up your Atomico learning path:

How to declare a component?

Atomico, like React, allows a declaration of components using only functions, example:

import { useState } from "
import { c, useProp } 

From the example we will highlight the following differences:

  1. In Atomico you only use one import.

  2. useProp is like useState, but with the difference that useProp references the state from the webcomponent property defined in counter.props.

  3. const props allows us to create the properties of our webcomponent, these are like React's propTypes, but with a big difference they are associated with the instance and can be read and modified by referencing the node, example document.querySelector("my-counter").count = 10;

  4. ReactDom.render needs a reference to mount the component, in Atomico you only need to create the my-counter tag to create a new instance of the component.

  5. The <host/> tag is similar to <> </> for React, but <host/> represents the webcomponent instance and every component created with Atomico must return the host tag

  6. This is only readability, but in Atomico by convention we do not use capital letters when naming our component, these are only used when creating the customElement as in line 16, since Counter is instantiable.

Now I want to invite you to learn how to declare a style using Atomico.

It is common to see the use of libraries such as Emotion or styled-components to encapsulate styles in React, but these add an additional cost, be it for performance or bundle, in Atomico there is no such cost.

It is normal for React to create components that you then instantiate within other components, for example:

with Atomico there are certain differences:

The constructor in Atomic is the product of the c function and is the one you will use to register your webcomponent, example:

According to the previous example, you can instantiate MyComponent as a JSX Component, example:

This instance type allows autocompletion at the JSX level and type validation at the Typescript level.

This will be useful for reusing templates, but always remember stateless.

use-slot

Retrieves the nodes assigned to a slot.

What can you do with Atomico?

With Atomico you can do this and more

You can create amazing webcomponentsYou can create design systemsYou can create web applicationsYou can create mobile applicationsYou can create websites
react
"
;
import ReactDOM from 'react-dom'
function Counter({initialCount}) {
const [count, setCount] = useState(initialCount);
return (
<>
Count: {count}
<button onClick={() => setCount(initialCount)}>Reset</button>
<button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
<button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
</>
);
}
render(
<Counter initialCount={1}/>,
document.querySelector("#counter")
);
from
"
atomico
"
;
const props = { count: { type: Number, value: 0 } };
const Counter = c(
() => {
const [count, setCount] = useProp("count");
return (
<host>
Count: {count}
<button onClick={() => setCount((prevCount) => prevCount - 1)}>-</button>
<button onClick={() => setCount((prevCount) => prevCount + 1)}>+</button>
</host>
);
},
{ props }
);
customElements.define("my-counter", Counter);

How do you declare styles using Atomico?

Instances, children and slots

1. With Atomico you can instantiate CustomElements using its constructor

2. With Atomico you can instantiate components as functions as long as these are only stateless functions

From React to Atomico
VirtualDOM api differences
const Button = styled.a`
  /* This renders the buttons above... Edit me! */
  display: inline-block;
  border-radius: 3px;
  padding: 0.5rem 0;
  margin: 0.5rem 1rem;
  width: 11rem;
  background: transparent;
  color: white;
  border: 2px solid white;

  /* The GitHub button is a primary button
   * edit this to target it specifically! */
  ${props => props.primary && css`
    background: white;
    color: black;
  `}
`

render(
  <div>
    <Button
      href="https://github.com/styled-components/styled-components"
      target="_blank"
      rel="noopener"
      primary
    >
      GitHub
    </Button>

    <Button as={Link} href="/docs">
      Documentation
    </Button>
  </div>
)
import { c, css } from "atomico";

const props = { primary: { type: Boolean, relfect: true } };

const styles = css`
  :host {
    display: inline-block;
    border-radius: 3px;
    padding: 0.5rem 0;
    margin: 0.5rem 1rem;
    width: 11rem;
    background: transparent;
    color: white;
    border: 2px solid white;
  }

  :host([primary]) {
    background: white;
    color: black;
  }
`;

export const Button = c(
  () => (
    <host shadowDom>
      <slot />
    </host>
  ),
  { props, styles }
);

customElements.define("my-button", Button);

function Child({children}){
    return <span>children</span>
}

function Main(){
    return <>
        <Child>text 1...</Child>
        <Child>text 2...</Child>
    </>
}
my-component.tsx
import { c } from "atomico";

export const MyComponent = c(() => <host>...</host>); // Constructor

customElements.define("my-component", MyComponent);
import { c } from "atomico";
import { MyComponent } from "./my-component";

export const MyApp = c(() => (
  <host>
    <MyComponent />
  </host>
));

customElements.define("my-app", MyApp);
function MyIcon({ size }) {
  return (
    <svg height={size} width={size}>
      <circle r="45" cx="50" cy="50" fill="red" />
    </svg>
  );
}

const MyComponent = c(() => (
  <host>
    Small <MyIcon size={"1rem"} />
    Large <MyIcon size={"2rem"} />
  </host>
));

use-parent

Retrieve a node higher than the current webcomponent.

Module

import { useParent, useParentPath } from "@atomico/hooks/use-parent";

Syntax useParent

const selector = "form";
const parent = useParent(selector);

Where:

  • selector: String, Selector to be used by Element.matches when searching for the parent.

  • parent: Element, ascending search result according to selector.

Where:

  • parents: parent nodes of the webcomponent

  • composed: bypasses shadow DOM in parent capture.

useSlot

Module

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

Syntax

const optionalFilter = (element)=> element instanceof MyCustomElement;
const childNodes = useSlot(ref, optionalFilter);

Where:

  1. ref: Reference of the slot to observe.

  2. childNodes: List of nodes assigned to the observed slot.

  3. optionalFilter: allows to filter nodes assign to childNodes

use-resize-observer

Observe the size change of a reference.

Module

import {
  useResizeObserver,
  useResizeObserverState,
} from "@atomico/hooks/use-resize-observer";

Syntax

useResizeObserver

useResizeObserver(
  ref,
  (rect) => void
);

Where:

  • ref: Ref, reference to observe the resizing.

  • rect: Object, the return of DOMRectReadOnly.toJSON(), documentation of

    • width

    • height

    • x

    • y

Where:

  • ref: Ref, reference to observe the resizing.

  • rect: Object, the return of DOMRectReadOnly.toJSON(), documentation of

useProxySlot

useProxySlot allows you to observe the nodes assigned to a slot and reassign them to another slot dynamically, example:

Input: Suppose we have a component that observe the slot[name="slide"] node

<my-component>
    <img slot="slide" src="slide-1"/>
    <img slot="slide" src="slide-1"/>
    <img slot="slide" src="slide-1"/>
</my-component>

output: thanks to useProxySlot you will be able to modify the assignment of the list nodes without losing the nodes in the process as normally happens with useSlot, example:

<my-component>
    <img slot="slide-1" src="slide-1"/>
    <img slot="slide-2" src="slide-1"/>
    <img slot="slide-3" src="slide-1"/>
</my-component>

Syntax and example

import { useRef } from "atomico";
import { useProxySlot } from "@atomico/hooks/use-slot";

function component() {
  const ref = useRef();
  const children = useProxySlot(ref);

  return (
    <host shadowDom>
      <slot name="slide" ref={ref} />
      {children.map((child, index) => (
        <slot name={(child.slot = "slide-" + index)} />
      ))}
    </host>
  );
}

All redirected hooks must exist under a slot

Live example

You can create amazing webcomponents

Atomico makes it easy to build components with less code, better readability, and better reusability.

We invite you to discover part of the development experience you will get with Atomico:

Create really fast webcomponents

Quick components to write since with Atomico you will require fewer lines of code to declare your webcomponents which will help you to be more productive

Fast in performance, since Atomico sends less code to the client, making your interface load quickly

Create web components with less code

This is thanks to a functional orientation inherited from React hooks plus some internal optimization from Atomic that ease the process of shaking the tree at compile time, achieving in this way sending the client a highly optimized JS that only has what you really use

Create webcomponents with a functional orientation

This is thanks to Atomico's reliance on React hooks syntax plus the ability to completely eliminate the need for this when using webcomponents.

Create friendly webcomponents for React, Vue and other libraries

Atomic offers additional coverage for native behavior for React and Vue, allowing your component to be more embed-friendly, example React:

Getting started with Atomico

This guide will know the essentials to start developing webcomponents with Atomico

Thanks for being here and getting started with Atomico. Let's talk a little about what Atomico offers today:

  1. Development agility, Atomico's functional approach simplifies code at all stages of development.

  2. Lightweight inside and out, Atomico allows you to create a component with less code and with a low dependency impact. Approximately 3kb.

  3. Really fast, Atomico has a in the browser and an agile development experience. Let's understand what a webcomponent created with Atomico looks like:

Let's analyze the code in parts ...

What have we imported?

  1. c: Function that transforms the functional component into a standard customElement.

  2. css: Function that allows creating the CSSStyleSheet (CSS) for our component as long as it declares the shadowDom.

Our function receives all the props (Properties and Attributes) declared in props, the component function declares all the logic and template of the webcomponent. An important rule within Atomico is "📌 every component created with Atomico must always return the tag".

Atomico detects the prop (Properties and Attributes) of the component thanks to the association of the props object, this through the use of index and value allows you to define:

  1. index: Name of the property and attribute.

  2. value: type of the prop.

From the example we can infer that Atomico will create in our webcomponent a property and attribute called message and this can only receive values of the String type.

Atomico detects the static styles of your component thanks to the association of the styles property:

styles accepts individual or list CSSStyleSheet (CSS) values, the return from the css function is a standard CSSStyleSheet, so it can be shared outside of Atomico.

To create our standard customElement we will have to deliver our functional component to the c function of the Atomico module, the c function will generate as a return a customElement that can be defined or extended.

You can create web applications

working on this documentation...

You can create mobile applications

working on this documentation...

1.0 Imports

2.0 Creating Our Web Component: Custom Element Definition

2.1 Defining Component Render Function

2.2 Defining Component Properties(props) and Attributes

2.3 Defining Encapsulated Styles for the Component

Web Component Registration and Definition

Example

good performance
https://play.atomicojs.dev/
react-app.tsx
import { Button } from "@formas/button/react";

function App(){
   return <>
      <h1>React App!</h1>
      <Button onClick={()=>console.log("Click!")}>
         Submit
      </Button>
   </>
}
MyComponent.jsx
// Imports
import { c, css } from "atomico";

// Creating Our Web Component: Custom Element Definition
export const MyComponent = c(
  // Defining Component Render Function
  ({ message }) => {
    return <host shadowDom>{message}</host>;
  },
  {
    // Defining Component Properties(props) and Attributes
    props: {
      message: String,
    },
    // Defining Encapsulated Styles for the Component
    styles: css`
      :host {
        font-size: 30px;
      }
    `,
  }
);

// Web Component Registration and Definition
customElements.define("my-component", c(component));
MyComponent.jsx - Line: 1
import { c, css } from "atomico";
MyComponent.jsx - Line: 7 to 9
// Defining Component Render Function
({ message }) => {
    return <host shadowDom>{message}</host>;
}
MyComponent.jsx - Line: 12 to 14
// Defining Component Properties(props) and Attributes
props: {
  message: String,
},
MyComponent.jsx - Line: 16 to 19
// Defining Encapsulated Styles for the Component
styles: css`
  :host {
    font-size: 30px;
  }
`,
MyComponent.jsx - Line: 25
// Web Component Registration and Definition
customElements.define("my-component", c(component));

top

  • right

  • bottom

  • left

  • width

  • height

  • x

  • y

  • top

  • right

  • bottom

  • left

  • const rect = useResizeObserverState(ref);

    useResizeObserverState

    Example

    DOMRect
    DOMRect
    const parents = useParentPath(composed?: boolean);

    Syntax useParentPath

    Example

    Live example

    Props(Properties)

    The props in Atomico are the way to associate the webcomponent properties and reactive attributes that trigger the logic or interface of the webcomponent.

    Props is the Atomico recommended way to declare visible and accessible states at the instance level of your webcomponents, with props you can:

    1. Access state via instance, example: document.querySelector("my-component").myStateProp.

    2. Dispatch events on prop value change, example: document.querySelector("my-component").addEventListener("myPropChange",console.log).

    3. Reflect attributes as prop, example: <my-component my-prop="...."> to document.querySelector("my-component").myProp.

    4. define strict input types for props.

    Any function that represents the webcomponent will be able to associate the static object props for the declaration of reactive properties and attributes, for example:

    1. The prop names in Camel Case format will be translated to for use as an attribute to the Kebab Case format, this behavior can be modified through the "attr" property when using a structured declaration.

    2. Structured declarations require the "type" property minimally.

    3. Not all types can use the "reflect" properties.

    4. The declaration of the "value" property can vary depending on the type.

    Simple statements allow setting just type validations.

    Improve the definition by adding utility declarations, allowing for example to reflect the property's value as attributes, automatically emit events or associate default values. Remember these types of declarations minimally require the use of the type property.

    Type
    Supports reflect

    If the "reflect" property is set to true, its value is reflected as an attribute of the webcomponent, this is useful for the declaration of CSS states, example:

    It allows dispatching an automatic event before the prop value change, example:

    Where:

    • event.type: String - optional, name of the event to be emitted when the prop is changed

    • event.bubbles: Boolean - optional, indicates that the event can be listened to by containers.

    • event.detail: Any - optional, allows to attach a custom detail for the event

    The special properties of the event are the well-known Event Init, you can know more details in the .

    Atomico allows the definition of default values of the props.

    The association of callback as value allows generating unique values for each instance of the webcomponent, this is useful with the Object and Array types since it eliminates the references between instances.

    Atomico removes the use of "this" given its functional approach, but adds the hook [useProp] (hooks / useprop.md) which allows to reference a prop for use with a functional syntax, eg:

    Atomico

    A micro library inspired by React Hooks, designed and optimized for the creation of webcomponents.

    import { c } from "
    
    import { c } from "
    

    Atomico simplifies learning, workflow and maintenance when creating webcomponents and achieves it with:

    1. Scalable and reusable interfaces: with Atomico the code is simpler and you can apply practices that facilitate the reuse of your code.

    2. Open communication: with Atomico you can communicate states by events, properties or methods.

    3. Agnostic: your custom Element will work in any web-compatible library, eg React, Vue, Svelte or Angular.

    4. Performance: Atomico has a comparative performance at Svelte levels, winning the third position in performance according to in a comparison of 55 libraries among which is React, Vue, Stencil and Lit.

    You can create design systems

    Today Atomico is used in the development of design systems for various industries such as Banking, Pledge Systems, Insurance, Clinical, Government and more.

    Many teams decide to use Atomico for the development of their design systems thanks to its similarity with React, which greatly facilitates the incorporation of human talent into the development of design systems.

    Why use Atomico to create design systems?

    1. Atomico offers you Storybook 7 Support with superpowers, thanks to @atomico/storybook you can create stories without the need to declare the argTypes or args since @Atomico/storybook creates them for you

    2. @atomico/vite makes it easy for you to build in NPM-friendly ESM format

    3. makes it easy for you to export your code by automatically adding the metadata so that it is optimally consumed as a package, @atomico/exports can even automatically create wrappers for React, Preact and Vue

    4. makes it easy for you to maintain a token system efficiently and sustainably

    We thank IBM IX since they have shared their experience in the development of the design system for their client Barmer, you can follow this case through Discord or Github.

    Value cycle as prop

    Atomico has a really efficient and simple type validation method, the type validation works in the following way:

    Cycle as attribute:

    the given value is transformed to the corresponding type, be it String, Number, Boolean, Array or Object, once transformed it is sent to the cycle as property.

    Cycle as property:

    evaluates if the value is of the declared type:

    • If it corresponds to the type:

      1. It is saved in props.

      2. An event is emitted (if this has been configured in the prop).

      3. It is reflected as an attribute (if this has been configured in the prop).

      4. It is sent to the update queue and subsequent rendering.

    • It does not correspond to the type: an error is created by console with the following data:

      • target: Instance of the webcomponent.

      • value: Input value.