Custom Layouts - HelixDesignSystem/helix-ui GitHub Wiki

TODO: move to "Guides > Custom Layouts" in component explorer

Audience
Consumers

WARNING: Building custom layouts should be the exception, not the norm.

  • If you think that HelixUI is missing a useful layout, please reach out to us in the #helix channel on Slack.
  • Please reference the Layouts Component for more information about supported layouts.

TL;DR

If you're not interested in the detailed explanations below, copy and paste this code snippet into your application's index page.

<!DOCTYPE html>
<html lang="en">
  <head>
    <!-- Head stuff goes here -->

    <link rel="stylesheet" href="node_modules/helix-ui/dist/styles/helix-ui.css" />

    <script src="node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script>
    <!-- polyfills injected here (if needed) -->
  </head>
  <body>
    <!-- Application markup goes here -->

    <!-- FIXME: point to HelixUI polyfills in node_modules/helix-ui -->
    <script src="node_modules/helix-ui/dist/scripts/helix-ui.polyfills.min.js"></script>

    <!-- intelligently load ES5 Adapter (if needed) -->
    <span id="ce-es5-adapter">
      <script>
        if (!window.customElements) {
          var elAdapter = document.querySelector('#ce-es5-adapter');
          elAdapter.parentElement.removeChild(elAdapter);
        }
      </script>
      <script src="node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
    </span>

    <script src="node_modules/helix-ui/dist/helix-ui.browser.js"></script>

    <!-- FIXME: Update with the correct path to your application behavior -->
    <script src="path/to/your/app.js"></script>
  </body>
</html>

Polyfills

HelixUI requires two polyfills to ensure maximum browser compatibility.

1. Base Polyfills

There are two options for base browser polyfills.

  1. polyfill.io (being phased out)
  2. helix-ui.polyfills

Load your chosen script before HelixUI and any application logic.

<body>
  ...

  <script src="path/to/chosen/polyfill/strategy.js"></script>

  <!-- HelixUI custom element definitions go here -->

  <!-- Application logic goes here -->
</body>

1.1 polyfill.io

NOTE: This requirement is being phased out for a set of custom-curated polyfills being shipped with HelixUI.

The first polyfill is an online service that uses browser detection to serve the smallest set of polyfills needed to accommodate missing functionality (polyfill.io). The drawback to this service is that it is not aware of the polyfills required by HelixUI or your application, so it loads every polyfill it knows for the useragent.

1.2 helix-ui.polyfills

The usage of polyfill.io is being deprecated in favor of an internally-maintained set of polyfills to reduce the risk of external points of failure and to reduce unnecessary file size.

  • helix-ui.polyfills are available as of v0.6.1, but they are not currently required
  • helix-ui.polyfills will replace polyfill.io in a future release
  • helix-ui.polyfills only include polyfills needed by the HelixUI toolkit
    • Polyfills for your own app will be up to you.

The new polyfills are available in two flavors:

  • dist/scripts/helix-ui.polyfills.js
  • dist/scripts/helix-ui.polyfills.min.js

2. webcomponentsjs

The second polyfill uses two scripts to add support for the following functionality:

  • Custom Elements registry (window.customElements)
  • HTML imports
  • ShadowDOM (Element.prototype.attachShadow())
  • HTML Templates (HTMLTemplateElement)
  • Promise
  • Event(), CustomEvent(), MouseEvent() constructors
  • Object.assign(), Array.from()

Web Components Polyfill Loader

NOTE: Currently, the loader only supports being loaded in the <head> of an HTML document.

The loader performs feature detection on the current browser to dynamically inject the smallest polyfill needed to patch missing browser functionality. Any polyfill added this way will be inserted at the end of the document <head>.

<head>
  ...

  <script src="node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script>
  <!-- polyfills injected here (if needed) -->
</head>

Once the polyfills are loaded, the "WebComponentsReady" event fires on the document object to announce the availability of Web Component functionality.

Custom Elements ES5 Adapter

The Custom Elements v1 spec requires that constructor classes be defined using ES6 class syntax. The ES6 class syntax requirement can be problematic, though. To support legacy browsers such as Internet Explorer that do not support ES6, HelixUI is compiled to ES5 syntax.

The ES5 Adapter corrects the problem by converting ES5 classes to ES6 syntax so that modern browsers can load custom element definitions. Because the adapter is written in a clever mix of ES5 and ES6 syntax, it raises an exception in browsers that do not support ES6 (i.e., Internet Explorer).

To avoid the exception, use the following strategy to wrap the injection of the ES5 adapter in an element that can be dynamically removed if it isn't needed.

<body>
  ...

  <!-- intelligently load ES5 Adapter (if needed) -->
  <span id="ce-es5-adapter">
    <script>
      if (!window.customElements) {
        var elAdapter = document.querySelector('#ce-es5-adapter');
        elAdapter.parentElement.removeChild(elAdapter);
      }
    </script>
    <script src="node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
  </span>

  ...
</body>
⚠️ **GitHub.com Fallback** ⚠️