SlideShare ist ein Scribd-Unternehmen logo
1 von 40
Felix Arntz / WordCamp London 2019
Web Components
Introduction to
Web Components are a standardized set of browser
APIs that allow you to define your own HTML tags,
reusable and self-contained.
<p>Hovering <a href="#tooltip1" class="tooltip-source">this text</a> will display a tooltip.</p>
<div id="tooltip1" class="tooltip">
<span class="tooltip-nag"></span>
This is the tooltip content.
</div>
<style>
.tooltip {
position: absolute;
display: none;
max-width: 16rem;
}
/* many more style rules... */
</style>
<script>
document.querySelector( '.tooltip-source' ).addEventListener( 'hover', event => {
event.preventDefault();
/* lots and lots more JavaScript... */
} );
</script>
Example: Tooltips
Example: Tooltips
<my-tooltips>
<p>Hovering <my-tooltip-anchor target="#tooltip1">this text</my-tooltip-anchor> will display a tooltip.</p>
<my-tooltip id="tooltip1">
This is the tooltip content.
</my-tooltip>
</my-tooltips>
Benefits of Web Components
MaintainabilityReusability Encapsulation Standardization
React vs. Vue vs. Web Components
React Vue Web Components
const { Component } = React;
class MyComponent extends
Component {
…
}
Vue.component(
‘my-component’, {
…
}
);
class MyComponent extends
HTMLElement {
…
}
customElements.define(
‘my-component’,
MyComponent
);
<MyComponent></MyComponent> <my-component></my-component> <my-component></my-component>
JSX (pre-processing required) HTML templates HTML templates
Framework Framework Standard
Key Takeaway: This is an unfair and false comparison.
Standardized Leaf Components
const { Component } = React;
class MyComponent extends Component {
render() {
const { active } = this.props;
return (
<my-leaf-component active={ active }>
</my-leaf-component>
);
}
}
class MyLeafComponent extends HTMLElement {
static get is() {
return 'my-leaf-component';
}
static get observedAttributes() {
return [ 'active' ];
}
}
customElements.define(
MyLeafComponent.is,
MyLeafComponent
);
React ❤ Web Components!
https://youtu.be/plt-iH_47GE
Source: https://softwareengineeringdaily.com/2018/10/22/google-javascript-with-malte-ubl/
Many frameworks are modeled around some notion of
components. [...]
So there's one thing that I am very sure of,
which is that we will see Web Components as the basically
only technology used for what I would call leaf components.
Malte Ubl
“
”Tech Lead of the AMP Project
Shadow DOM
Allows style and markup
to be encapsulated from
the regular DOM.
Custom Elements
Allows developers to
define their own
HTML tags.
HTML Templates
Allows to place markup
in a page that is only
parsed once necessary.
Key Web APIs
Current Browser Support
See full browser support
caniuse.com/#feat=custom-elementsv1
caniuse.com/#feat=shadowdomv1
caniuse.com/#feat=template
Also, check out the polyfill!
(github.com/webcomponents/custom-elements)
Let’s build a demo!
<h2 class="nav-tab-wrapper">
<a class="nav-tab nav-tab-active" href="#tab1">
Introduction
</a>
<a class="nav-tab" href="#tab2">
Polymer
</a>
<!-- ... -->
</h2>
<div id="tab1" class="nav-tab-panel nav-tab-panel-active"><!-- Panel 1 content. --></div>
<div id="tab2" class="nav-tab-panel"><!-- Panel 2 content. --></div>
<!-- ... -->
<h2 class="nav-tab-wrapper" role="tablist">
<a class="nav-tab nav-tab-active" href="#tab1" aria-controls="tab1" aria-selected="true" role="tab">
Introduction
</a>
<a class="nav-tab" href="#tab2" aria-controls="tab2" aria-selected="false" tabindex="-1" role="tab">
Polymer
</a>
<!-- ... -->
</h2>
<div id="tab1" class="nav-tab-panel nav-tab-panel-active" role="tabpanel"><!-- Panel 1 content. --></div>
<div id="tab2" class="nav-tab-panel" aria-hidden="true" role="tabpanel"><!-- Panel 2 content. --></div>
<!-- ... -->
Typical WordPress Approach
● wcig-tab for a single tab
● wcig-tab-panel for a single panel
associated with a tab
● wcig-tabs for the overall wrapper
Three Custom Elements
<wcig-tabs>
<wcig-tab slot="tabs" href="#tab1" selected>
Introduction
</wcig-tab>
<wcig-tab-panel slot="tabpanels" id="tab1" active>
<!-- Panel 1 content. -->
</wcig-tab-panel>
<wcig-tab slot="tabs" href="#tab2">
Polymer
</wcig-tab>
<wcig-tab-panel slot="tabpanels" id="tab2">
<!-- Panel 2 content. -->
</wcig-tab-panel>
<!-- ... -->
</wcig-tabs>
Custom Elements
https://html.spec.whatwg.org/#custom-elements
The Custom Elements API
1. Create a class that extends HTMLElement
2. Implement the element’s behavior and style in that class
3. Register the element with
customElements.define( tagName, elementClass )
class Tab extends HTMLElement {
constructor() {
super();
// ...
}
static get is() {
return 'wcig-tab';
}
static get observedAttributes() {
// ...
}
attributeChangedCallback( name, oldValue, newValue ) {
// ...
}
connectedCallback() {
// ...
}
disconnectedCallback() {
// ...
}
}
Scaffolding our Tab Element
connectedCallback() {
if ( ! this.hasAttribute( 'role' ) ) {
this.setAttribute( 'role', 'tab' );
}
const isSelected = this.hasAttribute( 'selected' );
if ( ! this.hasAttribute( 'tabindex' ) ) {
this.setAttribute( 'tabindex', isSelected ? 0 : -1 );
}
if ( ! this.hasAttribute( 'aria-selected' ) ) {
this.setAttribute( 'aria-selected', isSelected ? 'true' : 'false' );
}
this.addEventListener( 'click', this._onClick );
}
disconnectedCallback() {
this.removeEventListener( 'click', this._onClick );
}
Handling Custom Markup and Events
_onClick() {
if ( this.disabled || this.selected ) {
return;
}
this.selected = true;
this.dispatchEvent(
new CustomEvent(
'select',
{
bubbles: true
}
)
);
}
Emitting a Tab Selection Event
static get observedAttributes() {
return [ 'selected', 'disabled' ];
}
attributeChangedCallback( name, oldValue, newValue ) {
switch ( name ) {
case 'selected':
this.setAttribute( 'tabindex', null !== newValue ? 0 : -1 );
this.setAttribute( 'aria-selected', null !== newValue ? 'true' : 'false' );
break;
case 'disabled':
this.setAttribute( 'aria-disabled', null !== newValue ? 'true' : 'false' );
if ( null !== newValue || ! this.selected ) {
this.removeAttribute( 'tabindex' );
this.blur();
} else {
this.setAttribute( 'tabindex', 0 );
}
break;
}
}
Reacting to Attribute Changes
class Tab extends HTMLElement {
// ...
get selected() {
return this.hasAttribute( 'selected' );
}
set selected( val ) {
const isSelected = Boolean( val );
if ( isSelected ) {
this.setAttribute( 'selected', '' );
} else {
this.removeAttribute( 'selected' );
}
}
}
Reflecting Properties to Attributes
const tab = document.createElement(
'wcig-tab'
);
tab.selected = true;
<wcig-tab selected></wcig-tab>
class Tab extends HTMLElement {
// ...
}
customElements.define( Tab.is, Tab );
Registering The Custom Element
Shadow DOM
https://dom.spec.whatwg.org/#shadow-trees
What is the Shadow DOM?
● In addition to regular DOM node children, an element can have a
separate shadow tree attached to it.
● The element the shadow tree is attached to is called the shadow host.
● The document fragment attached to the shadow host is called the
shadow root.
● Elements in the shadow tree are scoped to the shadow host element and
cannot be accessed from the outside.
Example: The Built-in Range Input
Shadow trees have been used for quite a while by browsers already!
Providing Scoped Styles and Markup
class Tab extends HTMLElement {
constructor() {
super();
this.attachShadow( { mode: 'open' } );
this.shadowRoot.innerHTML = `
<style>
:host {
display: block;
/* ... */
}
:host(:focus),
:host(:hover) {
/* ... */
}
:host([selected]) {
/* ... */
}
</style>
<slot></slot>
`;
}
// ...
}
HTML Templates
https://html.spec.whatwg.org/#the-template-element
The template Element
<template id="my-template">
<div id="element-from-template">
<p>Element content.</p>
</div>
</template>
const template = document.querySelector( '#my-template' );
const element = template.content.cloneNode( true );
Improving Performance with a Template
const template = document.createElement( 'template' );
template.innerHTML = `
<style>
:host {
display: block;
/* ... */
}
/* ... */
</style>
<slot></slot>
`;
class Tab extends HTMLElement {
constructor() {
super();
this.attachShadow( { mode: 'open' } );
this.shadowRoot.appendChild( template.content.cloneNode( true ) );
}
// ...
}
To Be Continued...
Look up the full codebase at
github.com/felixarntz/web-components-in-gutenberg
Further Reading
● https://developers.google.com/web/fundamentals/web-components/customelements
● https://developers.google.com/web/fundamentals/web-components/shadowdom
● https://developers.google.com/web/fundamentals/web-components/best-practices
● https://developers.google.com/web/fundamentals/primers/async-functions
● https://developers.google.com/web/fundamentals/primers/modules
● https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
● https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set
● https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get
Proprietary + Confidential
Web Components Projects
https://www.webcomponents.org
https://www.polymer-project.org
https://amp.dev
https://amp-wp.org
https://github.com/felixarntz/web-components-in-gutenberg
Get Started with Web Components
MaintainabilityReusability Encapsulation Standardization
Proprietary + Confidential
Thank You
Felix Arntz
@felixarntz

Weitere ähnliche Inhalte

Was ist angesagt?

Django Class-based views (Slovenian)
Django Class-based views (Slovenian)Django Class-based views (Slovenian)
Django Class-based views (Slovenian)
Luka Zakrajšek
 
Propel sfugmd
Propel sfugmdPropel sfugmd
Propel sfugmd
iKlaus
 
Backbone.js Simple Tutorial
Backbone.js Simple TutorialBackbone.js Simple Tutorial
Backbone.js Simple Tutorial
추근 문
 
前端MVC 豆瓣说
前端MVC 豆瓣说前端MVC 豆瓣说
前端MVC 豆瓣说
Ting Lv
 
Gail villanueva add muscle to your wordpress site
Gail villanueva   add muscle to your wordpress siteGail villanueva   add muscle to your wordpress site
Gail villanueva add muscle to your wordpress site
references
 
Kick start with j query
Kick start with j queryKick start with j query
Kick start with j query
Md. Ziaul Haq
 

Was ist angesagt? (20)

Aplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com BackboneAplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com Backbone
 
Django Class-based views (Slovenian)
Django Class-based views (Slovenian)Django Class-based views (Slovenian)
Django Class-based views (Slovenian)
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ Etsy
 
WordPress Capabilities Magic
WordPress Capabilities MagicWordPress Capabilities Magic
WordPress Capabilities Magic
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From Iusethis
 
