Skip to content

Instantly share code, notes, and snippets.

@priley86
Last active May 17, 2023 14:14
Show Gist options
  • Save priley86/1f1b66cea7bd638049f31dfac9332b6a to your computer and use it in GitHub Desktop.
Save priley86/1f1b66cea7bd638049f31dfac9332b6a to your computer and use it in GitHub Desktop.
Web Components - latest thoughts

General links to read about Web Components

https://www.webcomponents.org/ https://www.polymer-project.org/

Best Practices: https://developers.google.com/web/fundamentals/web-components/

Styling within the Shadow Dom w/ CSS Properties: https://developers.google.com/web/fundamentals/web-components/shadowdom#stylefromoutside

State of Web Components: 2019 https://web.dev/web-components-io-2019

Link to Carbon WC repo (and relevant issue): https://github.com/carbon-design-system/carbon-custom-elements carbon-design-system/issue-tracking#121

WC Slides on Carbon / Lit-Elements

Patrick's Slides on Lit-HTML/Lit-Elements https://docs.google.com/presentation/d/16m9BkgJuoX2ymLeNwuGQxO5d5yDe_2IJMFX7LQnYx-g/edit?usp=sharing

PF4 POC

POC Repo: https://github.com/priley86/pf4-webcomponents-poc

Deployed Storybook: http://pf4-webcomponents-poc.surge.sh/?path=/story/button--default

Some notes/questions I've gathered so far:

  • There are actually three Storybooks here which we can build and demo - a Polymer version (that uses our vanilla lit-html web components), a React version, and an Angular version. The link above is just the Polymer version. I highly recommend this approach because it is actually integration testing WCs developed alongside frameworks as you develop new WCs.
  • Carbon uses a "createReactCustomElementType" utility to automatically build React shims. These can then be used in the React storybook and even exposed as wrappers to React consumers (although that may be a bit too automated if custom shims are needed): https://github.com/priley86/pf4-webcomponents-poc/blob/initial/src/globals/wrappers/createReactCustomElementType.ts

Discovered challenges so far within POC:

  • Some CSS selectors which make uses of nested selection, i.e.: .class1 > .class2 or .class1 > * do not penetrate the Shadow DOM root of a custom element if defined outside the WC. We'll need to analyze this and see what cases need adjustment (there are over 247 uses of the > * selector in patternfly.css today for example). Another such case is the pf-m-redhat-font class which applies globally for applying fonts. To work around this, we can set font-family on the element or the :root:
:root {
  font-family: var(--pf-global--FontFamily--redhatfont--sans-serif);
 }

A better way may be to implement something like cascading attributes: https://github.com/patternfly/patternfly-elements/blob/master/elements/pfe-band/src/pfe-band.js#L123

OR self implement a Context pattern. Stencil JS has done exactly this w/ "State Tunneling": https://www.joshmorony.com/state-management-with-state-tunnel-in-stencil-js/

Additional Notes from PF Elements Team

How-To-Components Demos https://developers.google.com/web/fundamentals/web-components/examples

Polyfill (and potential component bundler) polyfill.io

Disabling JS - should still render light DOM for other web crawlers, Chrome is the only engine that runs JS.

Light Dom - if semantically important, place it in the light DOM, then use a slot to progressively enhance content.

Light Dom styles will override host styles (:host) - higher specificity.

Broadcast variables - used w/ themes for variation (dark/light). These are css properties with fallbacks. CSS properties don’t really have conditionals. patternfly/patternfly-elements#392

Current components (notes on a few): pfe-content-set - a component that changes content based on the window size pfe-datetime - uses the Intl object instead of Moment.js pfe-icon - icon works with any font awesome or red hat font, svg

PF Elements blog: https://medium.com/patternfly-elements

Problems w/ Angular: https://medium.com/patternfly-elements/using-patternfly-elements-web-components-in-your-angular-app-4b18b1c9c363 MutationObserver - an alternative to slotChanged with more granularity on content changed.

Lit-Element (and Templates) as a potential option to replacing rendering. Per Google, reusing template blocks is the most performant.

document.createElement(‘template’); 

Service Workers - not currently exploring these (would need more infrastructure).

SSR (for React testing w/ JSDOM) - it's possible as long as you polyfill window and mutation observer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment