SlideShare a Scribd company logo
1 of 102
Download to read offline
‣
‣
‣
‣
‣
‣
‣
📕
‣
‣
‣
‣
‣
‣
<button>
fancy button
</button>
button {
background: #0086b3;
color: white;
padding: 1em;
border-radius: 0.5em;
border: none;
}
<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;
}
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 {
...
}
<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>
‣
‣
‣
‣
‣
const button = document.querySelector('button');
const shadowRoot = button.attachShadow({
mode: 'open' // or 'close'
});
// readonly property
console.log(button.shadowRoot);
<button>
fancy button
</button>
<style>
button {
background: #0086b3;
color: white;
padding: 1em;
border-radius: 0.5em;
border: none;
} 
</style>
<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>
<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>
<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>
🎉
‣
‣
‣
‣
‣
class FancyButton extends HTMLElement {
constructor() { ... }
connectedCallback() { ... }
disconnectedCallback() { ... }
attributeChangedCallback() { ... }
adoptedCallback() { ... }
}
‣
‣
‣
‣
‣
.fancy {
background: #0086b3;
color: white;
padding: 1em;
border-radius: 0.5em;
border: none;
}
document
.querySelector('.fancy')
.addEventListener('click', () => {
//...
});
<button class="fancy">
fancy button
</button>
<link rel="stylesheet" href="button.css">
...
<button class="fancy">
fancy button
</button>
...
<script src="button.js"></script>
class FancyButton extends HTMLElement {
connectedCallback() {
this.innerHTML = `
<style>button { … }</style>
<button>fancy button</button>
`;
}
}
customElements
.define('fancy-button', FancyButton);
<fancy-button>
fancy button
</fancy-button>
<fancy-button>
<style>
button {
background: #0086b3;
color: white;
padding: 1em;
border-radius: 0.5em;
border: none;
}
</style>
<button>
fancy button
</button>
</fancy-button>
🤔
class FancyButton extends HTMLElement {
connectedCallback() {
this.innerHTML = `
<style>button { … }</style>
<button>fancy button</button>
`;
}
}
customElements
.define('fancy-button', FancyButton);
class FancyButton extends HTMLElement {
connectedCallback() {
this.shadowRoot.innerHTML = `
<style>button { … }</style>
<button><slot></slot></button>
`;
}
}
customElements
.define('fancy-button', FancyButton);
<fancy-button>
<style>
button {
background: #0086b3;
color: white;
padding: 1em;
border-radius: 0.5em;
border: none;
}
</style>
<button>
fancy button
</button>
</fancy-button>
<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>
🎉
‣
‣
‣
<div style="display:none;">
<p>This is an image</p>
<img src="foo.jpg" alt="">
</div>
<script type="text/template">
<p>This is an image</p>
<img src="foo.jpg" alt="">
</script>
<template>
<p>This is an image</p>
<img src="foo.jpg" alt="">
</template>
✨
class FancyButton extends HTMLElement {
connectedCallback() {
this.shadowRoot.innerHTML = `
<style>button { … }</style>
<button><slot></slot></button>
`;
}
}
customElements
.define('fancy-button', FancyButton);
<template>
<style>button { … }</style>
<button><slot></slot></button>
</template>
<script>
class FancyButton extends HTMLElement {
// ...
}
customElements
.define('fancy-button', FancyButton);
</script>
<link
rel="import"
href="fancy-button.html">
<fancy-button>
fancy button
</fancy-button>
… 😇
… 🤔
import fancy from './fancy.html' as HTMLTemplateElement;
export class FancyButton extends HTMLElement {
connectedCallback() {
this.attachShadow({
mode: 'open'
}).appendChild(fancy.content.cloneNode(true));
}
}
🤔
‣
‣
‣
‣
‣
export default class FancyButton {
...
}
import React from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import FancyButton from './fancy-button.js';
<script type="module">
import FancyButton from './fancy-button.js';
customElements
.define('fancy-button', FancyButton);
</script>
class FancyButton extends HTMLElement {
connectedCallback() {
this.attachShadow({
mode: 'open'
}).innerHTML = `
<style>button { … }</style>
<button><slot></slot></button>
`;
}
}
customElements
.define('fancy-button', FancyButton);
export default
class FancyButton extends HTMLElement {
connectedCallback() {
this.attachShadow({
mode: 'open'
}).innerHTML = `
<style>button { … }</style>
<button><slot></slot></button>
`;
}
}
<fancy-button>
fancy button
</fancy-button>
<script type="module">
import FancyButton from './fancy-button.js';
customElements
.define('fancy-button', FancyButton);
</script>
🎉
‣
‣
‣
‣
‣
‣
‣
‣
‣
‣
‣
‣
😇
🐦
🐈
// fancy-button v1.0.0
customElements
.define('fancy-button', FancyButton);
// fancy-button v1.1.0
customElements
.define('fancy-button', FancyButton);
☠
💖
✨
‣
‣
‣
‣
‣
‣
‣
‣
🚧✅ 🤔✅
✅ ✅✅ ✅
✅ ✅✅ ✅
🤔✅✅ 🚧
🚩🚩
✨
‣
‣
‣
‣
‣
‣
‣
‣
‣
‣
🙊
‣
‣
‣
‣
‣
‣
‣
‣
‣
‣ 🤔
<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>
<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>
‣
‣
‣
‣
‣
‣
‣
‣
‣
‣
‣
‣
‣
‣
‣
‣
‣
‣
‣
‣
‣
‣
‣
‣
‣
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>
);
}
}
‣
‣
‣
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);
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>
`;
}
};
‣
‣
‣
‣
✨
💓
!
"

More Related Content

More from Shogo Sensui

Web Standards Interop 2022
Web Standards Interop 2022Web Standards Interop 2022
Web Standards Interop 2022Shogo Sensui
 
Introduction to Performance APIs
Introduction to Performance APIsIntroduction to Performance APIs
Introduction to Performance APIsShogo Sensui
 
Web Standards 2018
Web Standards 2018Web Standards 2018
Web Standards 2018Shogo Sensui
 
Component of Web Frontend
Component of Web FrontendComponent of Web Frontend
Component of Web FrontendShogo Sensui
 
Web フロントエンドの変遷とこれから
Web フロントエンドの変遷とこれからWeb フロントエンドの変遷とこれから
Web フロントエンドの変遷とこれからShogo Sensui
 
Introduction to Resource Hints
Introduction to Resource HintsIntroduction to Resource Hints
Introduction to Resource HintsShogo Sensui
 
Web Components 2016 & Polymer v2
Web Components 2016 & Polymer v2Web Components 2016 & Polymer v2
Web Components 2016 & Polymer v2Shogo Sensui
 
これからのJavaScriptの話
これからのJavaScriptの話これからのJavaScriptの話
これからのJavaScriptの話Shogo Sensui
 
初心者のためのWeb標準技術
初心者のためのWeb標準技術初心者のためのWeb標準技術
初心者のためのWeb標準技術Shogo Sensui
 
Introduction to Service Worker
Introduction to Service WorkerIntroduction to Service Worker
Introduction to Service WorkerShogo Sensui
 
We should optimize images
We should optimize imagesWe should optimize images
We should optimize imagesShogo Sensui
 
Web Components changes Web Development
Web Components changes Web DevelopmentWeb Components changes Web Development
Web Components changes Web DevelopmentShogo Sensui
 
Re-think about Web Performance
Re-think about Web PerformanceRe-think about Web Performance
Re-think about Web PerformanceShogo Sensui
 
Browser Computing Structure
Browser Computing StructureBrowser Computing Structure
Browser Computing StructureShogo Sensui
 
Brush up your Coding! 2013 winter
Brush up your Coding! 2013 winterBrush up your Coding! 2013 winter
Brush up your Coding! 2013 winterShogo Sensui
 
Brush up your Coding!
Brush up your Coding!Brush up your Coding!
Brush up your Coding!Shogo Sensui
 
Functional JavaScript with Lo-Dash.js
Functional JavaScript with Lo-Dash.jsFunctional JavaScript with Lo-Dash.js
Functional JavaScript with Lo-Dash.jsShogo Sensui
 

More from Shogo Sensui (17)

Web Standards Interop 2022
Web Standards Interop 2022Web Standards Interop 2022
Web Standards Interop 2022
 
Introduction to Performance APIs
Introduction to Performance APIsIntroduction to Performance APIs
Introduction to Performance APIs
 
Web Standards 2018
Web Standards 2018Web Standards 2018
Web Standards 2018
 
Component of Web Frontend
Component of Web FrontendComponent of Web Frontend
Component of Web Frontend
 
Web フロントエンドの変遷とこれから
Web フロントエンドの変遷とこれからWeb フロントエンドの変遷とこれから
Web フロントエンドの変遷とこれから
 
Introduction to Resource Hints
Introduction to Resource HintsIntroduction to Resource Hints
Introduction to Resource Hints
 
Web Components 2016 & Polymer v2
Web Components 2016 & Polymer v2Web Components 2016 & Polymer v2
Web Components 2016 & Polymer v2
 
これからのJavaScriptの話
これからのJavaScriptの話これからのJavaScriptの話
これからのJavaScriptの話
 
初心者のためのWeb標準技術
初心者のためのWeb標準技術初心者のためのWeb標準技術
初心者のためのWeb標準技術
 
Introduction to Service Worker
Introduction to Service WorkerIntroduction to Service Worker
Introduction to Service Worker
 
We should optimize images
We should optimize imagesWe should optimize images
We should optimize images
 
Web Components changes Web Development
Web Components changes Web DevelopmentWeb Components changes Web Development
Web Components changes Web Development
 
Re-think about Web Performance
Re-think about Web PerformanceRe-think about Web Performance
Re-think about Web Performance
 
Browser Computing Structure
Browser Computing StructureBrowser Computing Structure
Browser Computing Structure
 
Brush up your Coding! 2013 winter
Brush up your Coding! 2013 winterBrush up your Coding! 2013 winter
Brush up your Coding! 2013 winter
 
Brush up your Coding!
Brush up your Coding!Brush up your Coding!
Brush up your Coding!
 
Functional JavaScript with Lo-Dash.js
Functional JavaScript with Lo-Dash.jsFunctional JavaScript with Lo-Dash.js
Functional JavaScript with Lo-Dash.js
 

The State of Web Components