Skip to content

Instantly share code, notes, and snippets.

@CITguy
Last active May 1, 2020 19:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CITguy/6c407eb6e243bb092ca4acf0472ff9eb to your computer and use it in GitHub Desktop.
Save CITguy/6c407eb6e243bb092ca4acf0472ff9eb to your computer and use it in GitHub Desktop.
Web Components Framework Compatibility

Angular

This guide is in reference to modern versions of Angular (v2+).

Compatibility

@angular/cli

If you want use @angular/cli to bootstrap your application, you'll need to make sure to do the following to ensure maximum compatibility with custom elements.

Add CUSTOM_ELEMENTS_SCHEMA to the list of schemas in src/app/app.module.ts to allow 3rd-party custom elements in angular components (see snippet below).

/* 
 * src/app/app.module.ts 
 */
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent],
  schemas: [ CUSTOM_ELEMENTS_SCHEMA ]
})
export class AppModule { }

AngularJS

This guide is in reference to legacy 0.x and 1.x versions of AngularJS.

Compatibility

However, according to custom-elements-everywhere.com, AngularJS 1.7.8 has perfect compatibility with custom elements.
Compatibility with earlier versions of AngularJS 1.x are unknown, though.

Recommendations

If you are using AngularJS, you might want to consider upgrading or porting to a modern framework.
As announced by the AngularJS team, AngularJS 1.7 is the last feature release and will remain in a 3-year Long Term Support period.
On June 30, 2021, AngularJS will reach the end of its support.

Resources

React 15

Compatibility

React 15 does not fully support Custom Element v1 spec

It lacks support for the slot attribute, which is required in order to take advantage of Light DOM redistribution into Shadow DOM slots. For this redistribution to happen, the slot attribute needs to be present in the rendered markup.

React 15 ignores unknown attributes and slot isn't a known attribute, so it's missing from the rendered markup. This results in Light DOM elements being redistributed into the wrong Shadow DOM slots.

Assume the following React/JSX Template:

<my-custom-element>
  <p id="first">
    I will be redistributed into the default, unnamed slot in Shadow DOM.
  </p>

  <p id="second" slot="extra">
    I should be redistributed into the "extra" slot in Shadow DOM.
    React 15 doesn't include [slot="extra"], so I get redistributed 
    into the default, unnamed slot instead.
  </p>
</my-custom-element>

React 15 Renders the following: (notice how slot is missing from <p id="second">)

<my-custom-element>
  <p id="first">...</p>
  <p id="second">...</p>
</my-custom-element>

React 16+ Renders the following: (the slot attribute is still present)

<my-custom-element>
  <p id="first">...</p>
  <p id="second" slot="extra">...</p>
</my-custom-element>

React 16

Compatibility

  • Listening for custom events in React requires the use of a ref in order to attach event listeners via ref.addEventListener()
  • Warning: React's synthetic events violate non-bubbling specifications.

React Component Lifecycle

TL;DR - All HTMLElement (custom element) lifecycle methods execute during render()

Mount Phase

  1. React.Component - constructor
  2. React.Component - componentWillMount()
  3. React.Component - render()
    1. HTMLElement - create/connect
      1. constructor
      2. attributeChangedCallback()
      3. connectedCallback()
  4. React.Component - componentDidMount()

Unmount Phase

  1. React.Component - componentWillUnmount()
  2. React.Component - render()
    1. HTMLElement - disconnect
      1. disconnectedCallback()

Update Phase

  1. React.Component - componentWillUpdate()
  2. React.Component - render()
    1. HTMLElement - disconnect
      1. disconnectedCallback()
    2. HTMLElement - create/connect
      1. constructor
      2. attributeChangedCallback()
      3. connectedCallback()

Resources

Vue 2.x

Compatibility

There are no known compatibility issues when consuming custom elements in Vue templates.

Notes

  • FYI: nesting a <div> within a <p> seems to break data binding in VueJS 2.5
    • (codepen example)
    • trying to track down the reason why this breaks
    • To be continued...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment