Skip to content

Instantly share code, notes, and snippets.

@o0101
Last active August 28, 2020 10:27
Show Gist options
  • Save o0101/01c81227ae05c34da72fbfe6aa4a66ea to your computer and use it in GitHub Desktop.
Save o0101/01c81227ae05c34da72fbfe6aa4a66ea to your computer and use it in GitHub Desktop.
hiimgui tests -hypertext integrated immediate mode gui
// api tests
function * on() {
while(true) {
select(
option('plan1'),
option('plan2'),
option('plan3')
);
const [select, input] = yield 'input';
switch(select.value) {
case 'plan1':
select(...plan1opts);
break
}
}
function *form() {
button('submit')
}
[# listing 1]
function form() {
this.method = 'post'; this.action = 'login';
input('email');
input('password');
if (button('submit')) {
page(fetch(this.action, { method: this.method, body: new FormData(this)}));
}
}
page(form);
new form();
this compiles to
<form id=form1 method=post action=login>
<input type=email name=email>
<input type=password name=password>
<button>submit</button>
</form>
<script>
const form1 = document.querySelector('#form1');
const button = form1.querySelector('button');
button.onclick = async e => {
e.preventDefault(); e.stopPropagation();
const res = await fetch(form1.action, { method: form1.method, body: new FormData(form1)})).then(r => r.text());
page(res);
};
</script>
page is basically
function page(...args) {
for( const arg of args ) {
if ( typeof arg == "string" ) {
document.body.innerHTML = '';
document.body.insertAdjacentHTML('afterBegin', arg);
} else if ( typeof arg == "function" ) {
self[arg.name] = compile(arg);
}
}
}
function compile(f) {
const tagName = f.name;
return function(...args) {
const attrs = new f(...args);
const tag = document.createElement(tagName);
for(const attr of Object.keys(attrs)) {
tag.setAttribute(attr, attrs[attr]);
}
};
}
// it's sort of fiddly tho and I'm not sure the concise syntax in listing 1 really justifies it
function *frame({getState, setState, updateState}, render, ...toEvents) {
while(true) {
render(getState());
const event = yield toEvents;
const newState = updateState(getState(), event);
setState(newState);
}
}
hiim(frame, render, 'click', 'submit', 'input', 'scroll', 'keypress', 'mousemove');
function render(state) {
document.body.innerHTML = `
<html tags>
${ state.values }
<more html tags>
`;
}
@o0101
Copy link
Author

o0101 commented Apr 28, 2019

// state

const state = {};

export function getState() {
  return clone(state);
}

export function setState(newState) {
  Object.assign(state, clone(newState));
}

export function updateState(state, event) {
  // actions // reducers
}

@o0101
Copy link
Author

o0101 commented Apr 28, 2019

hiim is a function that receives the yielded event names, applies the listeners.

with a clever enough API (allowing to write render templates, specify events, specify actions and how they change state), this could be a good pattern.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment