SlideShare a Scribd company logo
1 of 144
Download to read offline
Creating container
components
in Web Components and Angular
ng-conf: March 5, 2015
Kara Erickson
Web Engineer
kara
karaforthewin
Rachael L Moore
UI Engineer
morewry
morewry
Roadmap
Web Components
Angular 1.3
Angular 2.0
<!-- #include virtual="head.html" -->
<!-- #include virtual="menu.html" -->
I render in body.
<!-- #include virtual="foot.html" -->
Server Side Includes
{{> head}}
{{> menu}}
I render in body.
{{> foot}}
mustache
UI Components
<ot-site>
I render in body.
</ot-site>
Native Elements
<input type="range" />
<input type="range" min="1"
max="8" />
<div id="site">
</div>
Component Development
<div id="site">
<header></header>
</div>
Head 
Component Development
<div id="site">
<header></header>
<nav></nav>>
</div>
Component Development
Menu 
<div id="site">
<header></header>
<nav></nav>
<main></main>
</div>
Component Development
Body 
<div id="site">
<header></header>
<nav></nav>
<main></main>
</div>
Component Development
<div id="site">
<header>
<svg id="logo"></svg>
</header>
<nav></nav>
<main></main>
</div>
Component Development
<div id="site">
<header>
<svg id="logo"></svg>
</header>
<nav></nav>
<main></main>
<footer>
© 2015 OpenTable, Inc.
</footer>
</div>
Component Development
<div id="site">
<header>
<svg id="logo"></svg>
</header>
<nav></nav>
<main></main>
<footer>
© 2015 OpenTable, Inc.
</footer>
</div>
Component Development
<div id="site">
<header>
<svg id="logo"></svg>
<!-- point-1 -->
</header>
<nav>
<!-- point-2 -->
</nav>
<main>
<!-- point-3 -->
</main>
<footer>
© 2015 OpenTable, Inc.
</footer>
</div>
Component Development
Component Use
<ot-site>
</ot-site>
Component Use
<ot-site>
<div>
I render in head.
</div>
<div>
I render in menu.
</div>
<div>
I render in body.
</div>
</ot-site>
I render in head.
I render in menu.
I render in body.
Component Use
<ot-site>
<div>
<!-- insert-1 -->
I render in head.
</div>
<div>
<!-- insert-2 -->
I render in menu.
</div>
<div>
<!-- insert-3 -->
I render in body.
</div>
</ot-site>
I render in head.
I render in menu.
I render in body.
<div id="site">
<header>
<svg id="logo"></svg>
<!-- point-1 -->
</header>
<nav>
<!-- point-2 -->
</nav>
<main>
<!-- point-3 -->
</main>
<footer>
© 2015 OpenTable, Inc.
</footer>
</div>
<ot-site>
<div>
<!-- insert-1 -->
I render in head.
</div>
<div>
<!-- insert-2 -->
I render in menu.
</div>
<div>
<!-- insert-3 -->
I render in body.
</div>
</ot-site>
Match Content → ← Match Component
Head 
Menu 
Body 
Web Components
Shadow DOM
<ot-site>
Native Elements
<input type="range" />
Secrets and Shadows
Shadow DOM
Light DOM
Shadow DOM
Light DOM
<input type="range" />
<input type="range" />
#shadow-root (user-agent)
<div pseudo="track" id="track">
<div pseudo="thumb" id="thumb">
</div>
</div>
UA Shadow DOM
...had flourished.
<span id="myspan">
Long ago there was something in me, but now that thing is
gone.
</span>
I cannot...
Shadow Host
var $ = document.querySelector.bind(document)
var span = $("#myspan")
span.createShadowRoot()
Shadow Root
...had flourished.
<span id="myspan">
Long ago there was something in me, but now that thing is
gone.
</span>
I cannot...
Shadow Host
...had flourished.
<span id="myspan">
#shadow-root
Long ago there was something in me, but now that thing is
gone.
</span>
I cannot...
Shadow Root
Before
...had flourished. Long
ago there was something
in me, but now that thing
is gone. I cannot...
After
...had flourished. I
cannot...
var host = $("ot-site")
host.createShadowRoot()
host.shadowRoot.innerHTML = ``
ot-site.js
host.shadowRoot.innerHTML = .``.
ot-site.js
host.shadowRoot.innerHTML = `
<div id="site">
<header>
<svg id="logo"></svg>
<!-- point-1 -->
</header>
<nav>
<!-- point-2 -->
</nav>
<main>
<!-- point-3 -->
</main>
<footer>
© 2015 OpenTable, Inc.
</footer>
</div>
`
ot-site.js
host.shadowRoot.innerHTML = `
<div id="site">
<header>
<svg id="logo"></svg>
<!-- point-1 -->
</header>
<nav>
<!-- point-2 -->
</nav>
<main>
<!-- point-3 -->
</main>
<footer>
© 2015 OpenTable, Inc.
</footer>
</div>
`
ot-site.js
host.shadowRoot.innerHTML += `
<style>
/* use your imagination */
</style>
`
ot-site.js
<ot-site>
#shadow-root
<div id="site">
<header>
<svg id="logo"></svg>
</header>
<nav></nav>
<main></main>
<footer>©</footer>
</div>
<style>/**/</style>
</ot-site>
Composed DOM
host.shadowRoot.innerHTML = `
<div id="site">
<header>
<svg id="logo"></svg>
<!-- point-1 -->
</header>
<nav>
<!-- point-2 -->
</nav>
<main>
<!-- point-3 -->
</main>
<footer>
© 2015 OpenTable, Inc.
</footer>
</div>
`
ot-site.js
host.shadowRoot.innerHTML = `
<div id="site">
<header>
<svg id="logo"></svg>
<content />
</header>
<nav>
<content />
</nav>
<main>
<content />
</main>
<footer>
© 2015 OpenTable, Inc.
</footer>
</div>
`
ot-site.js
host.shadowRoot.innerHTML = `
<div id="site">
<header>
<svg id="logo"></svg>
<content select="" />
</header>
<nav>
<content select="" />
</nav>
<main>
<content select="" />
</main>
<footer>
© 2015 OpenTable, Inc.
</footer>
</div>
`
ot-site.js
host.shadowRoot.innerHTML = `
<div id="site">
<header>
<svg id="logo"></svg>
<content select="[head]" />
</header>
<nav>
<content select="[menu]" />
</nav>
<main>
<content select="[body]" />
</main>
<footer>
© 2015 OpenTable, Inc.
</footer>
</div>
`
ot-site.js
<ot-site>
<div>
<!-- insert-1 -->
I render in head.
</div>
<div>
<!-- insert-2 -->
I render in menu.
</div>
<div>
<!-- insert-3 -->
I render in body.
</div>
</ot-site>
index.html
<ot-site>
<div head>
I render in head.
</div>
<div menu>
I render in menu.
</div>
<div body>
I render in body.
</div>
</ot-site>
index.html
Match Content →
<div id="site">
<header>
<svg id="logo"></svg>
<content select="[head]"/>
</header>
<nav>
<content select="[menu]"/>
</nav>
<main>
<content select="[body]"/>
</main>
<footer>
© 2015 OpenTable, Inc.
</footer>
</div>
<ot-site>
<div head>
I render in head.
</div>
<div menu>
I render in menu.
</div>
<div body>
I render in body.
</div>
</ot-site>
← Match Component
Light DOMShadow DOM
<div id="site">
  <header>
    <svg id="logo"></svg>
    <content select="[head]"/>
