UNPKG

8.19 kBMarkdownView Raw
1![Atomico](https://unpkg.com/atomico/docs/brand/logo-black.svg)
2
3[![CircleCI](https://circleci.com/gh/atomicojs/atomico.svg?style=svg)](https://circleci.com/gh/atomicojs/atomico)
4[![npm](https://badgen.net/npm/v/atomico)](http://npmjs.com/atomico)
5[![gzip](https://badgen.net/bundlephobia/minzip/atomico)](https://bundlephobia.com/result?p=atomico)
6
7Atomico is a small 3kb library for creating interfaces based on web-components, hooks, props and virtual-dom.
8
9If you want to try Atomico and you need help tell me in Twitter [Uppercod](https://twitter.com/uppercod)🤓.
10
11[read in Spanish](./docs/README-es.md)
12
131. [Overview](#overview)
142. [Installation](#installation)
153. [Creating a web-component](#creating-a-web-component)
16 1. [Jsx](#jsx)
17 2. [Template string](#template-string)
18 3. [Virtual-dom](#vitual-dom)
194. [Defining a web-component](#defining-a-web-component)
205. [Properties and attributes of the web-component](#properties-and-attributes-of-the-web-component)
21 1. [Props](#props)
22 2. [Types](#tipos)
236. [Hooks](#hooks)
24 1. [Hook guide](./docs/hooks.md)
257. Examples
26 1. [Calculator](https://webcomponents.dev/edit/emmJ9SYBiOJZhlNIYDJk)
27 2. [Watch](https://webcomponents.dev/edit/iOhxFWq5JfiKRJChwb5v)
28
29## Overview
30
31```jsx
32import { h, customElement } from "atomico";
33
34function WebComponent({ value }) {
35 return <host>Hi! {value}!</host>;
36}
37
38WebComponent.props = {
39 value: String
40};
41
42customElement("any-name", WebComponent);
43```
44
45Where:
46
47* `h`: pragma that builds virtual-dom using JSX using a compiler like babel.
48* `customElement`: function that registers the web component in the browser, eg `<any-name></any-name>`.
49* `WebComponent`: function used to represent the state of the web component's DOM.
50* `WebComponent.props`: represents the props that build the properties and attributes that are responsible for communicating the state to the web-component
51
52## Installation
53
54```bash
55npm install atomico
56```
57
58## Creating a web-component
59
60The interface of a web-component is defined in atomico thanks to the virtual-dom declared by using **Jsx**, **Template string** or a **Declarative object**.
61
62#### Jsx
63
64```jsx
65import { h } from "atomico";
66
67function WebComponent() {
68 return (
69 <host>
70 <button onclick={() => console.log("click")}>my web-component</button>
71 </host>
72 );
73}
74```
75
76#### Template string
77
78Thanks to [htm](https://github.com/developit/htm) you can build the virtual-dom using the `html` function, eg:
79
80```js
81import html from "atomico/html";
82
83function MyTag() {
84 return html`
85 <host>
86 <button onclick=${() => console.log("click")}>
87 my web-component
88 </button>
89 </host>
90 `;
91}
92```
93
94#### Virtual dom
95
96**The output** of the previous exercise either using [Jsx](#jsx) or [Template string](#template-string) is equivalent to a **declarative object** known as virtual-dom, eg:
97
98```js
99function MyTag() {
100 return {
101 nodeType: "host",
102 children: {
103 nodeType: "button",
104 onclick() {
105 console.log("click");
106 },
107 children: "my web-component"
108 }
109 };
110}
111```
112
113Atomico allows the manipulation of the web-component through the virtual-dom by declaring the tag `<host />`, eg:
114
115```jsx
116let styleSheet = `
117 :host{
118 display:flex;
119 flex-flow:row wrap;
120 }
121 button{
122 border:none;
123 }
124`;
125
126function MyTag() {
127 return (
128 <host
129 shadowDom
130 styleSheet={styleSheet}
131 onclick={() => console.log("click!")}
132 >
133 inside web-component
134 <button>1</button>
135 <button>2</button>
136 <button>3</button>
137 </host>
138 );
139}
140```
141
142The use of the shadowDom must be declared as part of the virtual-dom.
143
144## Defining a web-component
145
146```jsx
147import { h, customElement } from "atomico";
148
149function MyCustomButton() {
150 return (
151 <host>
152 <button>🤓 my custom button</button>
153 </host>
154 );
155}
156
157customElement("my-custom-button", MyCustomButton);
158```
159
160Where :
161
162* `h`: pragma that generates the virtual-dom, for the jsx compiler
163* `customElement`: function that registers the web-component in the browser, this transforms the function to a class that extends HTMLElement
164
165Alternatively you can export the class to later define the name of your web-component, eg:
166
167```js
168let HTMLWebComponent = customElement(WebComponent);
169
170customElements.define("my-custom-name", HTMLWebComponent);
171```
172
173Where :
174
175* `HTMLWebComponent`: WebComponent function that already extended the HTMLElement, making it a valid constructor to be declared by `customElements.define`
176
177## Properties and attributes of the web-component
178
179The web-component reaction to external states, previously defined and accessible as properties or attributes, eg:
180
181```html
182<!--case attributo-->
183<web-component my-field="./my-source">
184 <!--case property-->
185 <script>
186 document.querySelector("web-component").myField = "./my-source";
187 </script>
188</web-component>
189```
190
191The 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:
192
193```jsx
194function WebComponent({ myField }) {
195 return (
196 <host>
197 <h1>{myField}</h1>
198 </host>
199 );
200}
201
202WebComponent.props = {
203 myField: {
204 type: String,
205 value: "hi!"
206 }
207};
208```
209
210### Props
211
212Props can be simple to complex configurations, eg
213
214**Just declaring the type**
215
216```jsx
217WebComponent.props = {
218 fieldObject: Object
219};
220```
221
222**Type statement and additional behavior**
223
224```jsx
225WebComponent.props = {
226 fieldObject: {
227 type: Object,
228 reflect: true,
229 event: true,
230 get value() {
231 return { ...initialObject };
232 }
233 }
234};
235```
236
237Where :
238
239* `fieldObject.type`: defines the type of data to be supported by the property or attribute.
240* `fieldObject.reflect`:it allows to reflect the state in the web-component as an attribute.
241* `fieldObject.event`: allows dispatching a custom event in each change associated with the property.
242* `fieldObject.value`:It is the value that the property will take by default when initializing.
243
244#### Property types
245
246These are declared by the index `type`.
247
248| Type | Description |
249| ------- | -------------------------------------------------------------------------------------------------------- |
250| String | the type of prop must be a String |
251| Number | the type of prop must be a Number |
252| Boolean | the type of prop must be a Boolean, it is considered valid Boolean `[1, 0,"true","false", true, false]`. |
253| Object | the type of prop must be a Object, if it is a string, apply JSON.parse for a type analysis |
254| Array | the type of prop must be a Array, if it is a string, apply JSON.parse for a type analysis |
255| Date | the type of prop must be a Date, if a string applies `new Date` for a type analysis |
256
257> 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>]`
258
259## Hooks
260
261The 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 .
262
263In 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](./docs/hooks.md)