Skip to content

Instantly share code, notes, and snippets.

@o0101
Last active August 28, 2020 10:25
Show Gist options
  • Save o0101/0a18a10c0dc1d98162d092fe759910f3 to your computer and use it in GitHub Desktop.
Save o0101/0a18a10c0dc1d98162d092fe759910f3 to your computer and use it in GitHub Desktop.
const Z = self.Z = {
keyed: {}
}
function def({
name: name = 'Widget',
render: render = () => `<h1>Hello World</h1>`,
innerStyle: innerStyle = () => `h1 { font-family: monospace; color: dodgerblue; }`,
outerStyle: outerStyle = () => ({height:'10rem', width:'100%', display:'block'}),
keyed: keyed = false
} = {}) {
Object.assign(component, {[Symbol.toStringTag]: name});
if ( keyed ) {
Z.keyed[name] = component;
component.els = {};
} else {
Z[name] = component;
component.el = null;
}
return component;
function component(state, key) {
// render and replace in place
let markup;
if ( keyed ) {
if ( ! component.els[key] ) {
component.els[key] = document.createElement('iframe');
component.els[key].frameBorder = 0;
}
markup = `<style>${innerStyle(state, key)}</style>` + render(state, key);
component.els[key].srcdoc = markup;
Object.assign(component.els[key].style, outerStyle(state));
} else {
if ( ! component.el ) {
component.el = document.createElement('iframe');
component.el.frameBorder = 0;
}
markup = `<style>${innerStyle(state)}</style>` + render(state);
component.el.srcdoc = markup;
Object.assign(component.el.style, outerStyle(state));
}
if ( keyed ) {
if ( ! Z[key] ) {
Z[key] = {};
}
// then we can call Z[key][name](state) to render in place.
Z[key][name] = (state) => component(state, key);
}
return {
toString() {
if ( keyed ) {
return component.els[key].outerHTML;
} else {
return component.el.outerHTML;
}
},
valueOf() {
return this.toString();
},
to(location = 'beforeEnd', elemOrSelector = 'body') {
let elem = elemOrSelector;
if ( typeof elemOrSelector == "string" ) {
elem = document.querySelector(elemOrSelector);
}
elem.insertAdjacentElement(location, keyed ? component.els[key] : component.el);
}
};
}
}
@o0101
Copy link
Author

o0101 commented Oct 17, 2019

Can do something like:

  • add script to resize iframe based on content size
  • And add actions to transmit intent from sub components to update global app state

@o0101
Copy link
Author

o0101 commented Oct 18, 2019

In terms of messages emitted by components. There will be:

  • state update ACTIONS, API: act({type:'add',data:{value:5}}), as well as
  • parent NOTIFICATIONS (pertaining to application events which do NOT require an update to the client state object, such as intermediate values changing, some user interface events), API: notify({event:'filterUpdated', data:{newFilter:{...}}})

Basically, it's concievable there are views that exist as:

  • purely decorate (emit no actions and no events at all)
  • immutable (emit events, but never actions to change state, such as subviews that contribute partial values to an actual value, examples: IME composition updates, data types with multiple complex values, like date fields (where activity in a subview does not mean that the whole value is ready, only a parent can decide that, so only parent can submit action to the store)., intermediate values (like creating an image filter with a few sliders, the image filter may not be part of the application state, but the image it applies to, and how the image looks after filter is applied, is part of the state)`
  • mutable (emit actions, these views / components can decide, based on notifications from sub components and computation based on their own user interface events, what if any actions need to be submitted).
  • diverse (perhaps capable of emitting notifications and actions).

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