</header>
<nav>
<content select="[menu]"/>
</nav>
<main>
<content select="[body]"/>
</main>
<footer>
© 2015 OpenTable, Inc.
</footer>
</div>
<ot-site>
<div head>
I render in head.
</div>
<div menu>
I render in menu.
</div>
<div body>
I render in body.
</div>
</ot-site>
<div id="site">
<header>
<svg id="logo"></svg>
<content select="[head]"/>
</header>
<nav>
<content select="[menu]"/>
</nav>
<main>
<content select="[body]"/>
</main>
<footer>
© 2015 OpenTable, Inc.
</footer>
</div>
Light DOMShadow DOM
<ot-site>
<div head>
I render in head.
</div>
<div menu>
I render in menu.
</div>
<div body>
I render in body.
</div>
</ot-site>
I render in head.
I render in menu.
I render in body.
I render in head.
I render in menu.
I render in body.
Code Demo: Content Projection
Code Demo: Final
Angular 1.3
Transcluding Directive
<ot-site>
.directive("otSite", function() {
return {
template: ``
};
});
ot-site.js
.directive("otSite", function() {
return {
template: `
<div id="site">
<header> <!-- point-1 -->
<svg id="logo"></svg>
</header>
<nav></nav> <!-- point-2 -->
<main></main> <!-- point-3 -->
<footer>
© 2015 OpenTable, Inc.
</footer>
</div>`
};
});
ot-site.js
Transclusion
<ot-site>
</ot-site>
index.html
<ot-site>
<div>
I render in head.
</div>
<div>
I render in menu.
</div>
<div>
I render in body.
</div>
</ot-site>
index.html
<ot-site>
<div>
I render in head.
</div>
<div>
I render in menu.
</div>
<div>
I render in body.
</div>
</ot-site>
index.html
ot-site.js
.directive("otSite", function() {
return {
template: `
<div id="site">
<header>
<svg id="logo"></svg>
</header>
<nav></nav>
<main></main>
<footer>
© 2015 OpenTable, Inc.
</footer>
</div>`
};
});
ot-site.js
.directive("otSite", function() {
return {
transclude: true,
template: `
<div id="site">
<header>
<svg id="logo"></svg>
</header>
<nav></nav>
<main></main>
<footer>
© 2015 OpenTable, Inc.
</footer>
</div>`
};
});
<ot-site>
<div>
I render in head.
</div>
<div>
I render in menu.
</div>
<div>
I render in body.
</div>
</ot-site>
DOM
<ot-site>
<div>
I render in head.
</div>
<div>
I render in menu.
</div>
<div>
I render in body.
</div>
</ot-site>
DOM
DOM
<ot-site>
<div id="site">
<header>
<svg id="logo"></svg>
</header>
<nav></nav>
<main></main>
<footer>©</footer>
</div>
</ot-site>
<ot-site>
<div>
I render in head.
</div>
<div>
I render in menu.
</div>
<div>
I render in body.
</div>
</ot-site>
DOM
<ot-site>
<div>
I render in head.
</div>
<div>
I render in menu.
</div>
<div>
I render in body.
</div>
</ot-site>
Clone DOM
<ot-site>
<div>
I render in head.
</div>
<div>
I render in menu.
</div>
<div>
I render in body.
</div>
</ot-site>
Clone DOM
Clone DOM
<div>
I render in head.
</div>
<div>
I render in menu.
</div>
<div>
I render in body.
</div>
<ot-site>
<div>
I render in head.
</div>
<div>
I render in menu.
</div>
<div>
I render in body.
</div>
</ot-site>
<div>
I render in head.
</div>
<div>
I render in menu.
</div>
<div>
I render in body.
</div>
<ot-site>
</ot-site>
Clone DOM
<ot-site>
<div id="site">
<header>
<svg id="logo"></svg>
</header>
<nav></nav>
<main></main>
<footer>©</footer>
</div>
</ot-site>
Clone
<div>
I render in head.
</div>
<div>
I render in menu.
</div>
<div>
I render in body.
</div>
DOM
ot-site.js
.directive("otSite", function() {
return {
transclude: true,
template: `
<div id="site">
<header>
<svg id="logo"></svg>
</header>
<nav></nav>
<main></main>
<footer>
© 2015 OpenTable, Inc.
</footer>
</div>`
};
});
ot-site.js
.directive("otSite", function() {
return {
transclude: true,
template: `
<div id="site">
<header ng-transclude>
<svg id="logo"></svg>
</header>
<nav ng-transclude></nav>
<main ng-transclude></main>
<footer>
© 2015 OpenTable, Inc.
</footer>
</div>`
};
});
 
