useState works!

This commit is contained in:
John Shaver 2019-03-25 19:50:23 -07:00
parent b6d8d8f447
commit e5d58ddf11
5 changed files with 113 additions and 39 deletions

36
hookComponentFactory.js Normal file
View file

@ -0,0 +1,36 @@
import {prepareForRender} from "./store.js";
import getId from "./id.js";
export function hookComponentFactory(name, propNames, hookRender) {
class ComponentClass extends HTMLElement {
constructor (...args) {
super();
this.attachShadow({mode: 'open'});
this.identifier = getId(name);
this.domRender = hookRender.bind(this);
return;
}
render(args) {
prepareForRender(this.identifier, () => this.attributeChangedCallback());
let newDom = this.domRender(args, this);
this.shadowRoot.innerHTML= newDom;
}
connectedCallback() {
this.render(this.parseAttributes())
}
attributeChangedCallback() {
this.render(this.parseAttributes())
}
parseAttributes() {
console.log(this);
let attr = {};
for(let i = 0; i < this.attributes.length; ++i) {
attr[this.attributes[i].name] = this.getAttribute(this.attributes[i].name);
}
console.log("Parse attributes: ", attr);
return attr;
}
}
window.customElements.define(name, ComponentClass);
return ComponentClass;
}

5
id.js Normal file
View file

@ -0,0 +1,5 @@
let nextId = 1;
export default function getId(name){
return name + nextId++;
}

View file

@ -1,39 +1,3 @@
function pureComponentFactory (name, functionalRender) {
class ComponentClass extends HTMLElement {
constructor (...args) {
super();
this.attachShadow({mode: 'open'});
console.log("CONSTRUCTOR");
return;
}
render(args) {
let newDom = functionalRender(args);
console.log("Rendering: ", newDom);
this.shadowRoot.innerHTML= newDom;
}
static get observedAttributes() {
//How do we make this flexible????
return ['count'];
}
connectedCallback() {
this.render(this.parseAttributes())
}
attributeChangedCallback() {
this.render(this.parseAttributes())
}
parseAttributes() {
console.log(this);
let attr = {};
for(let i = 0; i < this.attributes.length; ++i) {
attr[this.attributes[i].name] = this.getAttribute(this.attributes[i].name);
}
console.log("Parse attributes: ", attr);
return attr;
}
}
window.customElements.define(name, ComponentClass);
return ComponentClass;
}
export {pureComponentFactory} from "./pureComponentFactory.js";
export {hookComponentFactory} from "./hookComponentFactory.js";
export {useState} from "./store.js";

38
pureComponentFactory.js Normal file
View file

@ -0,0 +1,38 @@
import getId from "./id.js";
export function pureComponentFactory (name, propNames, functionalRender) {
class ComponentClass extends HTMLElement {
constructor (...args) {
super();
this.attachShadow({mode: 'open'});
this.identifier = getId(name);
return;
}
render(args) {
let newDom = functionalRender(args);
this.shadowRoot.innerHTML= newDom;
}
static get observedAttributes() {
//How do we make this flexible????
return propNames;
}
connectedCallback() {
this.render(this.parseAttributes())
}
attributeChangedCallback() {
this.render(this.parseAttributes())
}
parseAttributes() {
console.log(this);
let attr = {};
for(let i = 0; i < this.attributes.length; ++i) {
attr[this.attributes[i].name] = this.getAttribute(this.attributes[i].name);
}
console.log("Parse attributes: ", attr);
return attr;
}
}
window.customElements.define(name, ComponentClass);
return ComponentClass;
}

31
store.js Normal file
View file

@ -0,0 +1,31 @@
const stateStore = {};
let componentId;
let stateIndex = 0;
let handleStateChange;
export function useState(defaultValue) {
const savedId = componentId;
const savedIndex = stateIndex++;
const savedHandler = handleStateChange;
if(!stateStore[savedId]) {
stateStore[savedId] = [];
}
if(!stateStore[savedId][savedIndex]) {
stateStore[savedId][savedIndex] = [
defaultValue,
value => {
stateStore[savedId][savedIndex][0] = value;
savedHandler();
},
]
}
return stateStore[savedId][savedIndex]
}
export function prepareForRender(_componentId, _handleStateChange) {
stateIndex = 0;
componentId = _componentId;
handleStateChange = _handleStateChange;
}