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)