-
Notifications
You must be signed in to change notification settings - Fork 26
Framework Compatibility
Even though HelixUI strives to remain platform-agnostic, we also want to build functionality in a way that provides the least resistance for integration into a consumer's technology stack. As such, you should avoid implementing any business logic into new functionality (no API calls, no permission/authorization logic, no URLs, etc.).
The frameworks we aim for the most compatibility are:
- Vanilla HTML (i.e., no framework)
- Angular 1.x
- React 16+
- VueJS 2.x
Keep reading to learn more about framework compatibility issues and strategies to correct or work around them.
(a.k.a. No framework)
- Be aware of built-in methods and properties of HTMLElement and its prototype chain.
- Node ← Element ← HTMLElement
-
WARNING: Be aware that
autocomplete
for forms has browser compatibility issues.
TBD
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 HelixUI.
- copy
node_modules/helix-ui/
assets tosrc/assets/helix-ui/
- copy
node_modules/@webcomponents/webcomponentsjs/
assets tosrc/assets/webcomponentsjs/
- update
src/index.html
contents with official Helix layout markup - make sure
<link>
and<scripts>
insrc/index.html
point to files insrc/assets/helix-ui
andsrc/assets/webcomponentsjs
- add
CUSTOM_ELEMENTS_SCHEMA
to the list of schemas insrc/app/app.module.ts
(see snippet below)
- Configures angular that to allow 3rd-party custom elements.
/*
* 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 { }
-
TODO: Using
ref
to attach event listeners -
Warning: React's synthetic events violate non-bubbling specifications.
- It is a "known and intentional deviation".
- See facebook/react#12786 and facebook/react#6410 for information.
React 15 is not supported.
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:
<hx-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>
</hx-custom-element>
React 15 Renders the following: (notice how slot
is missing from <p id="second">
)
<hx-custom-element>
<p id="first">...</p>
<p id="second">...</p>
</hx-custom-element>
React 16+ Renders the following: (the slot
attribute is still present)
<hx-custom-element>
<p id="first">...</p>
<p id="second" slot="extra">...</p>
</hx-custom-element>
All HTMLElement
(custom element) lifecycle methods are executed in render()
-
React.Component
- constructor -
React.Component
- componentWillMount() -
React.Component
- render()-
HTMLElement
- create/connect- constructor
- attributeChangedCallback()
- connectedCallback()
-
-
React.Component
- componentDidMount()
-
React.Component
- componentWillUnmount() -
React.Component
- render()-
HTMLElement
- disconnect 2. disconnectedCallback()
-
-
React.Component
- componentWillUpdate() -
React.Component
- render()-
HTMLElement
- disconnect- disconnectedCallback()
-
HTMLElement
- create/connect- constructor
- attributeChangedCallback()
- connectedCallback()
-
-
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...
- Custom Elements Everywhere
- Bypass synthetic event system for Web Component events (facebook/react#7901)