HirshHorn theme: how I created it
HirshHorn theme: how I created itHirshHorn theme: how I created it
HirshHorn theme: how I created it
 
Ruby - Design patterns tdc2011
Ruby - Design patterns tdc2011Ruby - Design patterns tdc2011
Ruby - Design patterns tdc2011
 
Propel sfugmd
Propel sfugmdPropel sfugmd
Propel sfugmd
 
Your Entity, Your Code
Your Entity, Your CodeYour Entity, Your Code
Your Entity, Your Code
 
Backbone.js Simple Tutorial
Backbone.js Simple TutorialBackbone.js Simple Tutorial
Backbone.js Simple Tutorial
 
前端MVC 豆瓣说
前端MVC 豆瓣说前端MVC 豆瓣说
前端MVC 豆瓣说
 
50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes
 
Jquery ui
Jquery uiJquery ui
Jquery ui
 
Gail villanueva add muscle to your wordpress site
Gail villanueva   add muscle to your wordpress siteGail villanueva   add muscle to your wordpress site
Gail villanueva add muscle to your wordpress site
 
Dig Deeper into WordPress - WD Meetup Cairo
Dig Deeper into WordPress - WD Meetup CairoDig Deeper into WordPress - WD Meetup Cairo
Dig Deeper into WordPress - WD Meetup Cairo
 
Kick start with j query
Kick start with j queryKick start with j query
Kick start with j query
 
Ajax nested form and ajax upload in rails
Ajax nested form and ajax upload in railsAjax nested form and ajax upload in rails
Ajax nested form and ajax upload in rails
 
Handlebars.js
Handlebars.jsHandlebars.js
Handlebars.js
 
Alfredo-PUMEX
Alfredo-PUMEXAlfredo-PUMEX
Alfredo-PUMEX
 
J query b_dotnet_ug_meet_12_may_2012
J query b_dotnet_ug_meet_12_may_2012J query b_dotnet_ug_meet_12_may_2012
J query b_dotnet_ug_meet_12_may_2012
 

Ähnlich wie Introduction to Web Components

HTML5 and the dawn of rich mobile web applications pt 2
HTML5 and the dawn of rich mobile web applications pt 2HTML5 and the dawn of rich mobile web applications pt 2
HTML5 and the dawn of rich mobile web applications pt 2
James Pearce
 
Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011
Chris Alfano
 
Your Custom WordPress Admin Pages Suck
Your Custom WordPress Admin Pages SuckYour Custom WordPress Admin Pages Suck
Your Custom WordPress Admin Pages Suck
Anthony Montalbano
 
How Not to Build a WordPress Plugin
How Not to Build a WordPress PluginHow Not to Build a WordPress Plugin
How Not to Build a WordPress Plugin
Will Norris
 
