~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.
72cd8533
—
Peter John 4 years ago
improve example
- element.d.ts +5 -3
- element.js +4 -12
- element.test.js +1 -1
- example/app-counter.js +37 -0
- example/index.js +16 -28
element.d.ts
CHANGED
|
@@ -32,10 +32,13 @@ export declare type Location = {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
export default class AtomsElement {
|
|
35
|
+
static register(): () => void;
|
|
36
|
+
static observedAttributes: Array<string>;
|
|
37
|
+
static getElement: (name: string) => AtomsElement | undefined;
|
|
35
38
|
config: Config;
|
|
36
39
|
location: Location;
|
|
37
|
-
styles(): string
|
|
38
|
-
|
|
40
|
+
attrs: {[key: string]: any};
|
|
41
|
+
styles: () => string;
|
|
39
42
|
useState: <S>(initialState: S | (() => S)) => [S, Dispatch<SetStateAction<S>>];
|
|
40
43
|
useEffect: (effect: EffectCallback, deps?: DependencyList) => void;
|
|
41
44
|
useLayoutEffect: (effect: EffectCallback, deps?: DependencyList) => void;
|
|
@@ -46,5 +49,4 @@ export default class AtomsElement {
|
|
|
46
49
|
) => [ReducerStateWithoutAction<R>, DispatchWithoutAction];
|
|
47
50
|
useCallback: <T extends (...args: any[]) => any>(callback: T, deps: DependencyList) => T;
|
|
48
51
|
useMemo: <T>(factory: () => T, deps: DependencyList | undefined) => T;
|
|
49
|
-
useRef: <T>(initialValue: T | null | undefined) => MutableRefObject<T>;
|
|
50
52
|
}
|
element.js
CHANGED
|
@@ -386,7 +386,7 @@ export default class AtomsElement extends BaseElement {
|
|
|
386
386
|
return Object.keys(this.attrTypes).map((k) => k.toLowerCase());
|
|
387
387
|
}
|
|
388
388
|
|
|
389
|
-
constructor(
|
|
389
|
+
constructor(ssrAttributes) {
|
|
390
390
|
super();
|
|
391
391
|
this._dirty = false;
|
|
392
392
|
this._connected = false;
|
|
@@ -398,7 +398,7 @@ export default class AtomsElement extends BaseElement {
|
|
|
398
398
|
layoutEffects: [],
|
|
399
399
|
cleanup: [],
|
|
400
400
|
};
|
|
401
|
-
this.
|
|
401
|
+
this.ssrAttributes = ssrAttributes;
|
|
402
402
|
this.config = isBrowser ? window.config : global.config;
|
|
403
403
|
this.location = isBrowser ? window.location : global.location;
|
|
404
404
|
}
|
|
@@ -477,18 +477,10 @@ export default class AtomsElement extends BaseElement {
|
|
|
477
477
|
return this.hooks.values[index];
|
|
478
478
|
}
|
|
479
479
|
|
|
480
|
-
useRef() {
|
|
481
|
-
const index = this.currentCursor++;
|
|
482
|
-
if (this.hooks.values.length <= index) {
|
|
483
|
-
this.hooks.values[index] = { current: initialValue };
|
|
484
|
-
}
|
|
485
|
-
return this.hooks.values[index];
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
|
|
480
|
+
get attrs() {
|
|
489
481
|
return Object.keys(this.constructor.attrTypes).reduceRight((acc, key) => {
|
|
490
482
|
const attrType = this.constructor.attrTypes[key];
|
|
491
|
-
const newValue = isBrowser ? this.getAttribute(key.toLowerCase()) : this.
|
|
483
|
+
const newValue = isBrowser ? this.getAttribute(key.toLowerCase()) : this.ssrAttributes.find((item) => item.name === key.toLowerCase())?.value;
|
|
492
484
|
const data = attrType.parse(newValue);
|
|
493
485
|
attrType.validate(`<${this.constructor.name}> ${key}`, data);
|
|
494
486
|
acc[key] = data;
|
element.test.js
CHANGED
|
@@ -253,7 +253,7 @@ test('AtomsElement', async () => {
|
|
|
253
253
|
const {
|
|
254
254
|
perPage,
|
|
255
255
|
address: { street },
|
|
256
|
-
} = this.
|
|
256
|
+
} = this.attrs;
|
|
257
257
|
const [count] = this.useState(0);
|
|
258
258
|
return html`
|
|
259
259
|
<div perPage=${perPage}>
|
example/app-counter.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import AtomsElement, { html, css, object, number, string } from '../element.js';
|
|
2
|
+
|
|
3
|
+
class Counter extends AtomsElement {
|
|
4
|
+
static name = 'app-counter';
|
|
5
|
+
|
|
6
|
+
static attrTypes = {
|
|
7
|
+
name: string.isRequired,
|
|
8
|
+
meta: object({
|
|
9
|
+
start: number,
|
|
10
|
+
}),
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
static styles = css`
|
|
14
|
+
.container {
|
|
15
|
+
}
|
|
16
|
+
`;
|
|
17
|
+
|
|
18
|
+
render() {
|
|
19
|
+
const { name, meta } = this.attrs;
|
|
20
|
+
const [count, setCount] = this.useState(meta?.start || 0);
|
|
21
|
+
|
|
22
|
+
return html`
|
|
23
|
+
<div>
|
|
24
|
+
<div class="font-bold mb-2">Counter: ${name}</div>
|
|
25
|
+
<div class="flex flex-1 flex-row text-3xl text-gray-700">
|
|
26
|
+
<button @click=${() => setCount((v) => v - 1)}>-</button>
|
|
27
|
+
<div class="mx-20">
|
|
28
|
+
<h1 class="text-1xl">${count}</h1>
|
|
29
|
+
</div>
|
|
30
|
+
<button @click=${() => setCount((v) => v + 1)}>+</button>
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
`;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
Counter.register();
|
example/index.js
CHANGED
|
@@ -1,40 +1,28 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { html, css } from '../element.js';
|
|
2
2
|
import Page from '../page.js';
|
|
3
|
+
import './app-counter.js';
|
|
3
4
|
|
|
4
|
-
class
|
|
5
|
+
class CounterPage extends Page {
|
|
6
|
+
route() {
|
|
5
|
-
|
|
7
|
+
return '/counter';
|
|
6
|
-
|
|
7
|
-
static attrTypes = {
|
|
8
|
-
name: string.isRequired,
|
|
9
|
-
meta: object({
|
|
10
|
-
start: number,
|
|
11
|
-
}),
|
|
12
|
-
}
|
|
8
|
+
}
|
|
13
9
|
|
|
14
|
-
|
|
10
|
+
styles() {
|
|
15
|
-
|
|
11
|
+
return css``;
|
|
16
|
-
|
|
12
|
+
}
|
|
17
|
-
`;
|
|
18
13
|
|
|
19
|
-
|
|
14
|
+
head({ config }) {
|
|
20
|
-
const { name, meta } = this.getAttrs();
|
|
21
|
-
|
|
15
|
+
return html` <title>${config.title}</title> `;
|
|
16
|
+
}
|
|
22
17
|
|
|
18
|
+
body() {
|
|
23
19
|
return html`
|
|
24
20
|
<div>
|
|
25
|
-
<div class="font-bold mb-2">Counter: ${name}</div>
|
|
26
|
-
<div class="flex flex-1 flex-row text-3xl text-gray-700">
|
|
27
|
-
<button @click=${() => setCount((v) => v - 1)}>-</button>
|
|
28
|
-
<div class="mx-20">
|
|
29
|
-
|
|
21
|
+
<app-counter name="1"></app-counter>
|
|
30
|
-
</div>
|
|
31
|
-
<button @click=${() => setCount((v) => v + 1)}>+</button>
|
|
32
|
-
</div>
|
|
33
22
|
</div>
|
|
34
23
|
`;
|
|
35
24
|
}
|
|
36
25
|
}
|
|
37
26
|
|
|
38
|
-
Counter.register();
|
|
39
|
-
|
|
40
|
-
|
|
27
|
+
const counterPage = new CounterPage({ config: { lang: 'en', title: 'Counter App' } });
|
|
28
|
+
console.log(counterPage.render());
|