If you’ve been following the Patternfly mailing list or happened to stumble on our recent post on developers.redhat.com, “Are Web Components in the future for Patternfly?”, you’ve probably noticed that we’re doing some thorough research on web components right now.
I’d like to take this opportunity to provide a few updates on our findings and share some context on our recent discussions around web components in Patternfly.
Are web components feasible?
Custom Elements, HTML Imports, Shadow DOM, and HTML Templates are the new specifications heavily influencing web components (you can read a great introduction here if you’re new to these topics), but it’s important to remember that these are mutually independent. Although many examples combine Custom Elements with Shadow DOM CSS techniques, they are not required to be used in conjunction (another trait which adds to their versatility). Custom Elements can stand alone and be styled just like other HTML.
Due to Shadow DOM’s currently minimal browser support, it would not be a stretch to consider a gradual adaptation to implementing new web component standards like the following:
As browser support improves, Shadow DOM can be adopted to improve our CSS encapsulation where necessary. It should also be noted that while HTML Imports may be the most common way to consume web components, Custom Elements can be defined and included as ES6 classes. This alleviates another web component standard and gives options with this specification as well.
Exploring Web Components with Patternfly
Building on our past breakaway sprint efforts with web components, we’ve extended our <pf-tabs> element and tested our approach with some popular new web frameworks gaining traction at Red Hat: ReactJS and Angular2. Utilizing components as “leaf nodes” within other framework components makes them essentially comparable to other DOM nodes used, only much more flexible.
The goal of this research was to integrate a custom element in these frameworks alongside our Patternfly implementations and explore any roadblocks or challenges discovered.
You can see our current work on the <pf-tabs> component here.
(pf-tabs component rendered individually)
A few things to note about this component:
- The element has been tested in a React context and an Angular2 context. Any differences in element rendering behaviors are noted in the source of the component (to ensure proper behavior in both frameworks).
- We’ve added some performance tests to analyze rendering speeds with several occurrences of tabs and nested tabs.
- It is completely possible to use element attributes to give your element unique behaviors or styles in different contexts (e.g. the class attribute).
- Shadow DOM initialization and styles have been commented out and appropriate constructs have been added in their place. It is easy enough to add them back if desired.
Notes on Frameworks ReactJS and Angular2
There are too many details to cover in this post, however I encourage you to explore the aforementioned demonstrations. If you run these demos, you will easily notice that our tabs component works as intended in both frameworks and the new frameworks provide adequate contexts to create a Patternfly application.
(Tabs component rendered in a Patternfly/React app)
I should add that our discussions on these frameworks have been fruitful (luckily, there is already an abundance of materials for each to aid in our research). Both frameworks provide exceptional solutions for common problems app developers face like data binding, observing state and inter-component communication, custom events, and optimal rendering. Particularly important, we haven’t found web components causing any barriers in this regard and observed the patterns implemented in these solutions translate quite nicely to web components.
We’ve prepared plenty more to share on this in future posts and will be fine-tuning our strategy in coming weeks. We’ll also be exploring other topics like performance, server rendering, and modular design. So stay tuned to our blog and mailing list all you Patternfliers!