Introduction to Web Components

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!
Introduction to Web Components
<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
Introduction to Web Components
Get Started with Web Components
MaintainabilityReusability Encapsulation Standardization
Proprietary + Confidential
Thank You
Felix Arntz
@felixarntz
1 of 40

Recommended

jQuery and Rails, Sitting in a Tree by
jQuery and Rails, Sitting in a TreejQuery and Rails, Sitting in a Tree
jQuery and Rails, Sitting in a Treeadamlogic
1.8K views47 slides
Backbone - TDC 2011 Floripa by
Backbone - TDC 2011 FloripaBackbone - TDC 2011 Floripa
Backbone - TDC 2011 FloripaRafael Felix da Silva
759 views102 slides
jQuery Presentasion by
jQuery PresentasionjQuery Presentasion
jQuery PresentasionMohammad Usman
328 views89 slides
Building iPhone Web Apps using "classic" Domino by
Building iPhone Web Apps using "classic" DominoBuilding iPhone Web Apps using "classic" Domino
Building iPhone Web Apps using "classic" DominoRob Bontekoe
1.6K views21 slides
Single page webapps & javascript-testing by
Single page webapps & javascript-testingSingle page webapps & javascript-testing
Single page webapps & javascript-testingsmontanari
7K views49 slides
Drupal & javascript by
Drupal & javascriptDrupal & javascript
Drupal & javascriptAlmog Baku
4.8K views53 slides

More Related Content

What's hot

Aplicacoes dinamicas Rails com Backbone by
Aplicacoes dinamicas Rails com BackboneAplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com BackboneRafael Felix da Silva
1.1K views95 slides
Django Class-based views (Slovenian) by
Django Class-based views (Slovenian)Django Class-based views (Slovenian)
Django Class-based views (Slovenian)Luka Zakrajšek
1.1K views26 slides
Virtual Madness @ Etsy by
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ EtsyNishan Subedi
524 views28 slides
WordPress Capabilities Magic by
WordPress Capabilities MagicWordPress Capabilities Magic
WordPress Capabilities Magicmannieschumpert
920 views30 slides
Bag Of Tricks From Iusethis by
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From IusethisMarcus Ramberg
6.4K views88 slides
HirshHorn theme: how I created it by
HirshHorn theme: how I created itHirshHorn theme: how I created it
HirshHorn theme: how I created itPaul Bearne
2.8K views39 slides

What's hot(20)

Django Class-based views (Slovenian) by Luka Zakrajšek
Django Class-based views (Slovenian)Django Class-based views (Slovenian)
Django Class-based views (Slovenian)
Luka Zakrajšek1.1K views
Bag Of Tricks From Iusethis by Marcus Ramberg
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From Iusethis
Marcus Ramberg6.4K views
HirshHorn theme: how I created it by Paul Bearne
HirshHorn theme: how I created itHirshHorn theme: how I created it
HirshHorn theme: how I created it
Paul Bearne2.8K views
Propel sfugmd by iKlaus
Propel sfugmdPropel sfugmd
Propel sfugmd
iKlaus464 views
Backbone.js Simple Tutorial by 추근 문
Backbone.js Simple TutorialBackbone.js Simple Tutorial
Backbone.js Simple Tutorial
추근 문4.7K views
前端MVC 豆瓣说 by Ting Lv
前端MVC 豆瓣说前端MVC 豆瓣说
前端MVC 豆瓣说
Ting Lv3.7K views
50 Laravel Tricks in 50 Minutes by Azim Kurtaliev
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes
Azim Kurtaliev1.7K views
Gail villanueva add muscle to your wordpress site by references
Gail villanueva   add muscle to your wordpress siteGail villanueva   add muscle to your wordpress site
Gail villanueva add muscle to your wordpress site
references2.8K views
Dig Deeper into WordPress - WD Meetup Cairo by Mohamed Mosaad
Dig Deeper into WordPress - WD Meetup CairoDig Deeper into WordPress - WD Meetup Cairo
Dig Deeper into WordPress - WD Meetup Cairo
Mohamed Mosaad934 views
Ajax nested form and ajax upload in rails by Tse-Ching Ho
Ajax nested form and ajax upload in railsAjax nested form and ajax upload in rails
Ajax nested form and ajax upload in rails
Tse-Ching Ho7.4K views
J query b_dotnet_ug_meet_12_may_2012 by ghnash
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
ghnash1.1K views

