Open deefco opened 1 year ago
@deefco You can already do this in TKO with a parameter e.g.
class TheTime extends tko.Component {
get template() {
const date = new Date().toISOString()
return <div>{date}</div>
}
}
class SideBar extends tko.Component {
constructor(params) {
super()
this.inner = params.insideTheBar
}
get template() {
return (
<div>
<h2>Sidebar header</h2>
{this.inner}
</div>
);
}
}
SideBar.register()
TheTime.register()
tko.applyBindings()
// there's no concept of an "App" in TKO.
<side-bar insideTheBar={<the-time />} /> // JSX
// or
<side-bar insideTheBar={<the-time></the-time}></side-bar> // proper HTML
Parameterization preserves the separation of responsibilities. We don't want components to have access to the inner data structures, since they may change.
TKO also has a concept of <template>
and <slot>
slots (similar to Vue) but it's rather verbose to achieve nearly the same outcome. It exists for legacy apps that cannot use T/JSX.
Do these happen to solve your use case?
<side-bar insideTheBar={<the-time />} /> // JSX
// or
<side-bar insideTheBar={<the-time></the-time}></side-bar> // proper HTML
My code is nothing but syntactic sugar for
<side-bar><the-time /></side-bar>
<side-bar children={<the-time />} />
It just ensures you can write nested jsx the way you would write html.
I'm not sure I understand your argument "Parameterization preserves the separation of responsibilities. We don't want components to have access to the inner data structures, since they may change." Could you explain that further? It seems to me that when you manually pass child components the parent also has access to the inner data structure of the element?
Nested components are also mentioned in the very first paragraph of the jsx standard. If tko works differently then perhaps there should be a notice in the documentation somewhere that tko doesn't support this?
@deefco I was thinking about this a bit and I think I understand the ask. Tell me if this makes sense for a desirable outcome:
The default get template
for a tko.ViewComponent
could/should be the inner HTML passed to that template.
class SideBar extends tko.ViewComponent {
}
SideBar.register()
// Given
<sub-menu><b>hello</b></sub-menu>
// Would render as
<sub-menu><b>hello</b></sub-menu>
This also enables some mediation since a ViewComponent
could use super.template
to get the children, and possibly do things with them e.g.
class SideBar extends tko.ViewComponent {
get template () {
return <div class='abc'>{super.template}</div>
}
}
SideBar.register()
// Now
<sub-menu><b>hello</b></sub-menu>
/// will render as
<sub-menu><div class='abc'><b>hello</b></div></sub-menu>
This seems to make sense to me. Do you feel like this is the desired outcome, or is there a use case that I haven't considered here?
Hi, this fix makes createElement automatically bind the child elements of a custom component as
parameters.children
in said component. This enables the creation of "layout components", where you can render {parameters.children} and display whatever components you passed into it.Quick example:
The time component will now get rendered inside the sidebar, without the sidebar component having to know anything about it.
For more information see: https://reactjs.org/docs/composition-vs-inheritance.html