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

SinnerSchrader Tech Session '18 - 2018 - The Year of Web Components

SinnerSchrader Tech Session '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 11, 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 | #s2techsession #webComponents #useThePlatform
  2. Hi! I'm Dominik Kundel! Developer Evangelist at ! dkundel.com "

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

    Kundel | @dkundel | #s2techsession #webComponents #useThePlatform
  4. Approach ! The "Bootstrap" approach Dominik Kundel | @dkundel |

    #s2techsession #webComponents #useThePlatform
  5. 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 | #s2techsession #webComponents #useThePlatform
  6. 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 | #s2techsession #webComponents #useThePlatform
  7. Approach ! The JavaScript API Dominik Kundel | @dkundel |

    #s2techsession #webComponents #useThePlatform
  8. 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 | #s2techsession #webComponents #useThePlatform
  9. Approach ! "Share button" style Dominik Kundel | @dkundel |

    #s2techsession #webComponents #useThePlatform
  10. 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 | #s2techsession #webComponents #useThePlatform
  11. 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 | #s2techsession #webComponents #useThePlatform
  12. ! What if we could extend HTMLElement Dominik Kundel |

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

    #s2techsession #webComponents #useThePlatform
  14. Spec No. ! ! Custom Elements Dominik Kundel | @dkundel

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

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

    { super(); // ... } } customElements.define('date-picker', DatePicker, { extends: 'input' }); Dominik Kundel | @dkundel | #s2techsession #webComponents #useThePlatform
  17. ! 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 | #s2techsession #webComponents #useThePlatform
  18. ! 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 | #s2techsession #webComponents #useThePlatform
  19. ! 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 | #s2techsession #webComponents #useThePlatform
  20. ! 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 | #s2techsession #webComponents #useThePlatform
  21. Spec No. ! ! HTML Templates Dominik Kundel | @dkundel

    | #s2techsession #webComponents #useThePlatform
  22. ! 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 | #s2techsession #webComponents #useThePlatform
  23. Spec No. ! ! Shadow DOM Dominik Kundel | @dkundel

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

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

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

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

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

    | #s2techsession #webComponents #useThePlatform
  30. ! You develop a UI component Dominik Kundel | @dkundel

    | #s2techsession #webComponents #useThePlatform
  31. ! Same tools for everyone Dominik Kundel | @dkundel |

    #s2techsession #webComponents #useThePlatform
  32. ! Example 1 WebVR with a-frame ! glitch.com/~aframe-basic-guide Dominik Kundel

    | @dkundel | #s2techsession #webComponents #useThePlatform
  33. ! Example 2 Progressive Enhancement ! web-share-wrapper by Phil Nash

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

    #s2techsession #webComponents #useThePlatform
  36. ! 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 | #s2techsession #webComponents #useThePlatform
  37. ! " How The Web Sausage Gets Made by Monica

    Dinculescu (@notwaldorf) youtube.com/watch?v=326SIMmRjc8 Dominik Kundel | @dkundel | #s2techsession #webComponents #useThePlatform
  38. ! Tooling Now (a few...) Dominik Kundel | @dkundel |

    #s2techsession #webComponents #useThePlatform
  39. Pick Your Favorite... ! and Let Others Pick Theirs! !

    Dominik Kundel | @dkundel | #s2techsession #webComponents #useThePlatform
  40. ! Let's build: the last datepicker Dominik Kundel | @dkundel

    | #s2techsession #webComponents #useThePlatform
  41. ! Let's build: the last datepicker a rating component Dominik

    Kundel | @dkundel | #s2techsession #webComponents #useThePlatform
  42. ⚒ Our tool of choice: LitElement Dominik Kundel | @dkundel

    | #s2techsession #webComponents #useThePlatform
  43. ⚒ 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 | #s2techsession #webComponents #useThePlatform
  44. ! 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 | #s2techsession #webComponents #useThePlatform
  45. ! Let's use a web component! Dominik Kundel | @dkundel

    | #s2techsession #webComponents #useThePlatform
  46. ! Let's wrap it up! Dominik Kundel | @dkundel |

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

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

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

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

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

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

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

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