Similar to Introduction to Web Components

HTML5 and the dawn of rich mobile web applications pt 2 by
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 2James Pearce
10.1K views67 slides
Polymer by
PolymerPolymer
PolymerCyril Balit
1.3K views67 slides
Vaadin Components @ Angular U by
Vaadin Components @ Angular UVaadin Components @ Angular U
Vaadin Components @ Angular UJoonas Lehtinen
2.1K views79 slides
Jarv.us Showcase — SenchaCon 2011 by
Jarv.us Showcase — SenchaCon 2011Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Chris Alfano
355 views85 slides
Symfony2 Building on Alpha / Beta technology by
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologyDaniel Knell
750 views59 slides
jQuery: Tips, tricks and hints for better development and Performance by
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 PerformanceJonas De Smet
3.5K views33 slides

Similar to Introduction to Web Components(20)

HTML5 and the dawn of rich mobile web applications pt 2 by James Pearce
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 Pearce10.1K views
Vaadin Components @ Angular U by Joonas Lehtinen
Vaadin Components @ Angular UVaadin Components @ Angular U
Vaadin Components @ Angular U
Joonas Lehtinen2.1K views
Jarv.us Showcase — SenchaCon 2011 by Chris Alfano
Jarv.us Showcase — SenchaCon 2011Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011
Chris Alfano355 views
Symfony2 Building on Alpha / Beta technology by Daniel Knell
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technology
Daniel Knell750 views
jQuery: Tips, tricks and hints for better development and Performance by Jonas De Smet
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
Jonas De Smet3.5K views
How to increase Performance of Web Application using JQuery by kolkatageeks
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
kolkatageeks1.9K views
Building complex User Interfaces with Sitecore and React by Jonne Kats
Building complex User Interfaces with Sitecore and ReactBuilding complex User Interfaces with Sitecore and React
Building complex User Interfaces with Sitecore and React
Jonne Kats204 views
How to Mess Up Your Angular UI Components by cagataycivici
How to Mess Up Your Angular UI ComponentsHow to Mess Up Your Angular UI Components
How to Mess Up Your Angular UI Components
cagataycivici842 views
Your Custom WordPress Admin Pages Suck by Anthony Montalbano
Your Custom WordPress Admin Pages SuckYour Custom WordPress Admin Pages Suck
Your Custom WordPress Admin Pages Suck
Anthony Montalbano10.4K views
AnkaraJUG Kasım 2012 - PrimeFaces by Ankara JUG
AnkaraJUG Kasım 2012 - PrimeFacesAnkaraJUG Kasım 2012 - PrimeFaces
AnkaraJUG Kasım 2012 - PrimeFaces
Ankara JUG1.8K views
Modern frontend development with VueJs by Tudor Barbu
Modern frontend development with VueJsModern frontend development with VueJs
Modern frontend development with VueJs
Tudor Barbu1.6K views
jQuery in the [Aol.] Enterprise by Dave Artz
jQuery in the [Aol.] EnterprisejQuery in the [Aol.] Enterprise
jQuery in the [Aol.] Enterprise
Dave Artz6K views
How Not to Build a WordPress Plugin by Will Norris
How Not to Build a WordPress PluginHow Not to Build a WordPress Plugin
How Not to Build a WordPress Plugin
Will Norris4.1K views

More from Felix Arntz

