This article was originally intended to be a readme for a small Github project I published where I am exploring using Elm and web components together. After writing it I realize it is really more generic and applicable to any framework -- hence pulling it out of the readme into a separate post.
I like the idea of leveraging native web components for building reusable UI components regardless of which technology you use. I believe it has a couple of key advantages that I would like to share.
You can use them with whatever framework du jour you are using today. If you work at a larger company, different teams may be using different technologies, and web components normally works with any of those (even with virtual doms) since they are no different than regular HTML elements. Making web components the lowest common denominator ensures your UI components works with any technology -- even with Elm!
Building complex software is challenging and reducing cognitive load is one of the key tools for success. Separating concerns is one of the most powerful ways of reducing cognitive load -- for example, writing database queries and CSS together requires juggling two completely separate concepts at the same time. I remember doing exactly this 20 years ago in good old Classic ASP. Luckily we don't do this anymore! When separating concerns we introduce constraints; artificial or technical boundaries, and constraints tend to free your mind.
For the same reason you would want to avoid writing database queries and CSS together, I think you would also want to avoid writing UI and business logic together. I have found it a useful pattern to separate the two. In the last couple of React apps I have built, UI components have been completely separate from my "app" components. In some cases a separate repo / npm package and in some cases just a separate folder within my application. UI components contain all the styles, layout, local UI state (e.g. whether the calendar popup is open) and they declaratively expose props/attributes for passing data and event handlers -- sound familiar? Yeah, this is exactly how native HTML elements works too. I believe separating UI and business logic and state has a profound effect on reducing cognitive load. For example, seeing
customerHasPendingOrders together is just too much to keep in my head at the same time.
So far my UI components have been regular React components, but as the web platform matures I think it makes sense to consider making them regular webcomponents instead. With interesting technologies such as lit-html and lit-element popping up I think building custom components, even more complex ones such as React Select, will become a delightful experience with the same declarative pattern we are used to and like about React. Add to that CSS variables finally getting adopted in all major browsers (and :part and :theme pseudo-elements being discussed) and I think even theming custom components using native technologies will become a breeze.
It sure is an exciting time to build web apps!