UNPKG

5.93 kBMarkdownView Raw
1Composi
2=======
3
4Contents
5--------
6- [Components](./components.md)
7- [JSX](./jsx.md)
8- Hyperx
9- [Hyperscript](./hyperscript.md)
10- [Mount and Render](./render.md)
11- [State](./state.md)
12- [Lifecycle Methods](./lifecycle.md)
13- [Events](./events.md)
14- [Styles](./styles.md)
15- [Unmount](./unmount.md)
16- [Installation](../README.md)
17- [Third Party Libraries](./third-party.md)
18- [Functional Components](./functional-components.md)
19- [Deployment](./deployment.md)
20
21Hyperx
22------
23
24If you do not like JSX, you can instead use Hyperx. This lets you define your component markup with ES6 template literals. At build time, Hyperx converts the template literals into hyperscript functions that Composi's virtual dom can understand.
25
26Installation
27------------
28
29First you will need to install Hyperx in your project. Open your terminal and run:
30
31```sh
32npm i -D hyperx
33```
34
35Then open your project's `gulpfile.js`. Scroll down to the `build` task and look for `commonjs(),`. Update it to the following:
36
37```javascript
38commonjs({
39 include: 'node_modules/**'
40}),
41```
42
43You will need to update this by adding in a new line: `ignoreGlobal: true`. This will enable Rollup to import Hyperx like a noraml ES6 module:
44
45```javascript
46commonjs({
47 include: 'node_modules/**',
48 ignoreGlobal: true
49}),
50```
51
52Importing Hyperx for Use
53------------------------
54Next you'll need to import Hyperx into any file where you want to use it. That means any file in which you are importing Composi's `Component` class, you'll want to also import Hyperx. Besides importing it, you'll also need to let Hyperx know that it should use Composi's `h` function when it converts template literals into functions. You do that by importing the `h` function and passing it to Hyperx:
55
56```javascript
57import {h, Component} from 'composi'
58import {hyperx} from 'hyperx'
59
60// Tell Hyperx to use the Composi h function:
61const html = hyperx(h)
62```
63
64We can now use the `html` function to define template literals as markup for Composi components. If you have not used template literals before, you might want to read up on [how they work](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals).
65
66Using Template Literals
67-----------------------
68You can use template literals just as you normally would. Whereas JSX uses `{someVariable}` to evaluate variables, template literals use `${someVariable}`. Notice how we capture Hyperx as a tagged template literal function `html`, which we then use to define markup:
69
70```javascript
71import {h, Component} from 'composi'
72import {hyperx} from 'hyperx'
73const html = hyperx(h)
74
75// Use class attribute as normal:
76function header(data) {
77 return html`
78 <header>
79 <h1 class='title'>${data.title}</h1>
80 <h2 class='subtitle'>${data.subtitle}</h2>
81 </header>
82 `
83}
84```
85
86
87### Partial Attributes
88
89Unlike JSX, Hyperx does support partial attribute values. The following code will work without a problem:
90
91```javascript
92import {h, Component} from 'composi'
93import {hyperx} from 'hyperx'
94const html = hyperx(h)
95
96function userList(users) {
97 return html`
98 <ul>
99 {
100 users.map(user => <li class='currently-${user.employed ? "employed" : "unemployed"}'>${user.name}</li>)
101 }
102 </ul>
103 `
104}
105```
106
107Hyperx with Components
108----------------------
109
110We can use Hyperx directly inside a Component as part of the `render` function. Notice that when we need to loop over the arrray of items, we use `html` to define the list item. If we instad made that part a template literal, the markup would be returned as an escaped string. Of course, if that is what you want, that is how you would do it.
111
112```javascript
113const fruitsList = new Component({
114 container: '#fruit-list',
115 state: fruits,
116 render: (fruits) => html`
117 <ul class='list'>
118 ${
119 fruits.map(fruit =>
120 html`<li>
121 <div>
122 <h3>{fruit.title}</h3>
123 <h4>{fruit.subtitle}</h4>
124 </div>
125 <aside>
126 <span class='disclosure'></span>
127 </aside>
128 </li>`
129 )
130 }
131 </ul>
132 `
133})
134```
135
136Custom Tags
137-----------
138JSX has the concept of custom tags that allow you to break up complex markup into smaller, reusable pieces. You can accomplish the same thing with Hyperx. Define the functions that return the markup and then use them inside the parent render function as methods inside dollar sign curly braces:
139
140```javascript
141function listItem(fruit) {
142 return html`
143 <div>
144 <h3>${fruit.name}</h3>
145 <h4>${fruit.price}</h4>
146 </div>`
147}
148
149// Function to return static markup:
150function disclosure() {
151 return html`
152 <aside>
153 <span class='disclosure'></span>
154 </aside>`
155}
156
157//Now that we have some custom tags, we can use them as follows:
158
159const fruitsList = new Component({
160 container: '#fruit-list',
161 state: fruits,
162 render: (fruits) => html`
163 <ul class='list'>
164 {
165 fruits.map(fruit => (
166 <li>
167 ${listItem(fruit)}
168 ${disclosure()}
169 </li>
170 )
171 }
172 </ul>
173 `
174})
175```
176
177About Sibling Tags
178------------------
179Like JSX, you markup must always have one enclosing tag. Although it is legal to return a set of sibling elements in an ES6 template literal, this will not work with Composi's `h` function. That's because each tag you define will be converted into a function. As such, there needs to be one final, top-most function that returns the markup.
180
181Bad markup:
182
183```javascript
184const badHyperx = new Component({
185 container: '#list',
186 render: () => html`
187 <li>One</li>
188 <li>Two</li>
189 <li>Three</li>
190 `
191})
192```
193
194The above code will not build. Instead you need to create the entire list like this and insert it in some higher element as the container:
195
196```javascript
197const goodHyperx = new Component({
198 container: '#listDiv',
199 render: () => html`
200 <ul>
201 <li>One</li>
202 <li>Two</li>
203 <li>Three</li>
204 </ul>
205 `
206})
207```
208