WebComponentStateManager
by amindunited
HTML
<state-lee>
<div>
<input id="name-input" />
<input id="value-input" />
<button id="add-button">
Add
</button>
</div>
<div>
<select id="select-items">
</select>
</div>
<div>
<h3>
State:
</h3>
<code></code>
</div>
</state-lee>
CSS
code {
padding: 1rem;
}
JavaScript
class StateLee extends HTMLElement {
static state = {};
static getState = () => {
return state
}
static updateState = (fn) => {
const newState = fn(this.state);
this.state = newState;
this.emitUpdate();
}
static emitUpdate = () => {
const updateEvent = new CustomEvent('state-update', {
bubbles: true,
cancelable: false,
detail: {
state: this.state
}
});
const dispatcher = this.dispatchEvent || window.dispatchEvent;
dispatcher(updateEvent);
}
}
customElements.define(`state-lee`, StateLee, []);
/* const stateLee */
const addButton = document.querySelector('#add-button');
const nameInput = document.querySelector('#name-input');
const valueInput = document.querySelector('#value-input');
const selectItems = document.querySelector('#select-items');
const addToState = () => {
console.log('add to state');
console.log('the state:', StateLee.state);
StateLee.updateState((state) => {
console.log('update state call back', state);
const newState = structuredClone(state);
const nameValue = nameInput.value;
const value = valueInput.value;
if (nameValue && value) {
console.log('update');
newState[nameValue] = value;
}
nameInput.value = null;
valueInput.value = null;
return newState;
});
console.log('after?', StateLee.state);
}
addButton.addEventListener('click', addToState);
window.addEventListener('state-update', (e) => {
console.log('state update', e.detail.state);
const state = e.detail.state;
let options = '';
for (const key in state) {
options += `<option value="${key}">${state[key]}</options>`;
}
selectItems.innerHTML = options;
console.log('updating options', options);
document.querySelector('code').innerHTML =
JSON.stringify(e.detail.state);
});