Closed dy closed 5 years ago
Can spect signature be merged with jsx? h(target, props, ...children)
, spect(target, handler, props?)
.
This way <x ${fn}></x>
spect cannot, but aspect (handler) can: spect(target, (target, props, ...children) => {})
. This way, aspects are just hyperscript functions, and spect is like "render" from react.
But at the same time, this way <x>${fn}</x>
spect can, therefore spect can be an aspect spect(target, () => {})
, with special case of passing args if the fn is the second argument (no attributes).
Therefore spect can be used both ways: as htm or directly
html`<.selector>${el => {}}<//>` === spect('.selector', el => {})
html`<div x=1>content</div>` === spect('div', {x: 1}, 'content')
The problem boils down to developing intuition over separating create/read. Eg. <.class
- obviously queries elements, <div
- makes sure this element exists. But
? how to select all button
s (should we)?
. spect('button')
!== <button>
, therefore we can't spect('button')
.
? Can we solve that via context? let el = <button>
=== let el = spect('button')
- creates button. let appEl = <.app><button><//>
, selects app and makes sure there's a button inside. <:root button><//>
- selects all buttons in host.
? spect('button')
- would that query all buttons within the context, or make sure at least one button exists?
? what's the meaning of div.class
? Select all div.class
or make sure that exists?
. If we'd want multiple same aspects on the single node, - we'd have to ignore existing same aspect.
. There's no this problem in passing direct values: <${str|element}><//> === update
, <${fn}><//>
=== create.
. We have to allow <.class#id><//>
to be complacent with spect(selector, handler)
. Effects are like <.ripple class="mdc-ripple">{el => { MDCRipple.attachTo(el) }}<//>
. In that, selector-tag can apply props.
? What if we introduce <@.app><//>
for read/update? <@div></@>
. Makes sense by pronunciation, similar to decorators, as well as makes sense as aspect
. Although, spect('@selector')
is not really good.
! Having inverse rendering would be helpful. So, aspect internals has access to parent, not children.
. Limiting selectors to . and #:
So, final draft:
<#app use=${[Provider, Store, Persistor]}>
<aside#menu/>
// maybe prohibiting sugaring is better here to discern selectors visually, afterall it doesn't save tons of time
<aside id="menu" is=${Aside}/>
<main is=${Page}/>
<footer></footer>
<//>
spect('#app', {use: []},
spect('aside', {id: 'menu', is: Aside}),
spect('main', {is: Page}),
spect('footer')
)
? use-case: tachyons-like ui-framework? nope, does not make sense as no-js. Although extending some fx-styles is good idea, like animations etc.
Update, considering token research #23
<#app provider store persistor>
<aside sidemenu/>
<main page/>
<footer />
</>
Pre-final noble draft:
$('#app', el => html`
<aside ${sidemenu}/>
<main>${page}</main>
<footer/>
`)
With spectators there's a subtle problem. Although it very reminds jquery and at all the idea of lifetime helper is really good, there's no clear way to mount things. Should that be spect from the beginning to mount app? But then for apps that will be used just once - to start the app, and the rest is left to htm, which is way more important.
An idea, reminded by jsxify
<document.body>
and atomico<host>
- putting spect into JSX to directly point to container<mount to=${target|selector} ${...attrs}></mount>
. That enables portals, solves problem of passing attrs to host, instantly mounts app to possibly multiple parts of DOM and rids of JS in case of pure jsx.Possible approaches:
<root></root>
<host></host>
<div slot=${selector}></div>
<$${target}><//>
<_${target}></_>
<target></target>
<mount at=${selector}></mount>
<render to=${target}></render>
in
,at
<${document.element}><//>
+ htm easter egg<within target=${}></within>
<join with=${target}></join>
<attach to=${target}></attach>
<at target=${}></at>
<htm for=${target}></htm>
.<:.app><//>
- confusing ending<div container=${target}></div>
+ classical regl/component approach - should be a prop on every element in multiple branches, which is confusing, needs fragment, which would be<container=${target}></container>
or just<${target}></>
. Although - both of that is possible with htm lol, and even makes sense.!
<div.class#id></div>
for shortcut