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 |
|
7 | Atomico is a small 3kb library for creating interfaces based on web-components, hooks, props and virtual-dom.
|
8 |
|
9 | If 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 |
|
13 | 1. [Overview](#overview)
|
14 | 2. [Installation](#installation)
|
15 | 3. [Creating a web-component](#creating-a-web-component)
|
16 | 1. [Jsx](#jsx)
|
17 | 2. [Template string](#template-string)
|
18 | 3. [Virtual-dom](#vitual-dom)
|
19 | 4. [Defining a web-component](#defining-a-web-component)
|
20 | 5. [Properties and attributes of the web-component](#properties-and-attributes-of-the-web-component)
|
21 | 1. [Props](#props)
|
22 | 2. [Types](#tipos)
|
23 | 6. [Hooks](#hooks)
|
24 | 1. [Hook guide](./docs/hooks.md)
|
25 | 7. Examples
|
26 | 1. [Calculator](https://webcomponents.dev/edit/emmJ9SYBiOJZhlNIYDJk)
|
27 | 2. [Watch](https://webcomponents.dev/edit/iOhxFWq5JfiKRJChwb5v)
|
28 |
|
29 | ## Overview
|
30 |
|
31 | ```jsx
|
32 | import { h, customElement } from "atomico";
|
33 |
|
34 | function WebComponent({ value }) {
|
35 | return <host>Hi! {value}!</host>;
|
36 | }
|
37 |
|
38 | WebComponent.props = {
|
39 | value: String
|
40 | };
|
41 |
|
42 | customElement("any-name", WebComponent);
|
43 | ```
|
44 |
|
45 | Where:
|
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
|
55 | npm install atomico
|
56 | ```
|
57 |
|
58 | ## Creating a web-component
|
59 |
|
60 | The 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
|
65 | import { h } from "atomico";
|
66 |
|
67 | function 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 |
|
78 | Thanks to [htm](https://github.com/developit/htm) you can build the virtual-dom using the `html` function, eg:
|
79 |
|
80 | ```js
|
81 | import html from "atomico/html";
|
82 |
|
83 | function 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
|
99 | function 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 |
|
113 | Atomico allows the manipulation of the web-component through the virtual-dom by declaring the tag `<host />`, eg:
|
114 |
|
115 | ```jsx
|
116 | let styleSheet = `
|
117 | :host{
|
118 | display:flex;
|
119 | flex-flow:row wrap;
|
120 | }
|
121 | button{
|
122 | border:none;
|
123 | }
|
124 | `;
|
125 |
|
126 | function 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 |
|
142 | The use of the shadowDom must be declared as part of the virtual-dom.
|
143 |
|
144 | ## Defining a web-component
|
145 |
|
146 | ```jsx
|
147 | import { h, customElement } from "atomico";
|
148 |
|
149 | function MyCustomButton() {
|
150 | return (
|
151 | <host>
|
152 | <button>🤓 my custom button</button>
|
153 | </host>
|
154 | );
|
155 | }
|
156 |
|
157 | customElement("my-custom-button", MyCustomButton);
|
158 | ```
|
159 |
|
160 | Where :
|
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 |
|
165 | Alternatively you can export the class to later define the name of your web-component, eg:
|
166 |
|
167 | ```js
|
168 | let HTMLWebComponent = customElement(WebComponent);
|
169 |
|
170 | customElements.define("my-custom-name", HTMLWebComponent);
|
171 | ```
|
172 |
|
173 | Where :
|
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 |
|
179 | The 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 |
|
191 | The 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
|
194 | function WebComponent({ myField }) {
|
195 | return (
|
196 | <host>
|
197 | <h1>{myField}</h1>
|
198 | </host>
|
199 | );
|
200 | }
|
201 |
|
202 | WebComponent.props = {
|
203 | myField: {
|
204 | type: String,
|
205 | value: "hi!"
|
206 | }
|
207 | };
|
208 | ```
|
209 |
|
210 | ### Props
|
211 |
|
212 | Props can be simple to complex configurations, eg
|
213 |
|
214 | **Just declaring the type**
|
215 |
|
216 | ```jsx
|
217 | WebComponent.props = {
|
218 | fieldObject: Object
|
219 | };
|
220 | ```
|
221 |
|
222 | **Type statement and additional behavior**
|
223 |
|
224 | ```jsx
|
225 | WebComponent.props = {
|
226 | fieldObject: {
|
227 | type: Object,
|
228 | reflect: true,
|
229 | event: true,
|
230 | get value() {
|
231 | return { ...initialObject };
|
232 | }
|
233 | }
|
234 | };
|
235 | ```
|
236 |
|
237 | Where :
|
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 |
|
246 | These 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 |
|
261 | The 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 |
|
263 | In 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)
|