Code Demo
ot-site.js
.directive("otSite", function() {
return {
transclude: true,
template: `
<div id="site">
<header ng-transclude>
<svg id="logo"></svg>
</header>
<nav ng-transclude></nav>
<main ng-transclude></main>
<footer>
© 2015 OpenTable, Inc.
</footer>
</div>`
};
});
ot-site.js
.directive("otSite", function() {
return {
transclude: true,
template: `
<div id="site">
<header>
<svg id="logo"></svg>
</header>
<nav></nav>
<main></main>
<footer>
© 2015 OpenTable, Inc.
</footer>
</div>`
};
});
ot-site.js
.directive("otSite", function() {
return {
transclude: true,
template: `
<div id="site">
<header t-id="head">
<svg id="logo"></svg>
</header>
<nav t-id="menu"></nav>
<main t-id="body"></main>
<footer>
© 2015 OpenTable, Inc.
</footer>
</div>`
};
});
<ot-site>
<div>
<!-- insert-1 -->
I render in head.
</div>
<div>
<!-- insert-2 -->
I render in menu.
</div>
<div>
<!-- insert-3 -->
I render in body.
</div>
</ot-site>
index.html
<ot-site>
<div t-to="head">
I render in head.
</div>
<div t-to="menu">
I render in menu.
</div>
<div t-to="body">
I render in body.
</div>
</ot-site>
index.html
<div t-to="head">
I render in head.
</div>
<div t-to="menu">
I render in menu.
</div>
<div t-to="body">
I render in body.
</div>
<ot-site>
<div id="site">
<header t-id="head">
<svg id="logo"></svg>
</header>
<nav t-id="menu"></nav>
<main t-id="body"></main>
<footer>©</footer>
</div>
</ot-site>
DOMClone
<div t-to="head">
I render in head.
</div>
<div t-to="menu">
I render in menu.
</div>
<div t-to="body">
I render in body.
</div>
<ot-site>
<div id="site">
<header t-id="head">
<svg id="logo"></svg>
</header>
<nav t-id="menu"></nav>
<main t-id="body"></main>
<footer>©</footer>
</div>
</ot-site>
DOMClone
angular.forEach(clone, function(cloneEl) {});
<div t-to="head">
I render in head.
</div>
<div t-to="menu">
I render in menu.
</div>
<div t-to="body">
I render in body.
</div>
<ot-site>
<div id="site">
<header t-id="head">
<svg id="logo"></svg>
</header>
<nav t-id="menu"></nav>
<main t-id="body"></main>
<footer>©</footer>
</div>
</ot-site>
DOMClone
angular.forEach(clone, function(cloneEl) {});
<div t-to="head">
I render in head.
</div>
<div t-to="menu">
I render in menu.
</div>
<div t-to="body">
I render in body.
</div>
<ot-site>
<div id="site">
<header t-id="head">
<svg id="logo"></svg>
</header>
<nav t-id="menu"></nav>
<main t-id="body"></main>
<footer>©</footer>
</div>
</ot-site>
DOMClone
angular.forEach(clone, function(cloneEl) {});
<ot-site>
<div id="site">
<header t-id="head">
<svg id="logo"></svg>
</header>
<nav t-id="menu"></nav>
<main t-id="body"></main>
<footer>©</footer>
</div>
</ot-site>
DOMClone
var tId = cloneEl.attributes["t-to"].value;
<div t-to="head">
I render in head.
</div>
<div t-to="menu">
I render in menu.
</div>
<div t-to="body">
I render in body.
</div>
DOMClone
var target = temp.find('[t-id="'+tId+'"]');
<div t-to="head">
I render in head.
</div>
<div t-to="menu">
I render in menu.
</div>
<div t-to="body">
I render in body.
</div>
<ot-site>
<div id="site">
<header t-id="head">
<svg id="logo"></svg>
</header>
<nav t-id="menu"></nav>
<main t-id="body"></main>
<footer>©</footer>
</div>
</ot-site>
<ot-site>
<div id="site">
<header t-id="head">
<svg id="logo"></svg>
</header>
<nav t-id="menu"></nav>
<main t-id="body"></main>
<footer>©</footer>
</div>
</ot-site>
<div t-to="head">
I render in head.
</div>
<div t-to="menu">
I render in menu.
</div>
<div t-to="body">
I render in body.
</div>
DOMClone
target.append(clone);
<div t-to="head">
I render in head.
</div>
<div t-to="menu">
I render in menu.
</div>
<div t-to="body">
I render in body.
</div>
DOMClone
<ot-site>
<div id="site">
<header t-id="head">
<svg id="logo"></svg>
<div t-to="head">
I render in head.
</div>
</header>
<nav t-id="menu"></nav>
<main t-id="body"></main>
<footer>©</footer>
</div>
</ot-site>
</ot-site>target.append(clone);
angular.forEach(clone, function(cloneEl) {
// get desired target ID
var tId = cloneEl.attributes["t-to"].value;
// find target element with that ID
var target = temp.find('[t-id="'+tId+'"]');
// append element to target
target.append(cloneEl);
});
custom-transclude.js
Transclude function
transclude(function(clone) {
# DOM manipulation
});
Transclude function access points
compile: function(tElem, tAttrs, transclude)
controller: function($scope, $element, $transclude)
link: function(scope, iElem, iAttrs, ctrl, transclude)
compile: function(tElem, tAttrs, transclude)
controller: function($scope, $element, $transclude)
link: function(scope, iElem, iAttrs, ctrl, transclude)
Transclude function access points
compile: function(tElem, tAttrs, transclude)
controller: function($scope, $element, $transclude)
link: function(scope, iElem, iAttrs, ctrl, transclude)
Transclude function access points
Directive Life Cycle
1
2
3
4
5
6
7
8
Child compile
Child controller
Child pre-link
Child post-link
Parent compile
Parent controller
Parent pre-link
Parent post-link
Directive Life Cycle
1
2
3
4
5
6
7
8
Child compile
Child controller
Child pre-link
Child post-link
Parent compile
Parent controller
Parent pre-link
Parent post-link
Transclude function availability
compile: function(tElem, tAttrs, transclude)
controller: function($scope, $element, $transclude)
link: function(scope, iElem, iAttrs, ctrl, transclude)
ot-site.js
.directive("otSite", function() {
return {
transclude: true,
template: ...,
link: function(scope, elem, attr, ctrl, transclude) {
}
};
});
ot-site.js
.directive("otSite", function() {
return {
transclude: true,
template: ...,
link: function(scope, elem, attr, ctrl, transclude) {
transclude(function(clone) {
angular.forEach(clone, function(cloneEl) {
var tId = ...
var target = ...
if (target.length) {...}
else {...}
});
});
}
};
});
ot-site.js
.directive("otSite", function() {
return {
scope: {},
transclude: true,
template: ...,
link: function(scope, elem, attr, ctrl, transclude) {
transclude(function(clone) {
angular.forEach(clone, function(cloneEl) {
var tId = ...
var target = ...
if (target.length) {...}
else {...}
});
});
}
};
});
transcluding directive with isolate scope
ot-site.js
.directive("otSite", function() {
return {
scope: {},
transclude: true,
template: ...,
link: function(scope, elem, attr, ctrl, transclude) {
transclude(function(clone) {
angular.forEach(clone, function(cloneEl) {
var tId = ...
var target = ...
if (target.length) {...}
else {...}
});
});
}
};
});
Code Demo
Angular 2.0
Component Directive
<ot-site>
Angular 1.3
Transclusion
Angular 2.0
Shadow DOM
Angular 2.0Angular 1.3
Transclusion
<div id="site">
<header t-id="head">
<svg id="logo"></svg>
</header>
<nav t-id="menu"></nav>
<main t-id="body"></main>
<footer> © 2015 OpenTable, Inc. </footer>
</div>
ot-site template
<div id="site">
<header t-id="head">
<svg id="logo"></svg>
</header>
<nav t-id="menu"></nav>
<main t-id="body"></main>
<footer> © 2015 OpenTable, Inc. </footer>
</div>
ot-site template
<div id="site">
<header>
<svg id="logo"></svg>
</header>
<nav></nav>
<main></main>
<footer> © 2015 OpenTable, Inc. </footer>
</div>
ot-site template
<div id="site">
<header>
<svg id="logo"></svg>
<content select="[head]"></content>
</header>
<nav>
<content select="[menu]"></content>
</nav>
<main>
<content select="[body]"></content>
</main>
<footer> © 2015 OpenTable, Inc. </footer>
</div>
ot-site template
ot-site.js
.directive("otSite", function() {
return {
scope: {},
transclude: true,
template: ...,
link: function(scope, elem, attr, ctrl, transclude) {
transclude(function(clone) {
angular.forEach(clone, function(cloneEl) {
var tId = ...
var target = ...
if (target.length) {...}
else {...}
});
});
}
};
});
ot-site.js
.directive("otSite", function() {
return {
scope: {},
transclude: true,
template: ...,
link: function(scope, elem, attr, ctrl, transclude) {
transclude(function(clone) {
angular.forEach(clone, function(cloneEl) {
var tId = ...
var target = ...
if (target.length) {...}
else {...}
});
});
}
};
});
ot-site.js
.directive("otSite", function() {
return {
scope: {},
transclude: true,
template: ...,
link: function(scope, elem, attr, ctrl, transclude) {
transclude(function(clone) {
angular.forEach(clone, function(cloneEl) {
var tId = ...
var target = ...
if (target.length) {...}
else {...}
});
});
}
};
});
Shadow DOM
Angular 2.0Angular 1.3
Transclusion
Manual scope
proper transclusion scope
Transclusion
Manual scope
Shadow DOM
Sensible default context
Angular 2.0Angular 1.3
ot-site.js
.directive("otSite", function() {
return {
scope: {},
transclude: true,
template: ...,
link: function(scope, elem, attr, ctrl, transclude) {
transclude(function(clone) {
angular.forEach(clone, function(cloneEl) {
var tId = ...
var target = ...
if (target.length) {...}
else {...}
});
});
}
};
});
ot-site.js
.directive("otSite", function() {
return {
scope: {},
transclude: true,
template: ...,
link: function(scope, elem, attr, ctrl, transclude) {
transclude(function(clone) {
angular.forEach(clone, function(cloneEl) {
var tId = ...
var target = ...
if (target.length) {...}
else {...}
});
});
}
};
});
ot-site.js
.directive("otSite", function() {
return {
template: ...
};
});
.directive(."otSite"., function() {
return {
template: ...
};
});
ot-site.js
ot-site.js
.directive(."otSite"., function() {
return {
.template: ....
};
});
Shadow DOM
Sensible default context
Angular 2.0Angular 1.3
Transclusion
Manual scope
One DDO
ot-site.js
.directive("otSite", function() {
return {
scope: {},
transclude: true,
template: ...,
link: function(scope, elem, attr, ctrl, transclude) {
transclude(function(clone) {
angular.forEach(clone, function(cloneEl) {
var tId = ...
var target = ...
if (target.length) {...}
else {...}
});
});
}
};
});
Shadow DOM
Sensible default context
Class & annotation
Angular 2.0Angular 1.3
Transclusion
Manual scope
One DDO
class OtSite() {
constructor () {
}
// public methods here
}
ot-site.js
ot-site.js
class OtSite() {
constructor () {
}
// public methods here
}
OtSite.annotations = [
];
ot-site.js
class OtSite() {
constructor () {
}
// public methods here
}
OtSite.annotations = [
new Component({
})
];
ot-site.js
class OtSite() {
constructor () {
}
// public methods here
}
OtSite.annotations = [
new Component({
selector: "ot-site"
})
];
ot-site.js
class OtSite() {
constructor () {
}
// public methods here
}
OtSite.annotations = [
new Component({
selector: "ot-site"
}),
new Template({
url: "ot-site.html"
})
];
ot-site.js
class OtSite() {
constructor () {
}
// public methods here
}
OtSite.annotations = [
new Component({
selector: "ot-site"
}),
new Template({
url: "ot-site.html"
})
];
ot-site.js
class OtSite() {
constructor () {
}
// public methods here
}
@Component({
selector: "ot-site"
})
@Template({
url: "ot-site.html"
})
class OtSite() {
constructor () {
}
// public methods here
}
@Component({
selector: "ot-site"
})
@Template({
url: "ot-site.html"
})
ot-site.js
@Component({
selector: "ot-site"
})
@Template({
url: "ot-site.html"
})
class OtSite() {
constructor () {
}
// public methods here
}
ot-site.js
ot-site.js
@Component({
selector: "ot-site"
})
@Template({
url: "ot-site.html"
})
class OtSite() {
constructor () {
}
// public methods here
}
<ot-site>
<div head>
I render in head.
</div>
<div menu>
I render in menu.
</div>
<div body>
I render in body.
</div>
</ot-site>
Thanks, everyone!
Kara Erickson
Web Engineer
kara
karaforthewin
Rachael L Moore
UI Engineer
morewry
morewry
We’re hiring!
Visit our careers page at
opentable.com/careers/
We’re hiring!
Visit our careers page at
opentable.com/careers/

More Related Content

What's hot

GWT integration with Vaadin
GWT integration with VaadinGWT integration with Vaadin
GWT integration with VaadinPeter Lehto
 
Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Chris Alfano
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KZepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KThomas Fuchs
 
Getting the Most Out of jQuery Widgets
Getting the Most Out of jQuery WidgetsGetting the Most Out of jQuery Widgets
Getting the Most Out of jQuery Widgetsvelveeta_512
 
Write Less Do More
Write Less Do MoreWrite Less Do More
Write Less Do MoreRemy Sharp
 
jQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & CompressionjQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & CompressionPaul Irish
 
ActiveResource & REST
ActiveResource & RESTActiveResource & REST
ActiveResource & RESTRobbert
 
An in-depth look at jQuery UI
An in-depth look at jQuery UIAn in-depth look at jQuery UI
An in-depth look at jQuery UIPaul Bakaus
 
jQuery for Sharepoint Dev
jQuery for Sharepoint DevjQuery for Sharepoint Dev
jQuery for Sharepoint DevZeddy Iskandar
 
Yearning jQuery
Yearning jQueryYearning jQuery
Yearning jQueryRemy Sharp
 
Javascript unit testing, yes we can e big
Javascript unit testing, yes we can   e bigJavascript unit testing, yes we can   e big
Javascript unit testing, yes we can e bigAndy Peterson
 
Better Selenium Tests with Geb - Selenium Conf 2014
Better Selenium Tests with Geb - Selenium Conf 2014Better Selenium Tests with Geb - Selenium Conf 2014
Better Selenium Tests with Geb - Selenium Conf 2014Naresha K
 
Polymer - pleasant client-side programming with web components
Polymer - pleasant client-side programming with web componentsPolymer - pleasant client-side programming with web components
Polymer - pleasant client-side programming with web componentspsstoev
 
Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)Remy Sharp
 
HTML5: friend or foe (to Flash)?
HTML5: friend or foe (to Flash)?HTML5: friend or foe (to Flash)?
HTML5: friend or foe (to Flash)?Remy Sharp
 
HTML5: where flash isn't needed anymore
HTML5: where flash isn't needed anymoreHTML5: where flash isn't needed anymore
HTML5: where flash isn't needed anymoreRemy Sharp
 

What's hot (20)

GWT integration with Vaadin
GWT integration with VaadinGWT integration with Vaadin
GWT integration with Vaadin
 
Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KZepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
 
Polymer 1.0
Polymer 1.0Polymer 1.0
Polymer 1.0
 
Getting the Most Out of jQuery Widgets
Getting the Most Out of jQuery WidgetsGetting the Most Out of jQuery Widgets
Getting the Most Out of jQuery Widgets
 
Write Less Do More
Write Less Do MoreWrite Less Do More
Write Less Do More
 
jQuery in 15 minutes
jQuery in 15 minutesjQuery in 15 minutes
jQuery in 15 minutes
 
jQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & CompressionjQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & Compression
 
ActiveResource & REST
ActiveResource & RESTActiveResource & REST
ActiveResource & REST
 
An in-depth look at jQuery UI
An in-depth look at jQuery UIAn in-depth look at jQuery UI
An in-depth look at jQuery UI
 
Html5 For Jjugccc2009fall
Html5 For Jjugccc2009fallHtml5 For Jjugccc2009fall
Html5 For Jjugccc2009fall
 
jQuery for Sharepoint Dev
jQuery for Sharepoint DevjQuery for Sharepoint Dev
jQuery for Sharepoint Dev
 
Yearning jQuery
Yearning jQueryYearning jQuery
Yearning jQuery
 
Sane Async Patterns
Sane Async PatternsSane Async Patterns
Sane Async Patterns
 
Javascript unit testing, yes we can e big
Javascript unit testing, yes we can   e bigJavascript unit testing, yes we can   e big
Javascript unit testing, yes we can e big
 
Better Selenium Tests with Geb - Selenium Conf 2014
Better Selenium Tests with Geb - Selenium Conf 2014Better Selenium Tests with Geb - Selenium Conf 2014
Better Selenium Tests with Geb - Selenium Conf 2014
 
