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);
});