components
See original GitHub issueSo @karissa asked in https://github.com/datproject/datproject.org/issues/511 what the status is on a certain component, and I linked to like 5 different things. I feel I’ve got a pretty good grasp of the status of components in choo, but that information is not written down anywhere right now. So this is a tracking issue to figure out where our components are at.
Building components
When I first wrote about the ideas of choo v5, I also mentioned components. We didn’t end up shipping components in the final release. This was because it turned out all the primitives for components can be built on top of choo, so by documenting the patterns needed, we can have them live as separate modules instead.
At their core, components are stateful DOM nodes that are not affected by the diffing algorithm. They manage their own lifecycle, and fire internal events when they’re mounted, unmounted or receive new data. This makes them ideal to wrap stateful third party code, like the leaflet map framework.
In order to achieve stateful nodes, we must make sure that certain parts of the DOM tree are not diffed by nanomorph
. We can do this by setting .isSameNode() on a node. This must be done conditionally, however, because at a first render we must pass a DOM tree. To detect when nodes are added and removed from the DOM we use on-load. Because wiring all these bits up together can be tricky, and prone to error, we created nanocomponent.
nanocomponent
is the core of our component abstraction. It’s just a convention turned into code. It exposes a prototypical API, which might prove to be a bit unwieldy if you’re writing application code. So for applications we’ve created microcomponent. It has a whole bunch of conventions around state management, logging, tracing, and determining if elements should be updated. If you’re curious how to write your own nanocomponent
-based elements, I think the microcomponent
API should give you a good idea of how to shape it (e.g. never expose a prototype API for application-level code).
Core modules
- nanocomponent is the core abstraction for our components. It’s a convenience wrapper around the patterns
nanomorph
requires to have stateful nodes, and uses on-load under the hood. It exposes a prototypical API. This is a module-level component; you should generally only use this if you’re creating modules to put on npm and not in applications. - cache-element caches an element, forever. This is ideal for parts of the app that never change (e.g. headers, footers, inner elements, etc.)
- microcomponent is a small wrapper around
nanocomponent
. It exposes an API that’s quite similar to React’s component API. But we also include tracing and logging, which makes it very debuggable. This is an application-level component; you should generally only use this if you’re writing applications, and not use it to to create npm modules. - cache-component by @bcomnes - a different take on
microcomponent
. This is not sure yet, but I think there’s a fair chance the two modules may converge in the future (or find a slightly different niche, too soon to tell)
Issues
- on-load listeners may leak over time (https://github.com/shama/on-load/issues/13). Since we rely on
on-load
for stateful components, this might be an issue - nanomorph when morphing lists, elements don’t apply child node reordering (https://github.com/yoshuawuyts/nanomorph/issues/8). Has a PR in https://github.com/yoshuawuyts/nanomorph/issues/61
- morphing two instances of nanocomponent can leak proxy nodes https://github.com/yoshuawuyts/nanocomponent/issues/29
ecosystem
- list element: So far hyperlist-component seems to be working the best, but I feel there’s a few things missing still:
- No tracing support yet (e.g. nanotiming)
- The API uses an options argument to pass down methods, I think ideally we’d have something closer to https://github.com/editdata/infinite-elements/issues/1 (less words to learn means it’s easier to pick up)
- It doesn’t support variable height elements yet, although there appears to be work on that front (https://github.com/tbranyen/hyperlist/issues/12)
- form element: I feel forms can be improved upon, I sketched out an API 7 months ago, but yeah we should probably figure out a way to easily create forms
- modal element: either https://github.com/shama/modal-element needs a patch, or we need to rewrite it from scratch to work with
nanocomponent
. Can be mostly modeled after base-elements/modal.
And there’s probably other elements that can be done: tabs, dropdown menus, slide-in panels, notification bubbles. The works. It’d be cool if people that are interested would start building those out too!
Wrapping up
And that’s it - I think this captures the current state of components in choo. I hope it’s been useful, and if you build something cool, have questions or want to help out on any of this - we’d love to hear from you! Cheers! ✨
Issue Analytics
- State:
- Created 6 years ago
- Reactions:10
- Comments:6 (6 by maintainers)
Top GitHub Comments
I like the nanocomponent idea, but after reading this, it doen’t sound like components are a part of choo. I mean, they can be used with choo, but they are not made for choo, also you could use (maybe) another component library with choo. So, when I think about choo components I imagine a plugin or library that extend nanocomponent and allow to use components in choo like this
I don’t know if that make sense, but thats the way it feels natural for me to use components. The registration method was the first one I came up with haha.
Components are now availaible in choo, I guess is safe to close this, reopen otherwise.