Polymer - pleasant client-side programming with web components
Polymer - pleasant client-side programming with web componentsPolymer - pleasant client-side programming with web components
Polymer - pleasant client-side programming with web components
 
Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)
 
HTML5: friend or foe (to Flash)?
HTML5: friend or foe (to Flash)?HTML5: friend or foe (to Flash)?
HTML5: friend or foe (to Flash)?
 
HTML5: where flash isn't needed anymore
HTML5: where flash isn't needed anymoreHTML5: where flash isn't needed anymore
HTML5: where flash isn't needed anymore
 

Viewers also liked

Distributing UI Libraries: in a post Web-Component world
Distributing UI Libraries: in a post Web-Component worldDistributing UI Libraries: in a post Web-Component world
Distributing UI Libraries: in a post Web-Component worldRachael L Moore
 
Operations Tooling for UI - DevOps for CSS Developers
Operations Tooling for UI - DevOps for CSS DevelopersOperations Tooling for UI - DevOps for CSS Developers
Operations Tooling for UI - DevOps for CSS DevelopersRachael L Moore
 
Microformats I: What & Why
Microformats I: What & WhyMicroformats I: What & Why
Microformats I: What & WhyRachael L Moore
 
Refresh Tallahassee: The RE/MAX Front End Story
Refresh Tallahassee: The RE/MAX Front End StoryRefresh Tallahassee: The RE/MAX Front End Story
Refresh Tallahassee: The RE/MAX Front End StoryRachael L Moore
 
Redefining your core product
Redefining your core productRedefining your core product
Redefining your core productInVision App
 

Viewers also liked (7)

Distributing UI Libraries: in a post Web-Component world
Distributing UI Libraries: in a post Web-Component worldDistributing UI Libraries: in a post Web-Component world
Distributing UI Libraries: in a post Web-Component world
 
Operations Tooling for UI - DevOps for CSS Developers
Operations Tooling for UI - DevOps for CSS DevelopersOperations Tooling for UI - DevOps for CSS Developers
Operations Tooling for UI - DevOps for CSS Developers
 
3a8 picture driven computing in assistive
3a8 picture driven computing in assistive3a8 picture driven computing in assistive
3a8 picture driven computing in assistive
 
Microformats I: What & Why
Microformats I: What & WhyMicroformats I: What & Why
Microformats I: What & Why
 
Refresh Tallahassee: The RE/MAX Front End Story
Refresh Tallahassee: The RE/MAX Front End StoryRefresh Tallahassee: The RE/MAX Front End Story
Refresh Tallahassee: The RE/MAX Front End Story
 
Redefining your core product
Redefining your core productRedefining your core product
Redefining your core product
 
Open table pdf
Open table pdfOpen table pdf
Open table pdf
 

Similar to Creating GUI container components in Angular and Web Components

Resource Registries: Plone Conference 2014
Resource Registries: Plone Conference 2014Resource Registries: Plone Conference 2014
Resource Registries: Plone Conference 2014Rob Gietema
 
HTML5 workshop, part 1
HTML5 workshop, part 1HTML5 workshop, part 1
HTML5 workshop, part 1Robert Nyman
 
The Complementarity of React and Web Components
The Complementarity of React and Web ComponentsThe Complementarity of React and Web Components
The Complementarity of React and Web ComponentsAndrew Rota
 
Node.js & Twitter Bootstrap Crash Course
Node.js & Twitter Bootstrap Crash CourseNode.js & Twitter Bootstrap Crash Course
Node.js & Twitter Bootstrap Crash CourseAaron Silverman
 
jQtouch, Building Awesome Webapps
jQtouch, Building Awesome WebappsjQtouch, Building Awesome Webapps
jQtouch, Building Awesome WebappsHome
 
Responsive WordPress workflow
Responsive WordPress workflowResponsive WordPress workflow
Responsive WordPress workflowJames Bundey
 
