Upgrade to Pro — share decks privately, control downloads, hide ads and more …

RuhrJS '18 - 2018 - The Year of Web Components

RuhrJS '18 - 2018 - The Year of Web Components

Components are hot. Every view library or framework seems to be based on components these days. But when you write your React component you can't share it with an Angular developer. Your Vue components can't be used in Preact. The result: fragmentation. The cost: reinventing the wheel for every library.

We've had the answer for years, though. Web components are the standards based solution, but they've never seemed ready for the big time. Until now.

In this talk we'll look at why 2018 is finally the year of web components, the tools and libraries that we can use to build with web components and how you can get started building shareable, compatible, standards based components.

Dominik Kundel

October 13, 2018
Tweet

More Decks by Dominik Kundel

Other Decks in Programming

Transcript

  1. Dominik Kundel | @dkundel | #ruhrjs | #webComponents #useThePlatform The

    Dream <date-picker> </date-picker> <video> </video> <input type="text" />
  2. Dominik Kundel | @dkundel | #ruhrjs | console.log(` Hi! I’m

    Dominik Kundel `); dkundel.com @dkundel [email protected] github/dkundel Developer Evangelist && JavaScript Hacker #webComponents #useThePlatform
  3. Dominik Kundel | @dkundel | #ruhrjs | #webComponents #useThePlatform Approach

    1: “Bootstrap” approach <!-- Bootstrap CSS --> <link rel="stylesheet" href="https: //maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> <!-- Optional JavaScript --> <!-- jQuery first, then Popper.js, then Bootstrap JS --> <script src="https: //code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"> </script> <script src="https: //cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"> </script> <script src="https: //maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"> </script>
  4. Dominik Kundel | @dkundel | #ruhrjs | #webComponents #useThePlatform Approach

    1: “Bootstrap” approach <div class="alert alert-success" role="alert"> <h4 class="alert-heading">Well done! </h4> <p>Aww yeah, you successfully read this important alert message </p> <hr> <p class="mb-0"> Whenever you need to, be sure to use margin utilities to keep things nice and tidy. </p> </div>
  5. Dominik Kundel | @dkundel | #ruhrjs | #webComponents #useThePlatform Approach

    2: JavaScript API <div id="map"> </div> <script> var map; function initMap() { map = new google.maps.Map(document.getElementById('map'), { center: {lat: -34.397, lng: 150.644}, zoom: 8 }); } </script> <script src="https: //maps.googleapis.com/maps/api/js? key=YOUR_API_KEY&callback=initMap" async defer> </script>
  6. Dominik Kundel | @dkundel | #ruhrjs | #webComponents #useThePlatform Approach

    3: “Share button” style <div id="fb-root"> </div> <script>(function(d, s, id) { var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id)) return; js = d.createElement(s); js.id = id; js.src = 'https: //connect.facebook.net/en_US/ sdk.js#xfbml=1&version=v2.12&appId=APP_ID&autoLogAppEvents=1'; fjs.parentNode.insertBefore(js, fjs); }(document, 'script', 'facebook-jssdk')); </script>
  7. Dominik Kundel | @dkundel | #ruhrjs | #webComponents #useThePlatform Approach

    3: “Share button” style <div class="fb-share-button" data-href="https: //developers.facebook.com/docs/plugins/" data-layout="button_count" data-size="small" data-mobile-iframe="true"> <a target="_blank" href="https: // www.facebook.com/sharer/sharer.php? u=https%3A%2F%2Fdevelopers.facebook.com%2Fdocs%2Fplugins%2F&amp;src=sdkpreparse" class="fb-xfbml-parse-ignore">Share </a> </div>
  8. Dominik Kundel | @dkundel | #ruhrjs | #webComponents #useThePlatform Custom

    Elements Definition class DatePicker extends HTMLElement { constructor() { super(); // ... } } customElements.define('date-picker', DatePicker);
  9. Dominik Kundel | @dkundel | #ruhrjs | #webComponents #useThePlatform Custom

    Elements Definition class DatePicker extends HTMLInputElement { constructor() { super(); // ... } } customElements.define( 'date-picker', DatePicker, { extends: 'input' } );
  10. Dominik Kundel | @dkundel | #ruhrjs | #webComponents #useThePlatform Custom

    Elements Usage <!-- normal custom element --> <date-picker> </date-picker> <!-- extended custom element --> <input is="date-picker" /> ``` // via JavaScript document.createElement('date-picker'); document.createElement('input', { is: 'date-picker' });
  11. Dominik Kundel | @dkundel | #ruhrjs | #webComponents #useThePlatform Custom

    Elements Attributes • Allows you to pass information to the component • Only supports “simple” data <date-picker value="5" disabled> </date-picker>
  12. Dominik Kundel | @dkundel | #ruhrjs | #webComponents #useThePlatform Custom

    Elements Properties • Access via JavaScript • Typically reflected back into attributes but doesn't have to • Supports complex data (arrays, objects, etc.) const el = document.querySelector('date-picker'); el.value = 99; el.disabled = false; el.range = ['2018-01-01', '2019-01-01'];
  13. Dominik Kundel | @dkundel | #ruhrjs | #webComponents #useThePlatform Custom

    Elements Properties class DatePicker extends HTMLElement { // ... get disabled() { return this.hasAttribute('disabled'); } set disabled(val) { // Reflect the value of `disabled` as an attribute. if (val) { this.setAttribute('disabled', ''); } else { this.removeAttribute('disabled'); } } // ... }
  14. Dominik Kundel | @dkundel | #ruhrjs | #webComponents #useThePlatform HTML

    Templates <template id="date-picker-template"> <style> /* ... */ </style> <div> <!-- some markup --> </div> <slot> </slot> <div> <!-- more markup --> </div> </template> const tmpl = document.querySelector('#date-picker-template'); tmpl.content.cloneNode( /*deep: */ true)
  15. Dominik Kundel | @dkundel | #ruhrjs | #webComponents #useThePlatform Shadow

    DOM class DatePicker extends HTMLElement { constructor() { super(); const shadowRoot = this.attachShadow({mode: 'open'}); shadowRoot.appendChild(tmpl.content.cloneNode(true)); } }
  16. Dominik Kundel | @dkundel | #ruhrjs | #webComponents #useThePlatform Shadow

    DOM <date-picker><p>I appear in the slot </p> </date-picker> <date-picker> #shadow-root <style> /* "global" styles are limited to this root */ </style> <div> <!-- some markup --> </div> <slot> <!-- paragraph appears here --> </slot> <div> <!-- more markup --> </div> </date-picker>
  17. Dominik Kundel | @dkundel | #ruhrjs | #webComponents #useThePlatform Example

    2: web-share-wrapper <web-share-wrapper text="Share this" sharetitle="This amazing thing was shared" sharetext="You should really click on the link to learn more" shareurl="http: //example.com/amazing" > <a href="https: //twitter.com/intent/tweet?text=Share+Text&amp;url=SHARE_URL"> Share on Twitter </a> </web-share-wrapper>
  18. Dominik Kundel | @dkundel | #ruhrjs | #webComponents #useThePlatform Extensible

    Web Manifesto • The standards process should focus on adding new low-level capabilities to the web platform that are secure and efficient • The web platform should expose low-level capabilities that explain existing features, such as HTML and CSS, allowing authors to understand and replicate them.
  19. Dominik Kundel | @dkundel | #ruhrjs | #webComponents #useThePlatform How

    The Web Sausage Gets Made by Monica Dinculescu (@notwaldorf) youtube.com/watch?v=326SIMmRjc8
  20. Dominik Kundel | @dkundel | #ruhrjs | #webComponents #useThePlatform About

    LitElement • Written by the Polymer Team • “A simple base class for creating custom elements rendered with lit-html” • Uses web standards (no compilation)* • lit-html is powered by HTML templates *Except module bundling https: //github.com/Polymer/lit-element
  21. Dominik Kundel | @dkundel | #ruhrjs | #webComponents #useThePlatform Stencil

    • Stencil was written by the Ionic Team • “compiler that generates web components” • Built to bring Ionic to more frameworks than Angular • Inspired by Angular, React and others • Uses TypeScript, decorators, and JSX https: //stenciljs.com
  22. Dominik Kundel | @dkundel | #ruhrjs | #webComponents #useThePlatform Web

    Components won’t limit your framework choices
  23. Dominik Kundel | @dkundel | #ruhrjs | #webComponents #useThePlatform Resources

    • d-k.im/webcomp-stencil • d-k.im/ruhrjs • github.com/dkundel/emoji-rating • webcomponents.org • ✅ custom-elements-everywhere.com • github.com/shprink/web-components-todo