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

The State of Web Components

Shogo Sensui
September 24, 2017

The State of Web Components

2017年9月24日に開催された HTML5 Conference 2017 の「The State of Web Components」のセッション資料です。

Shogo Sensui

September 24, 2017
Tweet

More Decks by Shogo Sensui

Other Decks in Technology

Transcript

  1. ‣ 4IPHP4FOTVJ ‣ ؎ٝة٦طحزדכDIדׅ ‣ $ZCFS"HFOU *OD ‣ 8FC*OJUJBUJWF$FOUFS ‣

    4PGUXBSF&OHJOFFS ‣ 8FC䪮遭Ⰻ菙ָ㥨ֹדׅ ‣ 044崞⹛׮׃גתׅ
  2. <button> fancy button </button> button { background: #0086b3; color: white;

    padding: 1em; border-radius: 0.5em; border: none; } )5.-ה$44׾剅ֽל0,
  3. <button class="a"> fancy button </button> <button class="b"> fancy button </button>

    button { color: white; padding: 1em; border-radius: 0.5em; border: none; } button.a { background: #0086b3; } button.b { background: #008080; }
  4. fancy button </button> <button class="b"> fancy button </button> <button class="c">

    fancy button </button> <button class="oval"> oval </button> <button class="square"> border-radius: 0.5em; border: none; } button.a { background: #0086b3; } button.b { background: #008080; } button.oval { ... }
  5. <fancy-button color="a"> fancy button </fancy-button> <fancy-button color="b"> fancy button </fancy-button>

    <fancy-button color="c"> fancy button </fancy-button> <oval-button>oval</oval-button> <square-button>square</square-button>
  6. const button = document.querySelector('button'); const shadowRoot = button.attachShadow({ mode: 'open'

    // or 'close' }); // readonly property console.log(button.shadowRoot); 4IBEPX%0.ך欰װ׃倯
  7. <button> fancy button </button> ֲֿ剅ֽ׋׵ءٝفٕ˘ <style> button { background: #0086b3;

    color: white; padding: 1em; border-radius: 0.5em; border: none; }ɹ </style>
  8. <button> #shadow-root fancy button </button> <style> button { background: #0086b3;

    color: white; padding: 1em; border-radius: 0.5em; border: none; } </style> <button> <slot></slot> </button>
  9. <button> #shadow-root fancy button </button> <style> button { background: #0086b3;

    color: white; padding: 1em; border-radius: 0.5em; border: none; }ɹ </style> <button> <slot></slot> </button>
  10. <button> #shadow-root fancy button </button> <style> button { background: #0086b3;

    color: white; padding: 1em; border-radius: 0.5em; border: none; } </style> <button> <slot></slot> </button> 4DPQFE
  11. class FancyButton extends HTMLElement { constructor() { ... } connectedCallback()

    { ... } disconnectedCallback() { ... } attributeChangedCallback() { ... } adoptedCallback() { ... } } ؕأةي銲稆ٓ؎ؿ؟؎ؙٕ
  12. class FancyButton extends HTMLElement { connectedCallback() { this.innerHTML = `

    <style>button { … }</style> <button>fancy button</button> `; } } customElements .define('fancy-button', FancyButton);
  13. <fancy-button> <style> button { background: #0086b3; color: white; padding: 1em;

    border-radius: 0.5em; border: none; } </style> <button> fancy button </button> </fancy-button> /PUTDPQFE
  14. class FancyButton extends HTMLElement { connectedCallback() { this.innerHTML = `

    <style>button { … }</style> <button>fancy button</button> `; } } customElements .define('fancy-button', FancyButton);
  15. class FancyButton extends HTMLElement { connectedCallback() { this.shadowRoot.innerHTML = `

    <style>button { … }</style> <button><slot></slot></button> `; } } customElements .define('fancy-button', FancyButton);
  16. <fancy-button> <style> button { background: #0086b3; color: white; padding: 1em;

    border-radius: 0.5em; border: none; } </style> <button> fancy button </button> </fancy-button>
  17. <fancy-button> #shadow-root <style> button { background: #0086b3; color: white; padding:

    1em; border-radius: 0.5em; border: none; } </style> <button> <slot></slot> </button> fancy button </fancy-button> 4DPQFE
  18. class FancyButton extends HTMLElement { connectedCallback() { this.shadowRoot.innerHTML = `

    <style>button { … }</style> <button><slot></slot></button> `; } } customElements .define('fancy-button', FancyButton);
  19. <template> <style>button { … }</style> <button><slot></slot></button> </template> <script> class FancyButton

    extends HTMLElement { // ... } customElements .define('fancy-button', FancyButton); </script>
  20. import fancy from './fancy.html' as HTMLTemplateElement; export class FancyButton extends

    HTMLElement { connectedCallback() { this.attachShadow({ mode: 'open' }).appendChild(fancy.content.cloneNode(true)); } }
  21. import React from 'react'; import ReactDOM from 'react-dom'; import PropTypes

    from 'prop-types'; import FancyButton from './fancy-button.js'; JOEFYKT
  22. class FancyButton extends HTMLElement { connectedCallback() { this.attachShadow({ mode: 'open'

    }).innerHTML = ` <style>button { … }</style> <button><slot></slot></button> `; } } customElements .define('fancy-button', FancyButton);
  23. export default class FancyButton extends HTMLElement { connectedCallback() { this.attachShadow({

    mode: 'open' }).innerHTML = ` <style>button { … }</style> <button><slot></slot></button> `; } }
  24. 4IBEPX%0. $VTUPN&MFNFOUT &4.PEVMFT OQN ZBSO 8FCחֶֽ׷鿇ㅷךꨇ׃ׁ ‣ )5.-ה$44חأ؝٦فָ㶷㖈׃זְ ‣ 铣׫鴥׿׌$44ך䕦갟眔㔲ָ鎘׶濼׸זְ

    ‣ せ⵸瑞꟦ָ遼瑱׃זְ״ֲծ䌢ח䠐陎ׅ׷䗳銲ָ֮׷ ‣ ⡲׏׋鿇ㅷ׾ⱄⵃ欽׃חְֻ ‣ )5.- $44 +BWB4DSJQU׾תה׭׷➬穈׫ָזְ ‣ תה׭׋鿇ㅷ׾ꂁ䋒ׅ׷ؒ؝ءأذيָזַ׏׋
  25. // fancy-button v1.0.0 customElements .define('fancy-button', FancyButton); // fancy-button v1.1.0 customElements

    .define('fancy-button', FancyButton); ZBSO׾⢪ֲץֹ椚歋 ☠ ⣛㶷ٌآُ٦ٕ׾ؿٓحزזخٔ٦ד鍑寸דֹ׷✨
  26. ✅ ✅ $VTUPN&MFNFOUTW 4IBEPX%0.W 5FNQMBUFT &4.PEVMFT ✅ ✅ ✅ ✅

    ✅ ✅ ✅ ✅ ✅ ✅ 䎃猧ـٓؐؠ؟ه٦ز
  27. <fancy-button> #shadow-root fancy button </fancy-button> <style> button { background: #0086b3;

    color: white; padding: 1em; border-radius: 0.5em; border: none; } </style> <button> <slot></slot> </button> &YQPTFE
  28. <fancy-button> #shadow-root fancy button </fancy-button> <style> div { background: #0086b3;

    color: white; padding: 1em; border-radius: 0.5em; border: none; } </style> <div role="button" tabindex="0"> <slot></slot> </div> &YQPTFE
  29. import React from 'react'; export default class Button extends React.Component

    { handleClick(e) { if (this.props.onClick) { this.props.onClick(e); } } render() { const handleClick = this.handleClick.bind(this); return ( <fancy-button onClick={handleClick}> {this.props.children} </fancy-button> ); } }
  30. const helloTemplate = (name) => html`<div>Hello ${name}!</div>`; // renders <div>Hello

    Steve!</div> to the document body render(helloTemplate('Steve'), document.body); // updates to <div>Hello Kevin!</div>, but only updates the ${name} part render(helloTemplate('Kevin'), document.body);
  31. import { html, render } from './lit-html.js'; export default class

    IconButton extends HTMLElement { connectedCallback() { this.attachShadow({ mode: 'open' }); render(this.template, this.shadowRoot); } get template() { return html` <style>...</style> <button> <i class="${this.getAttribute('icon')}"></i> <slot></slot> </button> `; } };