Building iPhone Web Apps using "classic" Domino
Building iPhone Web Apps using "classic" DominoBuilding iPhone Web Apps using "classic" Domino
Building iPhone Web Apps using "classic" DominoRob Bontekoe
 
Leave No One Behind with HTML5 - FFWD.PRO, Croatia
Leave No One Behind with HTML5 - FFWD.PRO, CroatiaLeave No One Behind with HTML5 - FFWD.PRO, Croatia
Leave No One Behind with HTML5 - FFWD.PRO, CroatiaRobert Nyman
 
20190118_NetadashiMeetup#8_React2019
20190118_NetadashiMeetup#8_React201920190118_NetadashiMeetup#8_React2019
20190118_NetadashiMeetup#8_React2019Makoto Mori
 
Nuxt.JS Introdruction
Nuxt.JS IntrodructionNuxt.JS Introdruction
Nuxt.JS IntrodructionDavid Ličen
 
Speak The Web: The HTML5 Experiments
Speak The Web: The HTML5 ExperimentsSpeak The Web: The HTML5 Experiments
Speak The Web: The HTML5 Experimentsguestd427df
 
Desenvolvimento web com Ruby on Rails (parte 2)
Desenvolvimento web com Ruby on Rails (parte 2)Desenvolvimento web com Ruby on Rails (parte 2)
Desenvolvimento web com Ruby on Rails (parte 2)Joao Lucas Santana
 
Training in Android with Maven
Training in Android with MavenTraining in Android with Maven
Training in Android with MavenArcadian Learning
 
Introduction to web development
Introduction to web developmentIntroduction to web development
Introduction to web developmentAlberto Apellidos
 

Similar to Creating GUI container components in Angular and Web Components (20)

Taking your Web App for a walk
Taking your Web App for a walkTaking your Web App for a walk
Taking your Web App for a walk
 
Resource Registries: Plone Conference 2014
Resource Registries: Plone Conference 2014Resource Registries: Plone Conference 2014
Resource Registries: Plone Conference 2014
 
HTML5 workshop, part 1
HTML5 workshop, part 1HTML5 workshop, part 1
HTML5 workshop, part 1
 
The Complementarity of React and Web Components
The Complementarity of React and Web ComponentsThe Complementarity of React and Web Components
The Complementarity of React and Web Components
 
Node.js & Twitter Bootstrap Crash Course
Node.js & Twitter Bootstrap Crash CourseNode.js & Twitter Bootstrap Crash Course
Node.js & Twitter Bootstrap Crash Course
 
jQtouch, Building Awesome Webapps
jQtouch, Building Awesome WebappsjQtouch, Building Awesome Webapps
jQtouch, Building Awesome Webapps
 
Responsive WordPress workflow
Responsive WordPress workflowResponsive WordPress workflow
Responsive WordPress workflow
 
Zen
ZenZen
Zen
 
Zen based theming
Zen based themingZen based theming
Zen based theming
 
HTML5 - Pedro Rosa
HTML5 - Pedro RosaHTML5 - Pedro Rosa
HTML5 - Pedro Rosa
 
Building iPhone Web Apps using "classic" Domino
Building iPhone Web Apps using "classic" DominoBuilding iPhone Web Apps using "classic" Domino
Building iPhone Web Apps using "classic" Domino
 
Leave No One Behind with HTML5 - FFWD.PRO, Croatia
Leave No One Behind with HTML5 - FFWD.PRO, CroatiaLeave No One Behind with HTML5 - FFWD.PRO, Croatia
Leave No One Behind with HTML5 - FFWD.PRO, Croatia
 
Adobe & HTML5
Adobe & HTML5Adobe & HTML5
Adobe & HTML5
 
20190118_NetadashiMeetup#8_React2019
20190118_NetadashiMeetup#8_React201920190118_NetadashiMeetup#8_React2019
20190118_NetadashiMeetup#8_React2019
 
Nuxt.JS Introdruction
Nuxt.JS IntrodructionNuxt.JS Introdruction
Nuxt.JS Introdruction
 
Speak The Web: The HTML5 Experiments
Speak The Web: The HTML5 ExperimentsSpeak The Web: The HTML5 Experiments
Speak The Web: The HTML5 Experiments
 
iWebkit
iWebkitiWebkit
iWebkit
 
Desenvolvimento web com Ruby on Rails (parte 2)
Desenvolvimento web com Ruby on Rails (parte 2)Desenvolvimento web com Ruby on Rails (parte 2)
Desenvolvimento web com Ruby on Rails (parte 2)
 
Training in Android with Maven
Training in Android with MavenTraining in Android with Maven
Training in Android with Maven
 
Introduction to web development
Introduction to web developmentIntroduction to web development
Introduction to web development
 

Recently uploaded

08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 

Recently uploaded (20)

08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 

Creating GUI container components in Angular and Web Components