HelixUI with React - HelixDesignSystem/helix-ui GitHub Wiki

React can consume Web Components with some known workarounds.

Please read "React: Web Components" for more information.

Installing

Prerequisites

  1. Latest stable NodeJS (for the npm and npx command-line utilities)
  2. helix-ui v0.18.0 or later

Assumptions

(all paths are relative to the root of the project directory)

  1. Your app was bootstrapped via create-react-app
  2. Your app is a greenfield app (brand new codebase)
  3. Vendor assets live in public/vendor/ (coded by 3rd party)

Instructions

1. Install NPM Assets

npm install helix-ui vendor-copy
  • vendor-copy allows you to automatically copy bundled assets to your project after npm install.

2. Configure package.json

2.1 - Modify package.json

Include the following configurations:

{
  "scripts": {
    "postinstall": "vendor-copy"
  },
  "vendorCopy": [
    {
      "from": "node_modules/helix-ui/node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js",
      "to": "public/vendor/webcomponents-loader.js"
    },
    {
      "from": "node_modules/helix-ui/node_modules/@webcomponents/webcomponentsjs/bundles",
      "to": "public/vendor/bundles"
    }
  ]
}
2.2 - Copy Vendor Assets

Run the following to copy files configured via the vendorCopy configuration, above.

npx vendor-copy

NOTE: You may also want to verify that your postinstall script is working as expected, by running npm install.

3. Consuming Assets in your App

3.1 - Modify public/index.html

Add the following to the bottom of the <head> element:

<!-- Required for HelixUI to function in older browsers -->
<script src="%PUBLIC_URL%/vendor/webcomponents-loader.js"></script>
3.2 - Modify your src/index.js to bring in HelixUI assets.
/* ... */

import 'helix-ui/dist/css/helix-ui.min.css';
import HelixUI from 'helix-ui';

/* ... */

HelixUI.initialize().then(() => {
  ReactDOM.render(/* ... */);
});

/* ... */

Compatibility

  • TODO: Using ref to attach event listeners
  • Warning: React's synthetic events violate non-bubbling specifications.

React Component Lifecycle

All HTMLElement (custom element) lifecycle methods are executed in 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()

React 15

React 15 is not supported by HelixUI.

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>

Resources

⚠️ **GitHub.com Fallback** ⚠️