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

How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
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
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
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
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
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
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 
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
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 

Recently uploaded (20)

How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
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
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
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
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
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
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
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
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 

Creating GUI container components in Angular and Web Components