-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathComponent.js
61 lines (48 loc) · 1.4 KB
/
Component.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import { h, render } from './index.js'
export default class extends HTMLElement {
constructor() {
super()
this.useShadowDOM = true
this.__state = {}
if(this.init) this.init()
this.watchProps = Object.keys(this.__state)
this.__attributesToState()
this.document = this.useShadowDOM ? this.attachShadow({mode: 'open'}) : this
}
__attributesToState() {
Object.assign(this.state, Array.from(this.attributes).reduce((obj, attr) => Object.assign(obj, {[attr.name]: attr.value}), {}))
}
get vdom() { return ({ state }) => '' }
get vstyle() { return ({ state }) => '' }
setAttribute(name, value) {
super.setAttribute(name, value)
if(this.watchProps.includes(name)) this.state[name] = value
}
removeAttribute(name) {
super.removeAttribute(name)
if(this.watchProps.includes(name) && name in this.state) delete this.state[name]
}
connectedCallback() {
if(this.connected) this.connected()
this.render()
}
disconnectedCallback() {
if(this.disconnected) this.disconnected()
}
setState(props = {}) {
return Object.assign(this.__state, props)
}
set state(value) {
Object.assign(this.__state, value)
}
get state() {
return this.__state
}
render(state) {
this.setState(state)
return render(h('root', {}, [
this.vdom({ state: this.__state }),
this.vstyle({ state: this.__state }),
]), this.document)
}
}