~repos /atoms-element
git clone https://pyrossh.dev/repos/atoms-element.git
A simple web component library for defining your custom elements. It works on both client and server.
318927ea
—
Peter John 4 years ago
v3.0.0
- package-lock.json +2 -2
- package.json +1 -1
- readme.md +25 -89
package-lock.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "atoms-element",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"lockfileVersion": 2,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
|
-
"version": "
|
|
8
|
+
"version": "3.0.0",
|
|
9
9
|
"license": "MIT",
|
|
10
10
|
"devDependencies": {
|
|
11
11
|
"jest": "^27.0.5"
|
package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "atoms-element",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "A simple web component library for defining your custom elements. It works on both client and server. It supports hooks and follows the same principles of react.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pyros.sh",
|
readme.md
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/atoms-element)
|
|
4
4
|

|
|
5
5
|
|
|
6
|
-
A simple web component library for defining your custom elements. It works on both client and server. It follows the same principles of react.
|
|
6
|
+
A simple web component library for defining your custom elements. It works on both client and server. It supports hooks and follows the same principles of react.
|
|
7
|
+
Data props are attributes on the custom element by default so its easier to debug and functions/handlers are attached to the element.
|
|
7
8
|
|
|
8
9
|
I initially started researching if it was possible to server render web components but found out not one framework supported it. I liked using
|
|
9
10
|
[haunted](https://github.com/matthewp/haunted) as it was react-like with hooks but was lost on how to implement server rendering. Libraries like
|
|
@@ -33,102 +34,37 @@ npm i atoms-element
|
|
|
33
34
|
## Example
|
|
34
35
|
|
|
35
36
|
```js
|
|
36
|
-
import { createElement,
|
|
37
|
+
import { createElement, useReducer, html, renderHtml } from 'atoms-element/index.js';
|
|
37
|
-
|
|
38
|
+
|
|
38
|
-
|
|
39
|
-
const name = () => 'app-counter';
|
|
40
|
-
|
|
41
|
-
const
|
|
39
|
+
const Counter = ({ name, meta }) => {
|
|
42
|
-
|
|
40
|
+
const { count, actions } = useReducer({
|
|
43
|
-
|
|
41
|
+
initial: {
|
|
44
|
-
|
|
42
|
+
count: 0,
|
|
45
|
-
|
|
43
|
+
},
|
|
44
|
+
reducer: {
|
|
45
|
+
increment: (state) => ({ ...state, count: state.count + 1 }),
|
|
46
|
+
decrement: (state) => ({ ...state, count: state.count - 1 }),
|
|
47
|
+
},
|
|
46
|
-
});
|
|
48
|
+
});
|
|
47
|
-
|
|
48
|
-
const stateTypes = () => ({
|
|
49
|
-
count: number()
|
|
50
|
-
.required()
|
|
51
|
-
.default((attrs) => attrs.meta?.start || 0),
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
const computedTypes = () => ({
|
|
55
|
-
sum: number()
|
|
56
|
-
.required()
|
|
57
|
-
.compute('count', (count) => {
|
|
58
|
-
return count + 10;
|
|
59
|
-
}),
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
const styles = css({
|
|
63
|
-
title: {
|
|
64
|
-
fontSize: '20px',
|
|
65
|
-
marginBottom: '0.5rem',
|
|
66
|
-
textAlign: 'center',
|
|
67
|
-
},
|
|
68
|
-
span: {
|
|
69
|
-
fontSize: '16px',
|
|
70
|
-
},
|
|
71
|
-
container: {
|
|
72
|
-
display: 'flex',
|
|
73
|
-
flex: 1,
|
|
74
|
-
flexDirection: 'row',
|
|
75
|
-
fontSize: '32px',
|
|
76
|
-
color: 'rgba(55, 65, 81, 1)',
|
|
77
|
-
},
|
|
78
|
-
mx: {
|
|
79
|
-
marginLeft: '5rem',
|
|
80
|
-
marginRight: '5rem',
|
|
81
|
-
fontSize: '30px',
|
|
82
|
-
fontFamily: `ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace`,
|
|
83
|
-
},
|
|
84
|
-
button: {
|
|
85
|
-
paddingTop: '0.5rem',
|
|
86
|
-
paddingBottom: '0.5rem',
|
|
87
|
-
paddingLeft: '1rem',
|
|
88
|
-
paddingRight: '1rem',
|
|
89
|
-
color: 'rgba(55, 65, 81, 1)',
|
|
90
|
-
borderRadius: '0.25rem',
|
|
91
|
-
|
|
49
|
+
const warningClass = count > 10 ? 'text-red-500' : '';
|
|
92
|
-
},
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
const render = ({ attrs, state, computed }) => {
|
|
96
|
-
const { name, meta } = attrs;
|
|
97
|
-
const { count, setCount } = state;
|
|
98
|
-
const { sum } = computed;
|
|
99
|
-
|
|
100
50
|
return html`
|
|
101
|
-
<div>
|
|
51
|
+
<div class="mt-10">
|
|
102
|
-
<div class=
|
|
52
|
+
<div class="mb-2">
|
|
103
53
|
Counter: ${name}
|
|
104
|
-
<span
|
|
54
|
+
<span>starts at ${meta?.start}</span>
|
|
105
55
|
</div>
|
|
106
|
-
<div class=
|
|
56
|
+
<div class="flex flex-1 flex-row items-center text-gray-700">
|
|
107
|
-
<button class=
|
|
57
|
+
<button class="bg-gray-300 text-gray-700 rounded hover:bg-gray-200 px-4 py-2 text-3xl focus:outline-none" @click=${actions.decrement}>-</button>
|
|
108
|
-
<div class=
|
|
58
|
+
<div class="mx-20">
|
|
109
|
-
<h1>${count}</h1>
|
|
59
|
+
<h1 class="text-3xl font-mono ${warningClass}">${count}</h1>
|
|
110
60
|
</div>
|
|
111
|
-
<button class=
|
|
61
|
+
<button class="bg-gray-300 text-gray-700 rounded hover:bg-gray-200 px-4 py-2 text-3xl focus:outline-none" @click=${actions.increment}>+</button>
|
|
112
|
-
</div>
|
|
113
|
-
<div class=${styles.mx}>
|
|
114
|
-
<h1>Sum: ${sum}</h1>
|
|
115
62
|
</div>
|
|
116
63
|
</div>
|
|
117
64
|
`;
|
|
118
65
|
};
|
|
119
66
|
|
|
120
|
-
|
|
67
|
+
createElement({ url: 'app-counter.js' }, Counter);
|
|
121
|
-
name,
|
|
122
|
-
attrTypes,
|
|
123
|
-
stateTypes,
|
|
124
|
-
computedTypes,
|
|
125
|
-
styles,
|
|
126
|
-
render,
|
|
127
|
-
});
|
|
128
68
|
|
|
129
|
-
console.log(
|
|
69
|
+
console.log(renderHtml(html`<app-counter name="1"></app-counter>`));
|
|
130
70
|
```
|
|
131
|
-
|
|
132
|
-
This works in node, to make it work in the client side you need to either compile atoms-element using esintall or esbuild to an esm module and then
|
|
133
|
-
rewrite the path from 'atoms-element' to 'web_modules/atoms-element/index.js' or if you can host the node_modules in a web server and change the path to
|
|
134
|
-
the import 'atoms-element/element.js'
|