Jqeury ajax plugins
Jqeury ajax pluginsJqeury ajax plugins
Jqeury ajax plugins
Inbal Geffen
 

Ähnlich wie Introduction to Web Components (20)

HTML5 and the dawn of rich mobile web applications pt 2
HTML5 and the dawn of rich mobile web applications pt 2HTML5 and the dawn of rich mobile web applications pt 2
HTML5 and the dawn of rich mobile web applications pt 2
 
Polymer
PolymerPolymer
Polymer
 
Vaadin Components @ Angular U
Vaadin Components @ Angular UVaadin Components @ Angular U
Vaadin Components @ Angular U
 
Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technology
 
jQuery: Tips, tricks and hints for better development and Performance
jQuery: Tips, tricks and hints for better development and PerformancejQuery: Tips, tricks and hints for better development and Performance
jQuery: Tips, tricks and hints for better development and Performance
 
How to increase Performance of Web Application using JQuery
How to increase Performance of Web Application using JQueryHow to increase Performance of Web Application using JQuery
How to increase Performance of Web Application using JQuery
 
Building complex User Interfaces with Sitecore and React
Building complex User Interfaces with Sitecore and ReactBuilding complex User Interfaces with Sitecore and React
Building complex User Interfaces with Sitecore and React
 
jQuery
jQueryjQuery
jQuery
 
How to Mess Up Your Angular UI Components
How to Mess Up Your Angular UI ComponentsHow to Mess Up Your Angular UI Components
How to Mess Up Your Angular UI Components
 
Your Custom WordPress Admin Pages Suck
Your Custom WordPress Admin Pages SuckYour Custom WordPress Admin Pages Suck
Your Custom WordPress Admin Pages Suck
 
Clean Javascript
Clean JavascriptClean Javascript
Clean Javascript
 
Practica n° 7
Practica n° 7Practica n° 7
Practica n° 7
 
AnkaraJUG Kasım 2012 - PrimeFaces
AnkaraJUG Kasım 2012 - PrimeFacesAnkaraJUG Kasım 2012 - PrimeFaces
AnkaraJUG Kasım 2012 - PrimeFaces
 
Broadleaf Presents Thymeleaf
Broadleaf Presents ThymeleafBroadleaf Presents Thymeleaf
Broadleaf Presents Thymeleaf
 
Modern frontend development with VueJs
Modern frontend development with VueJsModern frontend development with VueJs
Modern frontend development with VueJs
 
jQuery in the [Aol.] Enterprise
jQuery in the [Aol.] EnterprisejQuery in the [Aol.] Enterprise
jQuery in the [Aol.] Enterprise
 
How Not to Build a WordPress Plugin
How Not to Build a WordPress PluginHow Not to Build a WordPress Plugin
How Not to Build a WordPress Plugin
 
Soa lab 3
Soa lab 3Soa lab 3
Soa lab 3
 
Jqeury ajax plugins
Jqeury ajax pluginsJqeury ajax plugins
Jqeury ajax plugins
 

Mehr von Felix Arntz (7)

Tackling performance in the WordPress ecosystem at scale
Tackling performance in the WordPress ecosystem at scaleTackling performance in the WordPress ecosystem at scale
Tackling performance in the WordPress ecosystem at scale
 
Enhancing performance in an open-source CMS ecosystem
Enhancing performance in an open-source CMS ecosystemEnhancing performance in an open-source CMS ecosystem
Enhancing performance in an open-source CMS ecosystem
 
The WordPress Performance Team
The WordPress Performance TeamThe WordPress Performance Team
The WordPress Performance Team
 
Accessing APIs using OAuth on the federated (WordPress) web
Accessing APIs using OAuth on the federated (WordPress) webAccessing APIs using OAuth on the federated (WordPress) web
Accessing APIs using OAuth on the federated (WordPress) web
 
AMP for JavaScripters
AMP for JavaScriptersAMP for JavaScripters
AMP for JavaScripters
 
Leveraging the Power of Custom Elements in Gutenberg
Leveraging the Power of Custom Elements in GutenbergLeveraging the Power of Custom Elements in Gutenberg
Leveraging the Power of Custom Elements in Gutenberg
 
Web Policies & Reporting
Web Policies & ReportingWeb Policies & Reporting
Web Policies & Reporting
 

Kürzlich hochgeladen

哪里办理美国迈阿密大学毕业证(本硕)umiami在读证明存档可查
哪里办理美国迈阿密大学毕业证(本硕)umiami在读证明存档可查哪里办理美国迈阿密大学毕业证(本硕)umiami在读证明存档可查
哪里办理美国迈阿密大学毕业证(本硕)umiami在读证明存档可查
ydyuyu
 
