rsvp-reader/components/generic/Consumer.js
2019-12-08 09:16:12 +01:00

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)