Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.

Creating lightweight JS Apps w/ Web Components and lit-html

861 Aufrufe

Veröffentlicht am

What are Web Components and why should we use them, Pros and Cons. What is lit-html and how it helps us develop lightweight JavaScript Apps.

Veröffentlicht in: Technologie
  • ⇒ www.HelpWriting.net ⇐ is a good website if you’re looking to get your essay written for you. You can also request things like research papers or dissertations. It’s really convenient and helpful.
       Antworten 
    Sind Sie sicher, dass Sie …  Ja  Nein
    Ihre Nachricht erscheint hier
  • DOWNLOAD THE BOOK INTO AVAILABLE FORMAT (New Update) ......................................................................................................................... ......................................................................................................................... Download Full PDF EBOOK here { https://urlzs.com/UABbn } ......................................................................................................................... Download Full EPUB Ebook here { https://urlzs.com/UABbn } ......................................................................................................................... Download Full doc Ebook here { https://urlzs.com/UABbn } ......................................................................................................................... Download PDF EBOOK here { https://urlzs.com/UABbn } ......................................................................................................................... Download EPUB Ebook here { https://urlzs.com/UABbn } ......................................................................................................................... Download doc Ebook here { https://urlzs.com/UABbn } ......................................................................................................................... ......................................................................................................................... ................................................................................................................................... eBook is an electronic version of a traditional print book THE can be read by using a personal computer or by using an eBook reader. (An eBook reader can be a software application for use on a computer such as Microsoft's free Reader application, or a book-sized computer THE is used solely as a reading device such as Nuvomedia's Rocket eBook.) Users can purchase an eBook on diskette or CD, but the most popular method of getting an eBook is to purchase a downloadable file of the eBook (or other reading material) from a Web site (such as Barnes and Noble) to be read from the user's computer or reading device. Generally, an eBook can be downloaded in five minutes or less ......................................................................................................................... .............. Browse by Genre Available eBOOK .............................................................................................................................. Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, CookBOOK, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult, Crime, EBOOK, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, ......................................................................................................................... ......................................................................................................................... .....BEST SELLER FOR EBOOK RECOMMEND............................................................. ......................................................................................................................... Blowout: Corrupted Democracy, Rogue State Russia, and the Richest, Most Destructive Industry on Earth,-- The Ride of a Lifetime: Lessons Learned from 15 Years as CEO of the Walt Disney Company,-- Call Sign Chaos: Learning to Lead,-- StrengthsFinder 2.0,-- Stillness Is the Key,-- She Said: Breaking the Sexual Harassment Story THE Helped Ignite a Movement,-- Atomic Habits: An Easy & Proven Way to Build Good Habits & Break Bad Ones,-- Everything Is Figureoutable,-- What It Takes: Lessons in the Pursuit of Excellence,-- Rich Dad Poor Dad: What the Rich Teach Their Kids About Money THE the Poor and Middle Class Do Not!,-- The Total Money Makeover: Classic Edition: A Proven Plan for Financial Fitness,-- Shut Up and Listen!: Hard Business Truths THE Will Help You Succeed, ......................................................................................................................... .........................................................................................................................
       Antworten 
    Sind Sie sicher, dass Sie …  Ja  Nein
    Ihre Nachricht erscheint hier
  • DOWNLOAD THE BOOK INTO AVAILABLE FORMAT (New Update) ......................................................................................................................... ......................................................................................................................... Download Full PDF EBOOK here { https://urlzs.com/UABbn } ......................................................................................................................... Download Full EPUB Ebook here { https://urlzs.com/UABbn } ......................................................................................................................... Download Full doc Ebook here { https://urlzs.com/UABbn } ......................................................................................................................... Download PDF EBOOK here { https://urlzs.com/UABbn } ......................................................................................................................... Download EPUB Ebook here { https://urlzs.com/UABbn } ......................................................................................................................... Download doc Ebook here { https://urlzs.com/UABbn } ......................................................................................................................... ......................................................................................................................... ................................................................................................................................... eBook is an electronic version of a traditional print book THE can be read by using a personal computer or by using an eBook reader. (An eBook reader can be a software application for use on a computer such as Microsoft's free Reader application, or a book-sized computer THE is used solely as a reading device such as Nuvomedia's Rocket eBook.) Users can purchase an eBook on diskette or CD, but the most popular method of getting an eBook is to purchase a downloadable file of the eBook (or other reading material) from a Web site (such as Barnes and Noble) to be read from the user's computer or reading device. Generally, an eBook can be downloaded in five minutes or less ......................................................................................................................... .............. Browse by Genre Available eBOOK .............................................................................................................................. Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, CookBOOK, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult, Crime, EBOOK, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, ......................................................................................................................... ......................................................................................................................... .....BEST SELLER FOR EBOOK RECOMMEND............................................................. ......................................................................................................................... Blowout: Corrupted Democracy, Rogue State Russia, and the Richest, Most Destructive Industry on Earth,-- The Ride of a Lifetime: Lessons Learned from 15 Years as CEO of the Walt Disney Company,-- Call Sign Chaos: Learning to Lead,-- StrengthsFinder 2.0,-- Stillness Is the Key,-- She Said: Breaking the Sexual Harassment Story THE Helped Ignite a Movement,-- Atomic Habits: An Easy & Proven Way to Build Good Habits & Break Bad Ones,-- Everything Is Figureoutable,-- What It Takes: Lessons in the Pursuit of Excellence,-- Rich Dad Poor Dad: What the Rich Teach Their Kids About Money THE the Poor and Middle Class Do Not!,-- The Total Money Makeover: Classic Edition: A Proven Plan for Financial Fitness,-- Shut Up and Listen!: Hard Business Truths THE Will Help You Succeed, ......................................................................................................................... .........................................................................................................................
       Antworten 
    Sind Sie sicher, dass Sie …  Ja  Nein
    Ihre Nachricht erscheint hier
  • DOWNLOAD THE BOOK INTO AVAILABLE FORMAT (New Update) ......................................................................................................................... ......................................................................................................................... Download Full PDF EBOOK here { https://soo.gd/irt2 } ......................................................................................................................... Download Full EPUB Ebook here { https://soo.gd/irt2 } ......................................................................................................................... Download Full doc Ebook here { https://soo.gd/irt2 } ......................................................................................................................... Download PDF EBOOK here { https://soo.gd/irt2 } ......................................................................................................................... Download EPUB Ebook here { https://soo.gd/irt2 } ......................................................................................................................... Download doc Ebook here { https://soo.gd/irt2 } ......................................................................................................................... ......................................................................................................................... ................................................................................................................................... eBook is an electronic version of a traditional print book THE can be read by using a personal computer or by using an eBook reader. (An eBook reader can be a software application for use on a computer such as Microsoft's free Reader application, or a book-sized computer THE is used solely as a reading device such as Nuvomedia's Rocket eBook.) Users can purchase an eBook on diskette or CD, but the most popular method of getting an eBook is to purchase a downloadable file of the eBook (or other reading material) from a Web site (such as Barnes and Noble) to be read from the user's computer or reading device. Generally, an eBook can be downloaded in five minutes or less ......................................................................................................................... .............. Browse by Genre Available eBOOK .............................................................................................................................. Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, CookBOOK, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult, Crime, EBOOK, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, ......................................................................................................................... ......................................................................................................................... .....BEST SELLER FOR EBOOK RECOMMEND............................................................. ......................................................................................................................... Blowout: Corrupted Democracy, Rogue State Russia, and the Richest, Most Destructive Industry on Earth,-- The Ride of a Lifetime: Lessons Learned from 15 Years as CEO of the Walt Disney Company,-- Call Sign Chaos: Learning to Lead,-- StrengthsFinder 2.0,-- Stillness Is the Key,-- She Said: Breaking the Sexual Harassment Story THE Helped Ignite a Movement,-- Atomic Habits: An Easy & Proven Way to Build Good Habits & Break Bad Ones,-- Everything Is Figureoutable,-- What It Takes: Lessons in the Pursuit of Excellence,-- Rich Dad Poor Dad: What the Rich Teach Their Kids About Money THE the Poor and Middle Class Do Not!,-- The Total Money Makeover: Classic Edition: A Proven Plan for Financial Fitness,-- Shut Up and Listen!: Hard Business Truths THE Will Help You Succeed, ......................................................................................................................... .........................................................................................................................
       Antworten 
    Sind Sie sicher, dass Sie …  Ja  Nein
    Ihre Nachricht erscheint hier
  • DOWNLOAD THIS BOOKS INTO AVAILABLE FORMAT (2019 Update) ......................................................................................................................... ......................................................................................................................... Download Full PDF EBOOK here { https://soo.gd/irt2 } ......................................................................................................................... Download Full EPUB Ebook here { https://soo.gd/irt2 } ......................................................................................................................... Download Full doc Ebook here { https://soo.gd/irt2 } ......................................................................................................................... Download PDF EBOOK here { https://soo.gd/irt2 } ......................................................................................................................... Download EPUB Ebook here { https://soo.gd/irt2 } ......................................................................................................................... Download doc Ebook here { https://soo.gd/irt2 } ......................................................................................................................... ......................................................................................................................... ................................................................................................................................... eBook is an electronic version of a traditional print book THIS can be read by using a personal computer or by using an eBook reader. (An eBook reader can be a software application for use on a computer such as Microsoft's free Reader application, or a book-sized computer THIS is used solely as a reading device such as Nuvomedia's Rocket eBook.) Users can purchase an eBook on diskette or CD, but the most popular method of getting an eBook is to purchase a downloadable file of the eBook (or other reading material) from a Web site (such as Barnes and Noble) to be read from the user's computer or reading device. Generally, an eBook can be downloaded in five minutes or less ......................................................................................................................... .............. Browse by Genre Available eBooks .............................................................................................................................. Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, Cookbooks, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, ......................................................................................................................... ......................................................................................................................... .....BEST SELLER FOR EBOOK RECOMMEND............................................................. ......................................................................................................................... Blowout: Corrupted Democracy, Rogue State Russia, and the Richest, Most Destructive Industry on Earth,-- The Ride of a Lifetime: Lessons Learned from 15 Years as CEO of the Walt Disney Company,-- Call Sign Chaos: Learning to Lead,-- StrengthsFinder 2.0,-- Stillness Is the Key,-- She Said: Breaking the Sexual Harassment Story THIS Helped Ignite a Movement,-- Atomic Habits: An Easy & Proven Way to Build Good Habits & Break Bad Ones,-- Everything Is Figureoutable,-- What It Takes: Lessons in the Pursuit of Excellence,-- Rich Dad Poor Dad: What the Rich Teach Their Kids About Money THIS the Poor and Middle Class Do Not!,-- The Total Money Makeover: Classic Edition: A Proven Plan for Financial Fitness,-- Shut Up and Listen!: Hard Business Truths THIS Will Help You Succeed, ......................................................................................................................... .........................................................................................................................
       Antworten 
    Sind Sie sicher, dass Sie …  Ja  Nein
    Ihre Nachricht erscheint hier

Creating lightweight JS Apps w/ Web Components and lit-html

  1. 1. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML 🔥-HTML+
  2. 2. A B O U T M E { "name": "Ilia Idakiev", "experience": [ “Google Developer Expert (GDE)“, "Developer & Co-founder @ HILLGRAND", "Lecturer in 'Advanced JS' @ Sofia University", "Contractor / Consultant", "Public / Private Courses” ], "involvedIn": [ "Angular Sofia", "SofiaJS / BeerJS", ] }
  3. 3. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML SEPARATION OF CONCERNS (SOC) ▸ Design principle for separating a computer program into distinct sections, such that each section addresses a separate concern. (Modularity)
  4. 4. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML S.O.L.I.D PRINCIPLES OF OBJECT-ORIENTED PROGRAMMING ▸ Single Responsibility Principle ▸ Open / Close Principle ▸ Liskov Substitution Principle ▸ Interface Segregation Principle ▸ Dependency Inversion Principle http://aspiringcraftsman.com/2011/12/08/solid-javascript-single-responsibility-principle/
  5. 5. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML WEB COMPONENTS ▸ Introduced by Alex Russell (Chrome team @ Google) 
 at Fronteers Conference 2011 ▸ A set of features currently being added by the W3C to the HTML and DOM specifications that allow the creation of reusable widgets or components in web documents and web applications. ▸ The intention behind them is to bring component-based software engineering to the World Wide Web.
  6. 6. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML WEB COMPONENTS FEATURES: ▸ HTML Templates - an HTML fragment is not rendered, but stored until it is instantiated via JavaScript. ▸ Shadow DOM - Encapsulated DOM and styling, with composition. ▸ Custom Elements - APIs to define new HTML elements. ▸ HTML Imports - Declarative methods of importing HTML documents into other documents. (Replaced by ES6 Imports).
  7. 7. DEMOTHE NATIVE WAY
  8. 8. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML DEFINE CUSTOM ELEMENT (function () { }()); Create an isolated scope counter.js
  9. 9. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML (function () { class Counter extends HTMLElement { } }()); DEFINE CUSTOM ELEMENT Create a new class that extends HTMLElement counter.js
  10. 10. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML (function () { class Counter extends HTMLElement { } customElements.define('hg-counter', Counter); }()); DEFINE CUSTOM ELEMENT Register the new custom element. counter.js
  11. 11. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML HTML TEMPLATES ▸ The <template> tag holds its content hidden from the client. ▸ Content inside a <template> tag will be parsed but not rendered. ▸ The content can be visible and rendered later by using JavaScript.
  12. 12. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML WAYS TO CREATE A TEMPLATE <template id="template"> <h2>Hello World</h2> </template> const template = document.createElement('template'); template.innerHTML = '<h2>Hello World</h2>'; Using HTML Using JavaScript
  13. 13. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML CREATE TEMPLATE HELPER FUNCTION function createTemplate(string) { const template = document.createElement('template'); template.innerHTML = string; return template; } utils.js
  14. 14. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML CREATE THE TEMPLATE (function () { const template = createTemplate('<div>Hello World<div>'); class Counter extends HTMLElement { } customElements.define('hg-counter', Counter); }()); Use the create template helper function. counter.js
  15. 15. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML SHADOW DOM ▸ Isolated DOM - The component's DOM is self-contained (e.g. document.querySelector() won't return nodes in the component's shadow DOM). ▸ Scoped CSS - CSS defined inside shadow DOM is scoped to it. Style rules don't leak out and page styles don't bleed in. ▸ Composition - done with the <slot> element.
 (Slots are placeholders inside your component that users can fill with their own markup).
  16. 16. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML DEFINE CUSTOM ELEMENT (function () { const template = createTemplate('<div>Hello World<div>'); class Counter extends HTMLElement { constructor() { super(); } } customElements.define('hg-counter', Counter); }()); counter.js Utilise the class constructor.
  17. 17. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML ATTACH SHADOW DOM (function () { const template = createTemplate('<div>Hello World<div>'); class Counter extends HTMLElement { constructor() { super(); const shadowRoot = this.attachShadow({ mode: 'open' }); } } customElements.define('hg-counter', Counter); }()); Attach the shadow DOM. counter.js
  18. 18. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML (function () { const template = createTemplate('<div>Hello World<div>'); class Counter extends HTMLElement { constructor() { super(); const shadowRoot = this.attachShadow({ mode: 'open' }); shadowRoot.appendChild(template.content.cloneNode(true)); } } customElements.define('hg-counter', Counter); }()); CREATE THE TEMPLATE Attach the template contents to the shadow root. counter.js
  19. 19. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML USE OUR CUSTOM ELEMENT <body> <hg-counter></hg-counter> <script src="./util.js"></script> <script src="./counter.js"></script> </body> index.html
  20. 20. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML EXTEND OUR CUSTOM ELEMENT index.html (function () { const template = createTemplate(` <div name="value"></div> <button data-type=“dec">-</button> <button data-type="inc">+</button> `); class Counter extends HTMLElement { constructor() { super();
  21. 21. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML EXTEND OUR CUSTOM ELEMENT index.html constructor() { super(); const shadowRoot = this.attachShadow({ mode: 'open' }); shadowRoot.appendChild(template.content.cloneNode(true)); shadowRoot.addEventListener('click', ({ target }) => { const type = target.getAttribute('data-type'); if (type === 'dec') { this.counter--; } else if (type === 'inc') { this.counter++; } });
  22. 22. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML UPDATING THE DOM utils.js function updateDOM(root, updates) { updates.forEach(item => { root.querySelectorAll(`[name=${item.name}]`).forEach(element => element.textContent = item.value ); }); }
  23. 23. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML EXTEND OUR CUSTOM ELEMENT index.html class Counter extends HTMLElement { set counter(value) { this._counter = value; } get counter() { return this._counter; } constructor() { super(); const shadowRoot = this.attachShadow({ mode: 'open' }); shadowRoot.appendChild(template.content.cloneNode(true)); this.counter = 0;
  24. 24. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML EXTEND OUR CUSTOM ELEMENT index.html class Counter extends HTMLElement { constructor() { super(); const shadowRoot = this.attachShadow({ mode: 'open' }); shadowRoot.appendChild(template.content.cloneNode(true)); this.counter = 0; this._update = () => { updateDOM(shadowRoot, [{ name: 'value', value: this.counter }]); }
  25. 25. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML EXTEND OUR CUSTOM ELEMENT index.html class Counter extends HTMLElement { set counter(value) { this._counter = value; this._update(); } get counter() { return this._counter; } constructor() { super(); const shadowRoot = this.attachShadow({ mode: 'open' }); shadowRoot.appendChild(template.content.cloneNode(true)); this.counter = 0;
  26. 26. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML CUSTOM COMPONENT ATTRIBUTES index.html <body> <hg-counter value="10"></hg-counter> <script src="./util.js"></script> <script src="./counter.js"></script> </body>
  27. 27. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML CUSTOM ELEMENTS LIFECYCLE CALLBACKS ▸ connectedCallback - Invoked each time the custom element is appended into a document-connected element. This will happen each time the node is moved, and may happen before the element's contents have been fully parsed. ▸ disconnectedCallback - Invoked each time the custom element is disconnected from the document's DOM. ▸ attributeChangedCallback - Invoked each time one of the custom element's attributes is added, removed, or changed. ▸ adoptedCallback - Invoked each time the custom element is moved to a new document.
  28. 28. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML CUSTOM COMPONENT ATTRIBUTES index.html class Counter extends HTMLElement { attributeChangedCallback(name, oldValue, newValue) { if (name === 'value') { this.counter = newValue; } } constructor() { Handle attribute changes
  29. 29. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML CUSTOM COMPONENT ATTRIBUTES index.html class Counter extends HTMLElement { static get observedAttributes() { return ['value']; } attributeChangedCallback(name, oldValue, newValue) { if (name === 'value') { this.counter = newValue; } } constructor() { Define which attributes should be watched
  30. 30. WHAT ABOUT STYLES?
  31. 31. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML CUSTOM COMPONENT STYLES index.html Apply scoped styles to our component (function () { const template = createTemplate(` <style> :host { display: flex; } div[name="value"] { min-width: 30px; } </style> <div name="value"></div> <button data-type="dec">-</button> <button data-type="inc">+</button> `); class Counter extends HTMLElement {
  32. 32. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML WEB COMPONENT CSS ▸ :host - selects the shadow host of the shadow DOM ▸ :host() - match only if the selector given as the function's parameter matches the shadow host. ▸ :host-context() -  match only if the selector given as the function's parameter matches the shadow host's ancestor(s) in the place it sits inside the DOM hierarchy. ▸ ::slotted() - represents any element that has been placed into a slot inside an HTML template
  33. 33. WHAT ABOUT DISPATCHING EVENTS?
  34. 34. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML CUSTOM EVENTS Dispatching custom event const test = shadowRoot.getElementById('element-button'); test.addEventListener('click', () => { this.dispatchEvent(new CustomEvent('toggle', { detail: { value: true } })) }); custom-element.js
  35. 35. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML CUSTOM EVENTS Listening for custom event • CustomEvent {isTrusted: false, detail: {value: true}, type: "toggle", …} const el = document.getElementById('my-custom-element'); el.addEventListener('toggle', e => { console.log(e); }); main.js Console
  36. 36. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML FURTHER READING ▸ Extending different HTML Elements
 (e.g. HTMLButton)
  37. 37. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML BENEFITS OF USING CUSTOM COMPONENTS ▸ Framework agnostic - Written in JavaScript and native to the browser. ▸ Simplifies CSS - Scoped DOM means you can use simple CSS selectors, more generic id/class names, and not worry about naming conflicts. • Productivity - Think of apps in chunks of DOM rather than one large (global) page. ▸ Productivity - Think of apps in chunks of DOM rather than one large (global) page.
  38. 38. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML BROWSER SUPPORT
  39. 39. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML COSTS OF USING CUSTOM COMPONENTS ▸ Template Generation - manually construct the DOM for our templates 
 (No JSX features or Structural Directives) ▸ DOM Updates - manually track and handle changes to our DOM
 (No Virtual DOM or Change Detection)
  40. 40. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML LIT HTML ▸ Library Developed by the Polymer Team @ GOOGLE ▸ Efficient - lit-html is extremely fast. It uses fast platform features like HTML <template> elements with native cloning. ▸ Expressive - lit-html gives you the full power of JavaScript and functional programming patterns. ▸ Extensible - Different dialects of templates can be created with additional features for setting element properties, declarative event handlers and more. ▸ It can be used standalone for simple tasks, or combined with a framework or component model, like Web Components, for a full-featured UI development platform. ▸ It has an awesome VSC extension for syntax highlighting and formatting.
  41. 41. TAG FUNCTIONS
  42. 42. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML TAG FUNCTIONS function myTagFn(str, ...expr) { console.log(str, expr); return str.reduce((acc, curr, i) => acc + curr + (expr[i] || ''), ''); } myTagFn`1+1 equals ${1+1} and 3 + 3 equals ${3+3} ${3+2}` > (4) ["1+1 equals ", " and 3 + 3 equals ", " ", ""] (3) [2, 6, 5] > “1+1 equals 2 and 3 + 3 equals 6 5" Console
  43. 43. DEMOTHE LIT WAY
  44. 44. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML import { html, render } from 'lit-html'; const getTemplate = (context: App) => html`<div>Hello World!</div>`; export class App extends HTMLElement { constructor() { super(); const root = this.attachShadow({ mode: 'closed' }); this.changeHandler = () => { if (!this.scheduledRender) { this.scheduledRender = true; Promise.resolve().then(() => { this.scheduledRender = false; render(getTemplate(this), root); }); } } } connectedCallback() { this.changeHandler(); } } customElements.define('hg-app', App);
  45. 45. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML import { html, render } from 'lit-html'; const getTemplate = (context: App) => html`<div>Hello World!</div>`; export class App extends HTMLElement { constructor() { super(); const root = this.attachShadow({ mode: 'closed' }); this.changeHandler = () => { if (!this.scheduledRender) { this.scheduledRender = true; Promise.resolve().then(() => { this.scheduledRender = false; render(getTemplate(this), root); }); } } } connectedCallback() { this.changeHandler(); } } customElements.define('hg-app', App);
  46. 46. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML import { html, render } from 'lit-html'; const getTemplate = (context: App) => html`<div>Hello World!</div>`; export class App extends HTMLElement { constructor() { super(); const root = this.attachShadow({ mode: 'closed' }); this.changeHandler = () => { if (!this.scheduledRender) { this.scheduledRender = true; Promise.resolve().then(() => { this.scheduledRender = false; render(getTemplate(this), root); }); } } } connectedCallback() { this.changeHandler(); } } customElements.define('hg-app', App);
  47. 47. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML import { html, render } from 'lit-html'; const getTemplate = (context: App) => html`<div>Hello World!</div>`; export class App extends HTMLElement { constructor() { super(); const root = this.attachShadow({ mode: 'closed' }); this.changeHandler = () => { if (!this.scheduledRender) { this.scheduledRender = true; Promise.resolve().then(() => { this.scheduledRender = false; render(getTemplate(this), root); }); } } } connectedCallback() { this.changeHandler(); } } customElements.define('hg-app', App);
  48. 48. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML import { html, render } from 'lit-html'; const getTemplate = (context: App) => html`<div>Hello World!</div>`; export class App extends HTMLElement { constructor() { super(); const root = this.attachShadow({ mode: 'closed' }); this.changeHandler = () => { if (!this.scheduledRender) { this.scheduledRender = true; Promise.resolve().then(() => { this.scheduledRender = false; render(getTemplate(this), root); }); } } } connectedCallback() { this.changeHandler(); } } customElements.define('hg-app', App);
  49. 49. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML import { html, render } from 'lit-html'; const getTemplate = (context: App) => html`<div>Hello World!</div>`; export class App extends HTMLElement { constructor() { super(); const root = this.attachShadow({ mode: 'closed' }); this.changeHandler = () => { if (!this.scheduledRender) { this.scheduledRender = true; Promise.resolve().then(() => { this.scheduledRender = false; render(getTemplate(this), root); }); } } } connectedCallback() { this.changeHandler(); } } customElements.define('hg-app', App);
  50. 50. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML import { html, render } from 'lit-html'; const getTemplate = (context: App) => html`<div>Hello World!</div>`; export class App extends HTMLElement { constructor() { super(); const root = this.attachShadow({ mode: 'closed' }); this.changeHandler = () => { if (!this.scheduledRender) { this.scheduledRender = true; Promise.resolve().then(() => { this.scheduledRender = false; render(getTemplate(this), root); }); } } } connectedCallback() { this.changeHandler(); } } customElements.define('hg-app', App);
  51. 51. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML import { html, render } from 'lit-html'; const getTemplate = (context: App) => html`<div>Hello World!</div>`; export class App extends HTMLElement { constructor() { super(); const root = this.attachShadow({ mode: 'closed' }); this.changeHandler = () => { if (!this.scheduledRender) { this.scheduledRender = true; Promise.resolve().then(() => { this.scheduledRender = false; render(getTemplate(this), root); }); } } } connectedCallback() { this.changeHandler(); } } customElements.define('hg-app', App);
  52. 52. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML import { html, render } from 'lit-html'; const getTemplate = (context: App) => html`<div>Hello World!</div>`; export class App extends HTMLElement { constructor() { super(); const root = this.attachShadow({ mode: 'closed' }); this.changeHandler = () => { if (!this.scheduledRender) { this.scheduledRender = true; Promise.resolve().then(() => { this.scheduledRender = false; render(getTemplate(this), root); }); } } } connectedCallback() { this.changeHandler(); } } customElements.define('hg-app', App);
  53. 53. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML import { html, render } from 'lit-html'; const getTemplate = (context: App) => html`<div>Hello World!</div>`; export class App extends HTMLElement { constructor() { super(); const root = this.attachShadow({ mode: 'closed' }); this.changeHandler = () => { if (!this.scheduledRender) { this.scheduledRender = true; Promise.resolve().then(() => { this.scheduledRender = false; render(getTemplate(this), root); }); } } } connectedCallback() { this.changeHandler(); } } customElements.define('hg-app', App);
  54. 54. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML import { html, render } from 'lit-html'; const getTemplate = (context: App) => html`<div>Hello World!</div>`; export class App extends HTMLElement { constructor() { super(); const root = this.attachShadow({ mode: 'closed' }); this.changeHandler = () => { if (!this.scheduledRender) { this.scheduledRender = true; Promise.resolve().then(() => { this.scheduledRender = false; render(getTemplate(this), root); }); } } } connectedCallback() { this.changeHandler(); } } customElements.define('hg-app', App);
  55. 55. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML import { html, render } from 'lit-html'; const getTemplate = (context: App) => html`<div>Hello World!</div>`; export class App extends HTMLElement { constructor() { super(); const root = this.attachShadow({ mode: 'closed' }); this.changeHandler = () => { if (!this.scheduledRender) { this.scheduledRender = true; Promise.resolve().then(() => { this.scheduledRender = false; render(getTemplate(this), root); }); } } } connectedCallback() { this.changeHandler(); } } customElements.define('hg-app', App);
  56. 56. DEMOINTERPOLATION & EVENT HANDLER BINDING
  57. 57. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML const getTemplate = (context: App) => html` <div>${context.counter}</div> <button @click=${context.incrementHandler}>Increment</button> `; export class App extends HTMLElement { counter = 0; constructor() { ... } incrementHandler = () => { this.counter++; this.changeHandler(); } } customElements.define('hg-app', App);
  58. 58. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML const getTemplate = (context: App) => html` <div>${context.counter}</div> <button @click=${context.incrementHandler}>Increment</button> `; export class App extends HTMLElement { counter = 0; constructor() { ... } incrementHandler = () => { this.counter++; this.changeHandler(); } } customElements.define('hg-app', App);
  59. 59. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML const getTemplate = (context: App) => html` <div>${context.counter}</div> <button @click=${context.incrementHandler}>Increment</button> `; export class App extends HTMLElement { counter = 0; constructor() { ... } incrementHandler = () => { this.counter++; this.changeHandler(); } } customElements.define('hg-app', App);
  60. 60. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML const getTemplate = (context: App) => html` <div>${context.counter}</div> <button @click=${context.incrementHandler}>Increment</button> `; export class App extends HTMLElement { counter = 0; constructor() { ... } incrementHandler = () => { this.counter++; this.changeHandler(); } } customElements.define('hg-app', App);
  61. 61. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML const getTemplate = (context: App) => html` <div>${context.counter}</div> <button @click=${context.incrementHandler}>Increment</button> `; export class App extends HTMLElement { counter = 0; constructor() { ... } incrementHandler = () => { this.counter++; this.changeHandler(); } } customElements.define('hg-app', App);
  62. 62. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML const getTemplate = (context: App) => html` <div>${context.counter}</div> <button @click=${context.incrementHandler}>Increment</button> `; export class App extends HTMLElement { counter = 0; constructor() { ... } incrementHandler = () => { this.counter++; this.changeHandler(); } } customElements.define('hg-app', App);
  63. 63. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML const getTemplate = (context: App) => html` <div>${context.counter}</div> <button @click=${context.incrementHandler}>Increment</button> `; export class App extends HTMLElement { counter = 0; constructor() { ... } incrementHandler = () => { this.counter++; this.changeHandler(); } } customElements.define('hg-app', App);
  64. 64. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML const getTemplate = (context: App) => html` <div>${context.counter}</div> <button @click=${context.incrementHandler}>Increment</button> `; export class App extends HTMLElement { counter = 0; constructor() { ... } incrementHandler = () => { this.counter++; this.changeHandler(); } } customElements.define('hg-app', App);
  65. 65. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML const getTemplate = (context: App) => html` <div>${context.counter}</div> <button @click=${context.incrementHandler}>Increment</button> `; export class App extends HTMLElement { counter = 0; constructor() { ... } incrementHandler = () => { this.counter++; this.changeHandler(); } } customElements.define('hg-app', App);
  66. 66. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML const getTemplate = (context: App) => html` <div>${context.counter}</div> <button @click=${context.incrementHandler}>Increment</button> `; export class App extends HTMLElement { counter = 0; constructor() { ... } incrementHandler = () => { this.counter++; this.changeHandler(); } } customElements.define('hg-app', App);
  67. 67. DEMODATA BINDING
  68. 68. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML const getAppTemplate = (context: App) => html` <hg-counter .value=${context.counter}></hg-counter> <button @click=${context.incrementHandler}>Increment</button> `;
  69. 69. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML const getAppTemplate = (context: App) => html` <hg-counter .value=${context.counter}></hg-counter> <button @click=${context.incrementHandler}>Increment</button> `;
  70. 70. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML const getAppTemplate = (context: App) => html` <hg-counter .value=${context.counter}></hg-counter> <button @click=${context.incrementHandler}>Increment</button> `;
  71. 71. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML const getAppTemplate = (context: App) => html` <hg-counter .value=${context.counter}></hg-counter> <button @click=${context.incrementHandler}>Increment</button> `;
  72. 72. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML const getCounterTemplate = (context: Counter) => html` <div>${context.value}</div> `; export class Counter extends HTMLElement { _value = 0; set value(value) { this._value = value; this.changeHandler(); } get value() { return this._value; } constructor() { super(); const root = this.attachShadow({ mode: 'closed' }); } }
  73. 73. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML const getCounterTemplate = (context: Counter) => html` <div>${context.value}</div> `; export class Counter extends HTMLElement { _value = 0; set value(value) { this._value = value; this.changeHandler(); } get value() { return this._value; } constructor() { super(); const root = this.attachShadow({ mode: 'closed' }); } }
  74. 74. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML const getCounterTemplate = (context: Counter) => html` <div>${context.value}</div> `; export class Counter extends HTMLElement { _value = 0; set value(value) { this._value = value; this.changeHandler(); } get value() { return this._value; } constructor() { super(); const root = this.attachShadow({ mode: 'closed' }); } }
  75. 75. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML const getCounterTemplate = (context: Counter) => html` <div>${context.value}</div> `; export class Counter extends HTMLElement { _value = 0; set value(value) { this._value = value; this.changeHandler(); } get value() { return this._value; } constructor() { super(); const root = this.attachShadow({ mode: 'closed' }); } }
  76. 76. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML const getCounterTemplate = (context: Counter) => html` <div>${context.value}</div> `; export class Counter extends HTMLElement { _value = 0; set value(value) { this._value = value; this.changeHandler(); } get value() { return this._value; } constructor() { super(); const root = this.attachShadow({ mode: 'closed' }); } }
  77. 77. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML const getCounterTemplate = (context: Counter) => html` <div>${context.value}</div> `; export class Counter extends HTMLElement { _value = 0; set value(value) { this._value = value; this.changeHandler(); } get value() { return this._value; } constructor() { super(); const root = this.attachShadow({ mode: 'closed' }); ... } }
  78. 78. CAN WE EXTRACT THE REPEATING PARTS?
  79. 79. DEMODECORATORS
  80. 80. export function Component(config: { mode?: 'open' | 'closed', selector: string }) { return function componentDecorator(target) { const cmp = class extends HTMLElement { scheduledRender = false; constructor(...args) { super(); const root = this.attachShadow({ mode: config.mode || 'closed' }); const targetInstance = new target(...args); const { constructor, ...prototypeProps } = Object.getOwnPropertyDescriptors(target.prototype); const props = { ...Object.getOwnPropertyDescriptors(targetInstance), ...prototypeProps } Object.defineProperties(this, props); this.changeHandler = function () { if (!this.scheduledRender) { this.scheduledRender = true; Promise.resolve().then(() => { this.scheduledRender = false; if (!this.render) { return; } render(this.render(), root); }); } } return this; } connectedCallback() { this.changeHandler(); if (this.onConnected) { this.onConnected(); } } }; customElements.define(config.selector, cmp); return cmp as any; }; }
  81. 81. function property(target: any, propertyKey: string | symbol) { let _value; Object.defineProperty(target, propertyKey, { set: function (value) { _value = value; if (!this.changeHandler) { return; } this.changeHandler(); }, get: function () { return _value; } }) }
  82. 82. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML @Component({ selector: 'hg-counter' }) export class Counter { @property value; onConnected() { console.log('Counter connected'); } render() { return html` <div>${this.value}</div> `; } }
  83. 83. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML LIT ELEMENT ▸ A simple base class for creating fast, lightweight web components https://lit-element.polymer-project.org/
  84. 84. DEMODIRECTIVES
  85. 85. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML LIT HTML DIRECTIVES (1) ▸ Directives are functions that can customize how lit-html renders values. Template authors can use directives in their templates like other functions
  86. 86. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML LIT HTML DIRECTIVES (2) ▸ The returned function is called each time the part is rendered. The part argument is a Part object with an API for directly managing the dynamic DOM associated with expressions. Each type of binding has its own specific Part object: ▸ NodePart for content bindings. ▸ AttributePart for standard attribute bindings. ▸ BooleanAttributePart for boolean attribute bindings. ▸ EventPart for event bindings. ▸ PropertyPart for property bindings.
  87. 87. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML LIT HTML DIRECTIVES (3) ▸ Each of these part types implement a common API: ▸ value. Holds the current value of the part. ▸ setValue. Sets the pending value of the part. ▸ commit. Writes the pending value to the DOM. In most cases this happens automatically—this method is only required for advanced use cases, like asynchronous directives.
  88. 88. ASYNCHRONOUS DIRECTIVES?
  89. 89. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML
  90. 90. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML
  91. 91. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML LIT HTML UNTIL BUILT-IN DIRECTIVE
  92. 92. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML LIT HTML BUILT-IN DIRECTIVES ▸ asyncAppend and asyncReplace ▸ cache ▸ classMap ▸ ifDefined ▸ guard ▸ repeat ▸ styleMap ▸ unsafeHTML ▸ until
  93. 93. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML LIT-HTML & HTML/CSS ▸ Dynamic css class/id and property names ▸ Dynamic css property values ▸ Sharing styles and HTML between the isolated web components (mixins)
  94. 94. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML WEB COMPONENTS + LIT-HTML VS REACT + JSX ▸ React and JSX are not standard and JSX requires a compiler. ▸ React reconciliation is doing diff checking per node so there might be a lot of unnecessary checks when re-rendering and with lit-html the tag functions separate static from dynamic parts so checks are very fast. ▸ LIT-HTML is very small ~ 2.5K and Web Components are native.
  95. 95. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML LARGER FRAMEWORKS ▸ StencilJS - a simple library for generating Web Components and progressive web apps (PWA). 
 (built by the Ionic Framework team for its next generation of performant mobile and desktop Web Components) ▸ Polymer - library for creating web components.
 (built by Google and used by YouTube, Netflix, Google Earth and others) ▸ SkateJS - library providing functional abstraction over web components. ▸ Angular Elements
  96. 96. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML ADDITIONAL RESOURCES ▸ https://custom-elements-everywhere.com - This project runs a suite of tests against each framework to identify interoperability issues, and highlight potential fixes already implemented in other frameworks.
  97. 97. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML WEB COMPONENTS SERVER SIDE RENDERING ▸ SkateJS SSR - @skatejs/ssr is a web component server-side rendering and testing library. (uses undom) ▸ Rendertron - Rendertron is a headless Chrome rendering solution designed to render & serialise web pages on the fly. ▸ Domino - Server-side DOM implementation based on Mozilla's dom.js
  98. 98. CREATING LIGHTWEIGHT JS APPS W/ WEB COMPONENTS AND LIT-HTML CONNECT GitHub > https://github.com/iliaidakiev (/slides/ - list of future and past events) Twitter > @ilia_idakiev
  99. 99. THANK YOU!

×