call girls in Anand Vihar (delhi) call me [🔝9953056974🔝] escort service 24X7
call girls in Anand Vihar (delhi) call me [🔝9953056974🔝] escort service 24X7call girls in Anand Vihar (delhi) call me [🔝9953056974🔝] escort service 24X7
call girls in Anand Vihar (delhi) call me [🔝9953056974🔝] escort service 24X7
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 
一比一原版田纳西大学毕业证如何办理
一比一原版田纳西大学毕业证如何办理一比一原版田纳西大学毕业证如何办理
一比一原版田纳西大学毕业证如何办理
F
 
Russian Call girls in Abu Dhabi 0508644382 Abu Dhabi Call girls
Russian Call girls in Abu Dhabi 0508644382 Abu Dhabi Call girlsRussian Call girls in Abu Dhabi 0508644382 Abu Dhabi Call girls
Russian Call girls in Abu Dhabi 0508644382 Abu Dhabi Call girls
Monica Sydney
 
Top profile Call Girls In Dindigul [ 7014168258 ] Call Me For Genuine Models ...
Top profile Call Girls In Dindigul [ 7014168258 ] Call Me For Genuine Models ...Top profile Call Girls In Dindigul [ 7014168258 ] Call Me For Genuine Models ...
Top profile Call Girls In Dindigul [ 7014168258 ] Call Me For Genuine Models ...
gajnagarg
 
Indian Escort in Abu DHabi 0508644382 Abu Dhabi Escorts
Indian Escort in Abu DHabi 0508644382 Abu Dhabi EscortsIndian Escort in Abu DHabi 0508644382 Abu Dhabi Escorts
Indian Escort in Abu DHabi 0508644382 Abu Dhabi Escorts
Monica Sydney
 
在线制作约克大学毕业证(yu毕业证)在读证明认证可查
在线制作约克大学毕业证(yu毕业证)在读证明认证可查在线制作约克大学毕业证(yu毕业证)在读证明认证可查
在线制作约克大学毕业证(yu毕业证)在读证明认证可查
ydyuyu
 
一比一原版(Offer)康考迪亚大学毕业证学位证靠谱定制
一比一原版(Offer)康考迪亚大学毕业证学位证靠谱定制一比一原版(Offer)康考迪亚大学毕业证学位证靠谱定制
一比一原版(Offer)康考迪亚大学毕业证学位证靠谱定制
pxcywzqs
 
Russian Escort Abu Dhabi 0503464457 Abu DHabi Escorts
Russian Escort Abu Dhabi 0503464457 Abu DHabi EscortsRussian Escort Abu Dhabi 0503464457 Abu DHabi Escorts
Russian Escort Abu Dhabi 0503464457 Abu DHabi Escorts
Monica Sydney
 
Abu Dhabi Escorts Service 0508644382 Escorts in Abu Dhabi
Abu Dhabi Escorts Service 0508644382 Escorts in Abu DhabiAbu Dhabi Escorts Service 0508644382 Escorts in Abu Dhabi
Abu Dhabi Escorts Service 0508644382 Escorts in Abu Dhabi
Monica Sydney
 

Kürzlich hochgeladen (20)

APNIC Policy Roundup, presented by Sunny Chendi at the 5th ICANN APAC-TWNIC E...
APNIC Policy Roundup, presented by Sunny Chendi at the 5th ICANN APAC-TWNIC E...APNIC Policy Roundup, presented by Sunny Chendi at the 5th ICANN APAC-TWNIC E...
APNIC Policy Roundup, presented by Sunny Chendi at the 5th ICANN APAC-TWNIC E...
 
哪里办理美国迈阿密大学毕业证(本硕)umiami在读证明存档可查
哪里办理美国迈阿密大学毕业证(本硕)umiami在读证明存档可查哪里办理美国迈阿密大学毕业证(本硕)umiami在读证明存档可查
哪里办理美国迈阿密大学毕业证(本硕)umiami在读证明存档可查
 
best call girls in Hyderabad Finest Escorts Service 📞 9352988975 📞 Available ...
best call girls in Hyderabad Finest Escorts Service 📞 9352988975 📞 Available ...best call girls in Hyderabad Finest Escorts Service 📞 9352988975 📞 Available ...
best call girls in Hyderabad Finest Escorts Service 📞 9352988975 📞 Available ...
 
Tadepalligudem Escorts Service Girl ^ 9332606886, WhatsApp Anytime Tadepallig...
Tadepalligudem Escorts Service Girl ^ 9332606886, WhatsApp Anytime Tadepallig...Tadepalligudem Escorts Service Girl ^ 9332606886, WhatsApp Anytime Tadepallig...
Tadepalligudem Escorts Service Girl ^ 9332606886, WhatsApp Anytime Tadepallig...
 
