~repos /atoms-element

#js

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
Files changed (5) hide show
  1. element.d.ts +5 -3
  2. element.js +4 -12
  3. element.test.js +1 -1
  4. example/app-counter.js +37 -0
  5. 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
- getAttrs(): {[key: string]: any};
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(attrs) {
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.attrs = attrs;
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
- getAttrs() {
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.attrs.find((item) => item.name === key.toLowerCase())?.value;
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.getAttrs();
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 AtomsElement, { html, object, number, string } from '../element.js';
1
+ import { html, css } from '../element.js';
2
2
  import Page from '../page.js';
3
+ import './app-counter.js';
3
4
 
4
- class Counter extends AtomsElement {
5
+ class CounterPage extends Page {
6
+ route() {
5
- static name = 'app-counter';
7
+ return '/counter';
6
-
7
- static attrTypes = {
8
- name: string.isRequired,
9
- meta: object({
10
- start: number,
11
- }),
12
- };
8
+ }
13
9
 
14
- static styles = `
10
+ styles() {
15
- .container {
11
+ return css``;
16
- }
12
+ }
17
- `;
18
13
 
19
- render() {
14
+ head({ config }) {
20
- const { name, meta } = this.getAttrs();
21
- const [count, setCount] = this.useState(meta?.start || 0);
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
- <h1 class="text-1xl">${count}</h1>
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
- console.log(ssr(html`<app-counter name="1"></app-counter>`));
27
+ const counterPage = new CounterPage({ config: { lang: 'en', title: 'Counter App' } });
28
+ console.log(counterPage.render());