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

NDC Oslo 2018 - The Year of Web Components

NDC Oslo 2018 - The Year of Web Components

This talk has been given at NDC Oslo in 2018 going into the future of web components and how to get started with it.

Dominik Kundel

June 14, 2018
Tweet

More Decks by Dominik Kundel

Other Decks in Programming

Transcript

  1. ! The dream <date-picker> </date-picker> <video> </video> <input type="text" />

    Dominik Kundel | @dkundel | #webComponents #useThePlatform
  2. Hi! I'm Dominik Kundel! Developer Evangelist at ! dkundel.com "

    @dkundel # [email protected] $ github/dkundel Dominik Kundel | @dkundel | #webComponents #useThePlatform
  3. ! " How do you share UI between projects? Dominik

    Kundel | @dkundel | #webComponents #useThePlatform
  4. 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> Dominik Kundel | @dkundel | #webComponents #useThePlatform
  5. 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> Dominik Kundel | @dkundel | #webComponents #useThePlatform
  6. 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> Dominik Kundel | @dkundel | #webComponents #useThePlatform
  7. 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> Dominik Kundel | @dkundel | #webComponents #useThePlatform
  8. 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> Dominik Kundel | @dkundel | #webComponents #useThePlatform
  9. ! What if we could extend HTMLElement Dominik Kundel |

    @dkundel | #webComponents #useThePlatform
  10. ! ! ! Web Components Dominik Kundel | @dkundel |

    #webComponents #useThePlatform
  11. ! Custom Elements Definition class DatePicker extends HTMLElement { constructor()

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

    { super(); // ... } } customElements.define('date-picker', DatePicker, { extends: 'input' }); Dominik Kundel | @dkundel | #webComponents #useThePlatform
  13. ! 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' }); Dominik Kundel | @dkundel | #webComponents #useThePlatform
  14. ! Custom Elements Attributes <date-picker value="5" disabled> </date-picker> • Allows

    you to pass information to the component • Only supports "simple" data Dominik Kundel | @dkundel | #webComponents #useThePlatform
  15. ! Custom Elements Properties const el = document.querySelector('date-picker'); el.value =

    99; el.disabled = false; el.range = ['2018-01-01', '2019-01-01']; • Access via JavaScript • Typically reflected back into attributes but doesn't have to • Supports complex data (arrays, objects, etc.) Dominik Kundel | @dkundel | #webComponents #useThePlatform
  16. ! 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'); } } // ... } Dominik Kundel | @dkundel | #webComponents #useThePlatform
  17. ! 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) Dominik Kundel | @dkundel | #webComponents #useThePlatform
  18. Spec No. ! ! Shadow DOM Dominik Kundel | @dkundel

    | #webComponents #useThePlatform
  19. ! Shadow DOM class DatePicker extends HTMLElement { constructor() {

    super(); const shadowRoot = this.attachShadow({mode: 'open'}); shadowRoot.appendChild(tmpl.content.cloneNode(true)); } } Dominik Kundel | @dkundel | #webComponents #useThePlatform
  20. ! 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> Dominik Kundel | @dkundel | #webComponents #useThePlatform
  21. Spec No. ! ! HTML Imports Dominik Kundel | @dkundel

    | #webComponents #useThePlatform
  22. Spec No. ! !" HTML Imports Dominik Kundel | @dkundel

    | #webComponents #useThePlatform
  23. ✅ Support is there* * with Polyfills Dominik Kundel |

    @dkundel | #webComponents #useThePlatform
  24. ! " Why do I care? Dominik Kundel | @dkundel

    | #webComponents #useThePlatform
  25. ! Example 2 Progressive Enhancement ! web-share-wrapper by Phil Nash

    Dominik Kundel | @dkundel | #webComponents #useThePlatform
  26. ! 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> Dominik Kundel | @dkundel | #webComponents #useThePlatform
  27. ! Why not earlier? " Dominik Kundel | @dkundel |

    #webComponents #useThePlatform
  28. ! 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. Dominik Kundel | @dkundel | #webComponents #useThePlatform
  29. ! " How The Web Sausage Gets Made by Monica

    Dinculescu (@notwaldorf) youtube.com/watch?v=326SIMmRjc8 Dominik Kundel | @dkundel | #webComponents #useThePlatform
  30. Pick Your Favorite... ! and Let Others Pick Theirs! !

    Dominik Kundel | @dkundel | #webComponents #useThePlatform
  31. ! Let's build: the last datepicker a rating component Dominik

    Kundel | @dkundel | #webComponents #useThePlatform
  32. ⚒ 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 • ! https://github.com/Polymer/lit-element * Except module bundling Dominik Kundel | @dkundel | #webComponents #useThePlatform
  33. ! What about 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 • ! stenciljs.com Dominik Kundel | @dkundel | #webComponents #useThePlatform
  34. ! Let's wrap it up! Dominik Kundel | @dkundel |

    #webComponents #useThePlatform
  35. Think about Web Components for any shared UI Dominik Kundel

    | @dkundel | #webComponents #useThePlatform
  36. Web Components won't limit your framework choices Dominik Kundel |

    @dkundel | #webComponents #useThePlatform
  37. Pick Your Favorite... ! and Let Others Pick Theirs! !

    Dominik Kundel | @dkundel | #webComponents #useThePlatform
  38. ! One datepicker to rule !em a" ! Dominik Kundel

    | @dkundel | #webComponents #useThePlatform
  39. Resources • ! d-k.im/webcomp-stencil • " d-k.im/webcomp-ndcoslo • #$ github.com/dkundel/emoji-rating

    • webcomponents.org • ✅ custom-elements-everywhere.com • & github.com/shprink/web-components-todo Dominik Kundel | @dkundel | #webComponents #useThePlatform
  40. ! Let me know what you think! ! vote.dkundel.com Dominik

    Kundel | @dkundel | #webComponents #useThePlatform
  41. Thank You! ! Dominik Kundel " vote.dkundel.com # d-k.im/webcomp-ndcoslo $

    @dkundel % [email protected] & github/dkundel Dominik Kundel | @dkundel | #webComponents #useThePlatform