call girls in Anand Vihar (delhi) call me [🔝9953056974🔝] escort service 24X7
call girls in Anand Vihar (delhi) call me [🔝9953056974🔝] escort service 24X7call girls in Anand Vihar (delhi) call me [🔝9953056974🔝] escort service 24X7
call girls in Anand Vihar (delhi) call me [🔝9953056974🔝] escort service 24X7
 
Story Board.pptxrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
Story Board.pptxrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrStory Board.pptxrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
Story Board.pptxrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
 
20240508 QFM014 Elixir Reading List April 2024.pdf
20240508 QFM014 Elixir Reading List April 2024.pdf20240508 QFM014 Elixir Reading List April 2024.pdf
20240508 QFM014 Elixir Reading List April 2024.pdf
 
一比一原版田纳西大学毕业证如何办理
一比一原版田纳西大学毕业证如何办理一比一原版田纳西大学毕业证如何办理
一比一原版田纳西大学毕业证如何办理
 
Russian Call girls in Abu Dhabi 0508644382 Abu Dhabi Call girls
Russian Call girls in Abu Dhabi 0508644382 Abu Dhabi Call girlsRussian Call girls in Abu Dhabi 0508644382 Abu Dhabi Call girls
Russian Call girls in Abu Dhabi 0508644382 Abu Dhabi Call girls
 
Top profile Call Girls In Dindigul [ 7014168258 ] Call Me For Genuine Models ...
Top profile Call Girls In Dindigul [ 7014168258 ] Call Me For Genuine Models ...Top profile Call Girls In Dindigul [ 7014168258 ] Call Me For Genuine Models ...
Top profile Call Girls In Dindigul [ 7014168258 ] Call Me For Genuine Models ...
 
Indian Escort in Abu DHabi 0508644382 Abu Dhabi Escorts
Indian Escort in Abu DHabi 0508644382 Abu Dhabi EscortsIndian Escort in Abu DHabi 0508644382 Abu Dhabi Escorts
Indian Escort in Abu DHabi 0508644382 Abu Dhabi Escorts
 
Vip Firozabad Phone 8250092165 Escorts Service At 6k To 30k Along With Ac Room
Vip Firozabad Phone 8250092165 Escorts Service At 6k To 30k Along With Ac RoomVip Firozabad Phone 8250092165 Escorts Service At 6k To 30k Along With Ac Room
Vip Firozabad Phone 8250092165 Escorts Service At 6k To 30k Along With Ac Room
 
在线制作约克大学毕业证(yu毕业证)在读证明认证可查
在线制作约克大学毕业证(yu毕业证)在读证明认证可查在线制作约克大学毕业证(yu毕业证)在读证明认证可查
在线制作约克大学毕业证(yu毕业证)在读证明认证可查
 
一比一原版(Offer)康考迪亚大学毕业证学位证靠谱定制
一比一原版(Offer)康考迪亚大学毕业证学位证靠谱定制一比一原版(Offer)康考迪亚大学毕业证学位证靠谱定制
一比一原版(Offer)康考迪亚大学毕业证学位证靠谱定制
 
20240507 QFM013 Machine Intelligence Reading List April 2024.pdf
20240507 QFM013 Machine Intelligence Reading List April 2024.pdf20240507 QFM013 Machine Intelligence Reading List April 2024.pdf
20240507 QFM013 Machine Intelligence Reading List April 2024.pdf
 
Real Men Wear Diapers T Shirts sweatshirt
Real Men Wear Diapers T Shirts sweatshirtReal Men Wear Diapers T Shirts sweatshirt
Real Men Wear Diapers T Shirts sweatshirt
 
Russian Escort Abu Dhabi 0503464457 Abu DHabi Escorts
Russian Escort Abu Dhabi 0503464457 Abu DHabi EscortsRussian Escort Abu Dhabi 0503464457 Abu DHabi Escorts
Russian Escort Abu Dhabi 0503464457 Abu DHabi Escorts
 
Abu Dhabi Escorts Service 0508644382 Escorts in Abu Dhabi
Abu Dhabi Escorts Service 0508644382 Escorts in Abu DhabiAbu Dhabi Escorts Service 0508644382 Escorts in Abu Dhabi
Abu Dhabi Escorts Service 0508644382 Escorts in Abu Dhabi
 
Trump Diapers Over Dems t shirts Sweatshirt
Trump Diapers Over Dems t shirts SweatshirtTrump Diapers Over Dems t shirts Sweatshirt
Trump Diapers Over Dems t shirts Sweatshirt
 
20240510 QFM016 Irresponsible AI Reading List April 2024.pdf
20240510 QFM016 Irresponsible AI Reading List April 2024.pdf20240510 QFM016 Irresponsible AI Reading List April 2024.pdf
20240510 QFM016 Irresponsible AI Reading List April 2024.pdf
 