Tackling performance in the WordPress ecosystem at scale by
Tackling performance in the WordPress ecosystem at scaleTackling performance in the WordPress ecosystem at scale
Tackling performance in the WordPress ecosystem at scaleFelix Arntz
82 views32 slides
Enhancing performance in an open-source CMS ecosystem by
Enhancing performance in an open-source CMS ecosystemEnhancing performance in an open-source CMS ecosystem
Enhancing performance in an open-source CMS ecosystemFelix Arntz
653 views46 slides
The WordPress Performance Team by
The WordPress Performance TeamThe WordPress Performance Team
The WordPress Performance TeamFelix Arntz
560 views11 slides
Accessing APIs using OAuth on the federated (WordPress) web by
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) webFelix Arntz
251 views31 slides
AMP for JavaScripters by
AMP for JavaScriptersAMP for JavaScripters
AMP for JavaScriptersFelix Arntz
1.1K views40 slides
Leveraging the Power of Custom Elements in Gutenberg by
Leveraging the Power of Custom Elements in GutenbergLeveraging the Power of Custom Elements in Gutenberg
Leveraging the Power of Custom Elements in GutenbergFelix Arntz
2.1K views35 slides

More from Felix Arntz(7)

Tackling performance in the WordPress ecosystem at scale by Felix Arntz
Tackling performance in the WordPress ecosystem at scaleTackling performance in the WordPress ecosystem at scale
Tackling performance in the WordPress ecosystem at scale
Felix Arntz82 views
Enhancing performance in an open-source CMS ecosystem by Felix Arntz
Enhancing performance in an open-source CMS ecosystemEnhancing performance in an open-source CMS ecosystem
Enhancing performance in an open-source CMS ecosystem
Felix Arntz653 views
The WordPress Performance Team by Felix Arntz
The WordPress Performance TeamThe WordPress Performance Team
The WordPress Performance Team
Felix Arntz560 views
Accessing APIs using OAuth on the federated (WordPress) web by Felix Arntz
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
Felix Arntz251 views
AMP for JavaScripters by Felix Arntz
AMP for JavaScriptersAMP for JavaScripters
AMP for JavaScripters
Felix Arntz1.1K views
Leveraging the Power of Custom Elements in Gutenberg by Felix Arntz
Leveraging the Power of Custom Elements in GutenbergLeveraging the Power of Custom Elements in Gutenberg
Leveraging the Power of Custom Elements in Gutenberg
Felix Arntz2.1K views
Web Policies & Reporting by Felix Arntz
Web Policies & ReportingWeb Policies & Reporting
Web Policies & Reporting
Felix Arntz146 views

Recently uploaded

Existing documentaries (1).docx by
Existing documentaries (1).docxExisting documentaries (1).docx
Existing documentaries (1).docxMollyBrown86
13 views5 slides
𝐒𝐨𝐥𝐚𝐫𝐖𝐢𝐧𝐝𝐬 𝐂𝐚𝐬𝐞 𝐒𝐭𝐮𝐝𝐲 by
𝐒𝐨𝐥𝐚𝐫𝐖𝐢𝐧𝐝𝐬 𝐂𝐚𝐬𝐞 𝐒𝐭𝐮𝐝𝐲𝐒𝐨𝐥𝐚𝐫𝐖𝐢𝐧𝐝𝐬 𝐂𝐚𝐬𝐞 𝐒𝐭𝐮𝐝𝐲
𝐒𝐨𝐥𝐚𝐫𝐖𝐢𝐧𝐝𝐬 𝐂𝐚𝐬𝐞 𝐒𝐭𝐮𝐝𝐲Infosec train
7 views6 slides
information by
informationinformation
informationkhelgishekhar
7 views4 slides
Opportunities for Youth in IG - Alena Muravska RIPE NCC.pdf by
Opportunities for Youth in IG - Alena Muravska RIPE NCC.pdfOpportunities for Youth in IG - Alena Muravska RIPE NCC.pdf
Opportunities for Youth in IG - Alena Muravska RIPE NCC.pdfRIPE NCC
9 views12 slides
childcare.pdf by
childcare.pdfchildcare.pdf
childcare.pdffatma alnaqbi
14 views4 slides
WEB 2.O TOOLS: Empowering education.pptx by
WEB 2.O TOOLS: Empowering education.pptxWEB 2.O TOOLS: Empowering education.pptx
WEB 2.O TOOLS: Empowering education.pptxnarmadhamanohar21
15 views16 slides

