Me and @whaaaley had a convo about how hyperapp could manage its components, and had some interesting ideas. To sum up the proposal of what I want to implement, here an example of a mixin that contains the state, actions, and views of components:
const CustomUI = () => ({
state: { count: 0 },
actions: {
up: state => ({ count: state.count + 1 })
},
// Example of the new `app.components`
components: {
'my-component': (data, children) =>
<div class='my-component'>
<span>{data.subject} ({data.count })</span>
<div>{children}</div>
</div>
}
})
Components are defined as (data, children) and return vnodes (from h()). They are used by providing the property name through the tag of h(tag, ...). For example:
h('my-component', data, children)
This would require changes to how app() uses vnode.tag when it goes to render.
Oh, and it also provides a lot better usage for components with JSX and Hyperx!
<my-component {...data}>
<span>hello world</span>
</my-component>
Here is just a sum of 4 awesome things I think come out of organizing components like this:
I think this is great! The only change I would make here is to rename components to templates, only because I'm conditioned to think of a component as state, actions, and events too, not just the h().
@jamen @whaaaley I would go with just view since it's one less word to remember, but maybe is because I am thinking about views and this proposal is more like having mixins carry their own custom tags?
Is there a reason why the signature is (data, children)? That looks like the signature of a custom tag (props, children). Are they related? And what about actions or state? The view don't need that? 馃
@jbucaran So I guess you can think of the proposal as a change to custom tags, then. I'm suggesting they be defined through app.templates (or some other name). That way mixins have a role in reusing the view, and also how they are defined on the same level as their actions and state.
Also, anything that compiles to We talked about h() or produces a { tag, data, children } would support custom tags with this.typeof tag === 'function', but that is just part of the cons with JSX, I guess. So either:
<MyComponent /> for <my-component />tag types. string, function, and customWould be will to try and implement this in a fork to test this idea out, if you think it would be a possibility :smile:
@jamen Option 1) is certainly no good ;) and option 2), implementation hurdles aside can be discussed!
As you mentioned on Slack, you didn't know about custom tags before creating this issue, so maybe we should close here and start a new one. You can explain there what's not sufficient about custom tags and why introducing a third tag type would be a good thing.
I feel that someone stumbling upon this issue later may be confused if they already knew about custom tags or misled if they didn't. Please close when you are ready to create a new issue 馃檹.
EDIT: Grammar.
Most helpful comment
@jamen @whaaaley I would go with just
viewsince it's one less word to remember, but maybe is because I am thinking about views and this proposal is more like having mixins carry their own custom tags?Is there a reason why the signature is (data, children)? That looks like the signature of a custom tag (props, children). Are they related? And what about actions or state? The view don't need that? 馃