Introduction to Web Components

  • 1. Felix Arntz / WordCamp London 2019 Web Components Introduction to
  • 2. Web Components are a standardized set of browser APIs that allow you to define your own HTML tags, reusable and self-contained.
  • 3. <p>Hovering <a href="#tooltip1" class="tooltip-source">this text</a> will display a tooltip.</p> <div id="tooltip1" class="tooltip"> <span class="tooltip-nag"></span> This is the tooltip content. </div> <style> .tooltip { position: absolute; display: none; max-width: 16rem; } /* many more style rules... */ </style> <script> document.querySelector( '.tooltip-source' ).addEventListener( 'hover', event => { event.preventDefault(); /* lots and lots more JavaScript... */ } ); </script> Example: Tooltips
  • 4. Example: Tooltips <my-tooltips> <p>Hovering <my-tooltip-anchor target="#tooltip1">this text</my-tooltip-anchor> will display a tooltip.</p> <my-tooltip id="tooltip1"> This is the tooltip content. </my-tooltip> </my-tooltips>
  • 5. Benefits of Web Components MaintainabilityReusability Encapsulation Standardization
  • 6. React vs. Vue vs. Web Components React Vue Web Components const { Component } = React; class MyComponent extends Component { … } Vue.component( ‘my-component’, { … } ); class MyComponent extends HTMLElement { … } customElements.define( ‘my-component’, MyComponent ); <MyComponent></MyComponent> <my-component></my-component> <my-component></my-component> JSX (pre-processing required) HTML templates HTML templates Framework Framework Standard Key Takeaway: This is an unfair and false comparison.
  • 7. Standardized Leaf Components const { Component } = React; class MyComponent extends Component { render() { const { active } = this.props; return ( <my-leaf-component active={ active }> </my-leaf-component> ); } } class MyLeafComponent extends HTMLElement { static get is() { return 'my-leaf-component'; } static get observedAttributes() { return [ 'active' ]; } } customElements.define( MyLeafComponent.is, MyLeafComponent ); React ❤ Web Components!
  • 9. Source: https://softwareengineeringdaily.com/2018/10/22/google-javascript-with-malte-ubl/ Many frameworks are modeled around some notion of components. [...] So there's one thing that I am very sure of, which is that we will see Web Components as the basically only technology used for what I would call leaf components. Malte Ubl “ ”Tech Lead of the AMP Project
  • 10. Shadow DOM Allows style and markup to be encapsulated from the regular DOM. Custom Elements Allows developers to define their own HTML tags. HTML Templates Allows to place markup in a page that is only parsed once necessary. Key Web APIs
  • 11. Current Browser Support See full browser support caniuse.com/#feat=custom-elementsv1 caniuse.com/#feat=shadowdomv1 caniuse.com/#feat=template Also, check out the polyfill! (github.com/webcomponents/custom-elements)
  • 13.
  • 14. <h2 class="nav-tab-wrapper"> <a class="nav-tab nav-tab-active" href="#tab1"> Introduction </a> <a class="nav-tab" href="#tab2"> Polymer </a> <!-- ... --> </h2> <div id="tab1" class="nav-tab-panel nav-tab-panel-active"><!-- Panel 1 content. --></div> <div id="tab2" class="nav-tab-panel"><!-- Panel 2 content. --></div> <!-- ... --> <h2 class="nav-tab-wrapper" role="tablist"> <a class="nav-tab nav-tab-active" href="#tab1" aria-controls="tab1" aria-selected="true" role="tab"> Introduction </a> <a class="nav-tab" href="#tab2" aria-controls="tab2" aria-selected="false" tabindex="-1" role="tab"> Polymer </a> <!-- ... --> </h2> <div id="tab1" class="nav-tab-panel nav-tab-panel-active" role="tabpanel"><!-- Panel 1 content. --></div> <div id="tab2" class="nav-tab-panel" aria-hidden="true" role="tabpanel"><!-- Panel 2 content. --></div> <!-- ... --> Typical WordPress Approach
  • 15. ● wcig-tab for a single tab ● wcig-tab-panel for a single panel associated with a tab ● wcig-tabs for the overall wrapper Three Custom Elements <wcig-tabs> <wcig-tab slot="tabs" href="#tab1" selected> Introduction </wcig-tab> <wcig-tab-panel slot="tabpanels" id="tab1" active> <!-- Panel 1 content. --> </wcig-tab-panel> <wcig-tab slot="tabs" href="#tab2"> Polymer </wcig-tab> <wcig-tab-panel slot="tabpanels" id="tab2"> <!-- Panel 2 content. --> </wcig-tab-panel> <!-- ... --> </wcig-tabs>
  • 17. The Custom Elements API 1. Create a class that extends HTMLElement 2. Implement the element’s behavior and style in that class 3. Register the element with customElements.define( tagName, elementClass )
  • 18. class Tab extends HTMLElement { constructor() { super(); // ... } static get is() { return 'wcig-tab'; } static get observedAttributes() { // ... } attributeChangedCallback( name, oldValue, newValue ) { // ... } connectedCallback() { // ... } disconnectedCallback() { // ... } } Scaffolding our Tab Element
  • 19. connectedCallback() { if ( ! this.hasAttribute( 'role' ) ) { this.setAttribute( 'role', 'tab' ); } const isSelected = this.hasAttribute( 'selected' ); if ( ! this.hasAttribute( 'tabindex' ) ) { this.setAttribute( 'tabindex', isSelected ? 0 : -1 ); } if ( ! this.hasAttribute( 'aria-selected' ) ) { this.setAttribute( 'aria-selected', isSelected ? 'true' : 'false' ); } this.addEventListener( 'click', this._onClick ); } disconnectedCallback() { this.removeEventListener( 'click', this._onClick ); } Handling Custom Markup and Events
  • 20. _onClick() { if ( this.disabled || this.selected ) { return; } this.selected = true; this.dispatchEvent( new CustomEvent( 'select', { bubbles: true } ) ); } Emitting a Tab Selection Event
  • 21. static get observedAttributes() { return [ 'selected', 'disabled' ]; } attributeChangedCallback( name, oldValue, newValue ) { switch ( name ) { case 'selected': this.setAttribute( 'tabindex', null !== newValue ? 0 : -1 ); this.setAttribute( 'aria-selected', null !== newValue ? 'true' : 'false' ); break; case 'disabled': this.setAttribute( 'aria-disabled', null !== newValue ? 'true' : 'false' ); if ( null !== newValue || ! this.selected ) { this.removeAttribute( 'tabindex' ); this.blur(); } else { this.setAttribute( 'tabindex', 0 ); } break; } } Reacting to Attribute Changes
  • 22. class Tab extends HTMLElement { // ... get selected() { return this.hasAttribute( 'selected' ); } set selected( val ) { const isSelected = Boolean( val ); if ( isSelected ) { this.setAttribute( 'selected', '' ); } else { this.removeAttribute( 'selected' ); } } } Reflecting Properties to Attributes const tab = document.createElement( 'wcig-tab' ); tab.selected = true; <wcig-tab selected></wcig-tab>
  • 23. class Tab extends HTMLElement { // ... } customElements.define( Tab.is, Tab ); Registering The Custom Element
  • 25. What is the Shadow DOM? ● In addition to regular DOM node children, an element can have a separate shadow tree attached to it. ● The element the shadow tree is attached to is called the shadow host. ● The document fragment attached to the shadow host is called the shadow root. ● Elements in the shadow tree are scoped to the shadow host element and cannot be accessed from the outside.
  • 26. Example: The Built-in Range Input Shadow trees have been used for quite a while by browsers already!
  • 27. Providing Scoped Styles and Markup class Tab extends HTMLElement { constructor() { super(); this.attachShadow( { mode: 'open' } ); this.shadowRoot.innerHTML = ` <style> :host { display: block; /* ... */ } :host(:focus), :host(:hover) { /* ... */ } :host([selected]) { /* ... */ } </style> <slot></slot> `; } // ... }
  • 29. The template Element <template id="my-template"> <div id="element-from-template"> <p>Element content.</p> </div> </template> const template = document.querySelector( '#my-template' ); const element = template.content.cloneNode( true );
  • 30. Improving Performance with a Template const template = document.createElement( 'template' ); template.innerHTML = ` <style> :host { display: block; /* ... */ } /* ... */ </style> <slot></slot> `; class Tab extends HTMLElement { constructor() { super(); this.attachShadow( { mode: 'open' } ); this.shadowRoot.appendChild( template.content.cloneNode( true ) ); } // ... }
  • 31. To Be Continued... Look up the full codebase at github.com/felixarntz/web-components-in-gutenberg
  • 32. Further Reading ● https://developers.google.com/web/fundamentals/web-components/customelements ● https://developers.google.com/web/fundamentals/web-components/shadowdom ● https://developers.google.com/web/fundamentals/web-components/best-practices ● https://developers.google.com/web/fundamentals/primers/async-functions ● https://developers.google.com/web/fundamentals/primers/modules ● https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals ● https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set ● https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get
  • 33. Proprietary + Confidential Web Components Projects
  • 38.
  • 39. Get Started with Web Components MaintainabilityReusability Encapsulation Standardization
  • 40. Proprietary + Confidential Thank You Felix Arntz @felixarntz