Recently uploaded(20)

Existing documentaries (1).docx by MollyBrown86
Existing documentaries (1).docxExisting documentaries (1).docx
Existing documentaries (1).docx
MollyBrown8613 views
𝐒𝐨𝐥𝐚𝐫𝐖𝐢𝐧𝐝𝐬 𝐂𝐚𝐬𝐞 𝐒𝐭𝐮𝐝𝐲 by Infosec train
𝐒𝐨𝐥𝐚𝐫𝐖𝐢𝐧𝐝𝐬 𝐂𝐚𝐬𝐞 𝐒𝐭𝐮𝐝𝐲𝐒𝐨𝐥𝐚𝐫𝐖𝐢𝐧𝐝𝐬 𝐂𝐚𝐬𝐞 𝐒𝐭𝐮𝐝𝐲
𝐒𝐨𝐥𝐚𝐫𝐖𝐢𝐧𝐝𝐬 𝐂𝐚𝐬𝐞 𝐒𝐭𝐮𝐝𝐲
Infosec train7 views
Opportunities for Youth in IG - Alena Muravska RIPE NCC.pdf by RIPE NCC
Opportunities for Youth in IG - Alena Muravska RIPE NCC.pdfOpportunities for Youth in IG - Alena Muravska RIPE NCC.pdf
Opportunities for Youth in IG - Alena Muravska RIPE NCC.pdf
RIPE NCC9 views
We see everywhere that many people are talking about technology.docx by ssuserc5935b
We see everywhere that many people are talking about technology.docxWe see everywhere that many people are talking about technology.docx
We see everywhere that many people are talking about technology.docx
ssuserc5935b6 views
IGF UA - Dialog with I_ organisations - Alena Muavska RIPE NCC.pdf by RIPE NCC
IGF UA - Dialog with I_ organisations - Alena Muavska RIPE NCC.pdfIGF UA - Dialog with I_ organisations - Alena Muavska RIPE NCC.pdf
IGF UA - Dialog with I_ organisations - Alena Muavska RIPE NCC.pdf
RIPE NCC15 views
Building trust in our information ecosystem: who do we trust in an emergency by Tina Purnat
Building trust in our information ecosystem: who do we trust in an emergencyBuilding trust in our information ecosystem: who do we trust in an emergency
Building trust in our information ecosystem: who do we trust in an emergency
Tina Purnat85 views
Serverless cloud architecture patterns by Jimmy Dahlqvist
Serverless cloud architecture patternsServerless cloud architecture patterns
Serverless cloud architecture patterns
Jimmy Dahlqvist17 views
UiPath Document Understanding_Day 3.pptx by UiPathCommunity
UiPath Document Understanding_Day 3.pptxUiPath Document Understanding_Day 3.pptx
UiPath Document Understanding_Day 3.pptx
UiPathCommunity95 views
AI Powered event-driven translation bot by Jimmy Dahlqvist
AI Powered event-driven translation botAI Powered event-driven translation bot
AI Powered event-driven translation bot
Jimmy Dahlqvist16 views
PORTFOLIO 1 (Bret Michael Pepito).pdf by brejess0410
PORTFOLIO 1 (Bret Michael Pepito).pdfPORTFOLIO 1 (Bret Michael Pepito).pdf
PORTFOLIO 1 (Bret Michael Pepito).pdf
brejess04107 views
google forms survey (1).pptx by MollyBrown86
google forms survey (1).pptxgoogle forms survey (1).pptx
google forms survey (1).pptx
MollyBrown8614 views

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)
  • 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
  • 39. Get Started with Web Components MaintainabilityReusability Encapsulation Standardization
  • 40. Proprietary + Confidential Thank You Felix Arntz @felixarntz