53 lines
1.2 KiB
JavaScript
53 lines
1.2 KiB
JavaScript
import { createParentsIterator } from './ParentsIterator.js'
|
|
import { StateProvider } from './Provider.js'
|
|
|
|
class StateConsumer extends HTMLElement {
|
|
constructor() {
|
|
super()
|
|
this.provider = null
|
|
this.appendChild(document.createElement('slot'))
|
|
}
|
|
|
|
get name() {
|
|
return this.getAttribute('name')
|
|
}
|
|
|
|
/** Returns the value of the corresponding provider */
|
|
get value() {
|
|
return this.provider ? this.provider.value : null
|
|
}
|
|
|
|
connectedCallback() {
|
|
this.provider = this.findProvider()
|
|
if (this.provider) {
|
|
this.provider.addObserver(this)
|
|
}
|
|
this.update(this.provider)
|
|
}
|
|
|
|
disconnectedCallback() {
|
|
this.provider.removeObserver(this)
|
|
}
|
|
|
|
/**
|
|
* Traverses tree upwards until a Provider with the same name is found
|
|
* Returns the closest provider or null if none is existent
|
|
*/
|
|
findProvider() {
|
|
for (let node of createParentsIterator(this)) {
|
|
if (node instanceof StateProvider && node.name === this.name) {
|
|
return node
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
|
|
update({ value }) {
|
|
if (typeof this.onChange === 'function') {
|
|
this.onChange(value)
|
|
}
|
|
}
|
|
}
|
|
|
|
window.customElements.define('state-consumer', StateConsumer)
|