SlideShare une entreprise Scribd logo
1  sur  113
Télécharger pour lire hors ligne
Reactive
Type-safe
WebComponents
with @skate_js
Martin Hochel
@martin_hotell
Martin Hochel
SE, Prague / Czech Republic
@martin_hotell
github.com/Hotell
Hello Prague !
▪ @ngPartyCz meetup founder
▪ Author of ngMetadata
▪ Member of @skate_js
▪
▪
Today’s talk
Will be all about
Skateboarding
This is how you do an Ollie
Problem set 1:
Create a reusable widget
Problem 1
Create
reusable widget
Library size
10.7 kB
4.9 kB
3.9 kB
Implementation size
4.2 kB
4.12 kB
2.2kB
MINIFIED + GZIPPED
32.7kB
MINIFIED + GZIPPED
Problem 1
Create
reusable widget
FUTURE JS
Problem set I1:
Create Interoperable Widget
Problem I1
Create
Interoperable widget ALPHA
BETA
GAMMA DELTA
Widget
WebComponents ?
WHY WHAT HOW
WebComponents
WHY
WebComponents
WHY
WebComponents
Reusable
Interoperable
Problem
I + I1
Solved
So can I write whole apps with
vanilla WebComponents ?
You can! but It will/may hurt
WHAT
is a WebComponent
“
Platform new primitive for building
Reusable
Interoperable
Encapsulated
Widgets
<sk-user name="Martin" age="100">
<img src="./assets/skate-deck.jpg">
</sk-user>
Custom
Elements
Shadow
DOM
JS
Modules
WebComponents
Templates
Custom
Elements
class User extends HTMLElement {}
// user.component.js
<sk-user></sk-user>
// index.html
// Global registry
window.customElements.define('sk-user', User)
window.customElements.get('sk-user') // User
Custom
Elements
API
Attributes / Properties
Events
Life Cycle hooks
// $0 === User instance
$0.setAttribute('age','18')
$0.age = 18
// Imperative (JS)
<sk-user age="100"></sk-user>
// Declarative (HTML)
Custom Elements
API
Attributes
&
Properties
Primitive
Data
export class User extends HTMLElement {
static get observedAttributes() {
return ['age']
}
_age = 0
set age(value) {
this._age = Number(value)
this.render()
}
get age() {
return this._age
}
attributeChangedCallback(name, oldValue, newValue) {
this.age = newValue
}
render() {}
}
// user.component.js
Custom Elements
API
Attributes
&
Properties
Primitive
Data
export class User extends HTMLElement {
static get observedAttributes() {
return ['age']
}
_age = 0
set age(value) {
this._age = Number(value)
this.render()
}
get age() {
return this._age
}
attributeChangedCallback(name, oldValue, newValue) {
this.age = newValue
}
render() {}
}
// user.component.js
$0.age = 18
$0.age
Custom Elements
API
Attributes
&
Properties
Primitive
Data
export class User extends HTMLElement {
static get observedAttributes() {
return ['age']
}
_age = 0
set age(value) {
this._age = Number(value)
this.render()
}
get age() {
return this._age
}
attributeChangedCallback(name, oldValue, newValue) {
this.age = newValue
}
render() {}
}
// user.component.js
$0.setAttribute('age','18')
Custom Elements
API
Attributes
&
Properties
Primitive
Data
// $0 === User instance
$0.tricks = [
{ name: 'ollie', difficulty: 'easy' },
{ name: 'kickflip', difficulty: 'medium' },
{ name: 'hardflip', difficulty: 'hard' },
]
// Imperative (JS)
<sk-user hobbies="[{
"name": "ollie",
"difficulty ": "easy"
}]"></sk-user>
// Declarative (HTML)
Custom Elements
API
Attributes
&
Properties
Rich
Data
export class User extends HTMLElement {
_tricks = []
set tricks(value) {
this._tricks = value
this.render()
}
get tricks() {
return this._tricks
}
render() {}
}
// user.component.js
Custom Elements
API
Attributes
&
Properties
Rich
Data
export class User extends HTMLElement {
_tricks = []
set tricks(value) {
this._tricks = value
this.render()
}
get tricks() {
return this._tricks
}
render() {}
}
// user.component.js
Custom Elements
API
Attributes
&
Properties
Rich
Data
export class User extends HTMLElement {
_tricks = []
set tricks(value) {
this._tricks = value
this.render()
}
get tricks() {
return this._tricks
}
render() {}
}
// user.component.js
Custom Elements
API
Attributes
&
Properties
Rich
Data
// $0 === User instance
$0.addEventListener('learntrick',(event)=>{ /* ... */ })
// Imperative (JS)
Nope
// Declarative (HTML)
Custom Elements
API
Events
export class User extends HTMLElement {
emitLearnTrick(trick) {
const eventConfig = {
bubble: true,
composed: false,
detail: trick
}
const event = new CustomEvent('learntrick', eventConfig)
this.dispatchEvent(event)
}
}
// user.component.js
Custom Elements
API
Events
export class User extends HTMLElement {
constructor() {
super()
}
attributeChangedCallback(name, oldValue, newValue) {
// do some stuff
}
connectedCallback() {
console.log('component mounted!')
}
disconnectedCallback() {
console.log('goodbye!')
}
render() {}
}
// user.component.js
Custom Elements
API
Life Cycle
Hooks
export class User extends HTMLElement {
constructor() {
super()
}
attributeChangedCallback(name, oldValue, newValue) {
// do some stuff
}
connectedCallback() {
console.log('component mounted!')
}
disconnectedCallback() {
console.log('goodbye!')
}
render() {}
}
// user.component.js
Custom Elements
API
Life Cycle
Hooks
export class User extends HTMLElement {
constructor() {
super()
}
attributeChangedCallback(name, oldValue, newValue) {
// do some stuff
}
connectedCallback() {
console.log('component mounted!')
}
disconnectedCallback() {
console.log('goodbye!')
}
render() {}
}
// user.component.js
Custom Elements
API
Life Cycle
Hooks
export class User extends HTMLElement {
constructor() {
super()
}
attributeChangedCallback(name, oldValue, newValue) {
// do some stuff
}
connectedCallback() {
console.log('component mounted!')
}
disconnectedCallback() {
console.log('goodbye!')
}
render() {}
}
// user.component.js
Custom Elements
API
Life Cycle
Hooks
export class User extends HTMLElement {
constructor() {
super()
}
attributeChangedCallback(name, oldValue, newValue) {
// do some stuff
}
connectedCallback() {
console.log('component mounted!')
}
disconnectedCallback() {
console.log('goodbye!')
}
render() {}
}
// user.component.js
Custom Elements
API
Life Cycle
Hooks
<template>
<template id="view">
<style>
:host { display: flex }
div { color: blue; }
</style>
<h2>Hello World!</h2>
<p>Yo what’s up dough?</p>
<slot></slot>
</template>
// user.template.html
<template>
<template id="view">
<style>
:host { display: flex }
div { color: blue; }
</style>
<h2>Hello World!</h2>
<p>Yo what’s up dough?</p>
<slot></slot>
</template>
// user.template.html
<template>
<template id="view">
<style>
:host { display: flex }
div { color: blue; }
</style>
<h2>Hello World!</h2>
<p>Yo what’s up dough?</p>
<slot></slot>
</template>
// user.template.html
<template>
<template id="view">
<style>
:host { display: flex }
div { color: blue; }
</style>
<h2>Hello World!</h2>
<p>Yo what’s up dough?</p>
<slot></slot>
</template>
// user.template.html
<template>
export class User extends HTMLElement {
constructor() {
super()
const template = document.querySelector('#view')
const view = template.content.cloneNode(true)
this.appendChild(view)
}
}
// user.component.html
Shadow
DOM
<sk-user name="Martin" age="30">
<img src="./assets/skate-deck.jpg">
</sk-user>
Shadow
DOM
<sk-user name="Martin" age="30">
<img src="./assets/skate-deck.jpg">
</sk-user>
<sk-user name="Martin" age="30">
#shadow-root(open)
<style></style>
<div>
<ul>
<li>Age</li>
</ul>
<slot>#refToImg</slot>
</div>
<img src="./assets/skate-deck.jpg">
</sk-user>
Shadow
DOM
<sk-user name="Martin" age="30">
<img src="./assets/skate-deck.jpg">
</sk-user>
<sk-user name="Martin" age="30">
#shadow-root(open)
<style></style>
<div>
<ul>
<li>Age</li>
</ul>
<slot>#refToImg</slot>
</div>
<img src="./assets/skate-deck.jpg">
</sk-user>
Shadow
DOM
<sk-user name="Martin" age="30">
<img src="./assets/skate-deck.jpg">
</sk-user>
<sk-user name="Martin" age="30">
#shadow-root(open)
<style></style>
<div>
<ul>
<li>Age</li>
</ul>
<slot>#refToImg</slot>
</div>
<img src="./assets/skate-deck.jpg">
</sk-user>
Shadow
DOM
<sk-user name="Martin" age="30">
<img src="./assets/skate-deck.jpg">
</sk-user>
<sk-user name="Martin" age="30">
#shadow-root(open)
<style></style>
<div>
<ul>
<li>Age</li>
</ul>
<slot>#refToImg</slot>
</div>
<img src="./assets/skate-deck.jpg">
</sk-user>
LIGHT
Shadow
DOM
<sk-user name="Martin" age="30">
<img src="./assets/skate-deck.jpg">
</sk-user>
<sk-user name="Martin" age="30">
#shadow-root(open)
<style></style>
<div>
<ul>
<li>Age</li>
</ul>
<slot>#refToImg</slot>
</div>
<img src="./assets/skate-deck.jpg">
</sk-user>
Shadow
DOM
<style></style>
<sk-user name="Martin" age="30">
<img src="./assets/skate-deck.jpg">
</sk-user>
<sk-user name="Martin" age="30">
#shadow-root(open)
<style></style>
<div>
<ul>
<li>Age</li>
</ul>
<slot>#refToImg</slot>
</div>
<img src="./assets/skate-deck.jpg">
</sk-user>
Shadow
DOM
<style></style>
<sk-user name="Martin" age="30">
<img src="./assets/skate-deck.jpg">
</sk-user>
<sk-user name="Martin" age="30">
#shadow-root(open)
<style></style>
<div>
<ul>
<li>Age</li>
</ul>
<slot>#refToImg</slot>
</div>
<img src="./assets/skate-deck.jpg">
</sk-user>
Shadow
DOM
constructor() {
super()
const shadowRoot = this.attachShadow({ mode: 'open' })
shadowRoot.appendChild(template.content.cloneNode(true))
}
Shadow
DOM
Isolated sandbox
API -> projection -> <slot/>
scoped CSS
<script type="module">
import './src/app.js'
</script>
<my-app></my-app>
JS
Modules
WHAT ✅
is a WebComponent
Hey!
What about browser support?
Browser
support
HOW
to build a WebComponent
Reactive
Type-safe
<sk-app>
WC App
Demo
WC App
architecture
WC App
Reactive
data-flow
sk-app
sk-user
name: string
age: number
tricks: Array<Trick>
learntrick: CustomEvent<Trick>
removetrick: CustomEvent<Trick>
export type Trick = {
name: string
difficulty: 'easy' | 'medium' | 'hard'
}
sk-user
Implementation
Types, template
type Attrs = 'name' | 'age'
type Props = {
name: string
age: number
tricks: Array<Trick>
}
const template = document.createElement('template')
template.innerHTML = `
<style> :host { … } </style>
<header>
Hello <b id="name"></b>! Let's skate!
</header>
<div>
Only <b id="age"></b> years old? Time to learn new tricks!
</div>
<form>
<input name="trickName" value="">
<select id="trickDifficulty" class="form-control">
</form>
`
// user.component.ts
export class User extends HTMLElement implements Props {
set name(value: string) {}
get name() {}
set age(value: number) {}
get age() {}
set tricks(value: Array<Trick>) {}
get tricks() {
private _tricks: Array<Trick> = []
private view: {
form: HTMLFormElement
trickList: HTMLUListElement
age: HTMLElement
name: HTMLElement
}
}
sk-user
Implementation
Define Properties
window.customElements.define('sk-user', User)
// user.component.ts
export class User extends HTMLElement implements Props {
constructor() {
super()
const shadowRoot = this.attachShadow({ mode: 'open' })
shadowRoot.appendChild(template.content.cloneNode(true))
this.view = {
form: shadowRoot.querySelector('form'),
trickList: shadowRoot.querySelector('#trick-list'),
age: shadowRoot.querySelector('#age'),
name: shadowRoot.querySelector('#name'),
}
this.view.form.addEventListener(
'submit',
this.handleNewTrickAddition
)
}
}
sk-user
Implementation
construction
// user.component.ts
export class User extends HTMLElement implements Props {
attributeChangedCallback(
name: Attrs, oldValue: string | null, newValue: string | null
) {
this.render()
}
connectedCallback() {
this.render()
}
}
sk-user
Implementation
Reactions,
Rendering
// user.component.ts
HOW
frameworks/libraries Interop with
WebComponents
index.html
<sk-user
name="Martin"
age="100"
tricks=""[{"foo":"bar"}]""
></sk-user>
app.component.html
<sk-user
[attr.name]="model.name"
[attr.age]="model.age"
[tricks]="model.tricks"
></sk-user>
App.vue
<sk-user
:name="model.name"
:age="model.age"
:tricks.prop="model.tricks"
></sk-user>
App.tsx
<sk-user
name={this.state.user.name}
age={this.state.user.age}
tricks={this.state.user.tricks}
/>
https://custom-elements-everywhere.com
“
So what’s the problem with
vanilla WebComponents ?
“
UNFORTUNATELY
THE DEVELOPER EXPERIENCE
OF BUILDING AN APPLICATION
WITH WEB COMPONENTS TODAY IS
QUITE PAINFUL
SAM SACCONE
“
Eventually
You’ll build some kind
of abstraction
From Imperative
to Declarative
rendering
lit-html
HTML templates,
via JavaScript template literals
const sayHello = (name: string) =>
html`<div>Hello ${name}!</div>`
lit-html
const container = document.querySelector('#container')
render(sayHello('Steve'), container)
// renders <div>Hello Steve!</div> to container
render(sayHello('Kevin'), container);
// renders <div>Hello Kevin!</div> to container
class App extends HTMLElement {
connectedCallback() {
console.log('App mounted')
this.render()
}
render() {
const { tricks, logs } = this
const template = html`
<ul class="log">
${logs.map(item => CreateLogEvent(item))}
</ul>
<sk-user
name="Martin"
age="30"
tricks="${tricks}"
on-learnTrick="${this.handleNewTrick}"
on-removeTrick="${this.handleRemoveTrick}"
><sk-user>
`
render(template, this.shadowRoot)
}
}
lit-html
Building API via composition & mixins
export const withShadow = <TBase>(Base: TBase) =>
class WithShadow extends Base {
constructor(...args: Array<any>) {
super(...args)
this.attachShadow({ mode: 'open' })
}
}
JS mixins
class App extends withShadow(HTMLElement) { }
class App extends withRender(withShadow(HTMLElement)) { }
Good news !
Skate JSSkate JS
Skate JSSkate JS
What is
skateJS Reactive
Pluggable
WebComponents Micro-library
Stable 4.x
Beta 5.x
2200+ ⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Reactive ?
props
View
Logic
render
Action
( click, keypress )
state
Pluggable ?
- mixins
- custom renderers
- fine grained LC hooks
Micro library ?
HOW
to build a WebComponent
with
skateJS
Core Tricks
skateJS
Renderers
- renderer-preact
- renderer-react
- renderer-lit-html
- renderer-vue ( TODO )
- custom
import { withComponent } from 'skatejs';
import withPreact from '@skatejs/renderer-preact';
export const Component = withComponent(withPreact())
Choose
renderer
import { withComponent } from 'skatejs';
import withPreact from '@skatejs/renderer-preact';
export const Component = withComponent(withPreact())
Choose
renderer
import { withComponent } from 'skatejs';
import withPreact from '@skatejs/renderer-preact';
export const Component = withComponent(withPreact())
Choose
renderer
import { h } from 'preact'
import { props } from 'skatejs'
import { Component } from './base'
type Props = {
name: string
}
class Hello extends Component<Props> {
static readonly props = {
name: props.string,
}
renderCallback() {
const { name } = this.props
return <span>Hello, {name}!</span>
}
}
customElements.define('x-hello', Hello)
Implement
Component
import { h } from 'preact'
import { props } from 'skatejs'
import { Component } from './base'
type Props = {
name: string
}
class Hello extends Component<Props> {
static readonly props = {
name: props.string,
}
renderCallback() {
const { name } = this.props
return <span>Hello, {name}!</span>
}
}
customElements.define('x-hello', Hello)
Implement
Component
import { h } from 'preact'
import { props } from 'skatejs'
import { Component } from './base'
type Props = {
name: string
}
class Hello extends Component<Props> {
static readonly props = {
name: props.string,
}
renderCallback() {
const { name } = this.props
return <span>Hello, {name}!</span>
}
}
customElements.define('x-hello', Hello)
Implement
Component
import { h } from 'preact'
import { props } from 'skatejs'
import { Component } from './base'
type Props = {
name: string
}
class Hello extends Component<Props> {
static readonly props = {
name: props.string,
}
renderCallback() {
const { name } = this.props
return <span>Hello, {name}!</span>
}
}
customElements.define('x-hello', Hello)
Implement
Component
import { h } from 'preact'
import { props } from 'skatejs'
import { Component } from './base'
type Props = {
name: string
}
class Hello extends Component<Props> {
static readonly props = {
name: props.string,
}
renderCallback() {
const { name } = this.props
return <span>Hello, {name}!</span>
}
}
customElements.define('x-hello', Hello)
Implement
Component
import { h, props } from 'skatejs'
import { Component } from './base'
type Props = {
name: string
}
class Hello extends Component<Props> {
}
declare global {
namespace JSX {
interface IntrinsicElements {
'x-hello': Props
}
}
}
Implement
Component
<sk-app>
github.com/Hotell/reactive-typesafe-webcomponents
Vanilla
vs
Skate
Vanilla With skateJS
Advanced Tricks
Advanced Tricks
- State like React
- No default renderer in core ✅
- Mixins for everything - ✅
- API for turning off ShadowDOM - ✅
- Server side rendering - ✅
- Testing with Jest - ✅
@skatejs
ecoystem
● ssr
● val
● bore
Support us !
Keep in touch
github.com/skatejs/skatejs
@skate_js
@treshugart
@martin_hotell
What did
we learn ?
Are WebCompoents
The Future of web ?
The Future is now
KEEP CALM
and
USE
WEBCOMPONENTS
Thank you ! Martin Hochel
@martin_hotell

Contenu connexe

Tendances

jQuery in the [Aol.] Enterprise
jQuery in the [Aol.] EnterprisejQuery in the [Aol.] Enterprise
jQuery in the [Aol.] EnterpriseDave Artz
 
Building Universal Web Apps with React ForwardJS 2017
Building Universal Web Apps with React ForwardJS 2017Building Universal Web Apps with React ForwardJS 2017
Building Universal Web Apps with React ForwardJS 2017Elyse Kolker Gordon
 
JQuery in Seaside
JQuery in SeasideJQuery in Seaside
JQuery in SeasideESUG
 
Polymer, A Web Component Polyfill Library
Polymer, A Web Component Polyfill LibraryPolymer, A Web Component Polyfill Library
Polymer, A Web Component Polyfill Librarynaohito maeda
 
Polymer & the web components revolution 6:25:14
Polymer & the web components revolution 6:25:14Polymer & the web components revolution 6:25:14
Polymer & the web components revolution 6:25:14mattsmcnulty
 
jQuery For Developers Stack Overflow Dev Days Toronto
jQuery For Developers Stack Overflow Dev Days TorontojQuery For Developers Stack Overflow Dev Days Toronto
jQuery For Developers Stack Overflow Dev Days TorontoRalph Whitbeck
 
JavaScript Library Overview
JavaScript Library OverviewJavaScript Library Overview
JavaScript Library Overviewjeresig
 
Why and How to Use Virtual DOM
Why and How to Use Virtual DOMWhy and How to Use Virtual DOM
Why and How to Use Virtual DOMDaiwei Lu
 
The Many Ways to Build Modular JavaScript
The Many Ways to Build Modular JavaScriptThe Many Ways to Build Modular JavaScript
The Many Ways to Build Modular JavaScriptTim Perry
 
Basic Tutorial of React for Programmers
Basic Tutorial of React for ProgrammersBasic Tutorial of React for Programmers
Basic Tutorial of React for ProgrammersDavid Rodenas
 
gDayX 2013 - Advanced AngularJS - Nicolas Embleton
gDayX 2013 - Advanced AngularJS - Nicolas EmbletongDayX 2013 - Advanced AngularJS - Nicolas Embleton
gDayX 2013 - Advanced AngularJS - Nicolas EmbletonGeorge Nguyen
 
Javascript Module Patterns
Javascript Module PatternsJavascript Module Patterns
Javascript Module PatternsNicholas Jansma
 
Vaadin Components @ Angular U
Vaadin Components @ Angular UVaadin Components @ Angular U
Vaadin Components @ Angular UJoonas Lehtinen
 
Enjoy the vue.js
Enjoy the vue.jsEnjoy the vue.js
Enjoy the vue.jsTechExeter
 
Using ReactJS in AngularJS
Using ReactJS in AngularJSUsing ReactJS in AngularJS
Using ReactJS in AngularJSBoris Dinkevich
 
From Back to Front: Rails To React Family
From Back to Front: Rails To React FamilyFrom Back to Front: Rails To React Family
From Back to Front: Rails To React FamilyKhor SoonHin
 
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
 

Tendances (20)

jQuery in the [Aol.] Enterprise
jQuery in the [Aol.] EnterprisejQuery in the [Aol.] Enterprise
jQuery in the [Aol.] Enterprise
 
Building Universal Web Apps with React ForwardJS 2017
Building Universal Web Apps with React ForwardJS 2017Building Universal Web Apps with React ForwardJS 2017
Building Universal Web Apps with React ForwardJS 2017
 
JQuery in Seaside
JQuery in SeasideJQuery in Seaside
JQuery in Seaside
 
Polymer, A Web Component Polyfill Library
Polymer, A Web Component Polyfill LibraryPolymer, A Web Component Polyfill Library
Polymer, A Web Component Polyfill Library
 
Polymer & the web components revolution 6:25:14
Polymer & the web components revolution 6:25:14Polymer & the web components revolution 6:25:14
Polymer & the web components revolution 6:25:14
 
jQuery For Developers Stack Overflow Dev Days Toronto
jQuery For Developers Stack Overflow Dev Days TorontojQuery For Developers Stack Overflow Dev Days Toronto
jQuery For Developers Stack Overflow Dev Days Toronto
 
FuncUnit
FuncUnitFuncUnit
FuncUnit
 
JavaScript Library Overview
JavaScript Library OverviewJavaScript Library Overview
JavaScript Library Overview
 
Html5
Html5Html5
Html5
 
Why and How to Use Virtual DOM
Why and How to Use Virtual DOMWhy and How to Use Virtual DOM
Why and How to Use Virtual DOM
 
The Many Ways to Build Modular JavaScript
The Many Ways to Build Modular JavaScriptThe Many Ways to Build Modular JavaScript
The Many Ways to Build Modular JavaScript
 
Basic Tutorial of React for Programmers
Basic Tutorial of React for ProgrammersBasic Tutorial of React for Programmers
Basic Tutorial of React for Programmers
 
gDayX 2013 - Advanced AngularJS - Nicolas Embleton
gDayX 2013 - Advanced AngularJS - Nicolas EmbletongDayX 2013 - Advanced AngularJS - Nicolas Embleton
gDayX 2013 - Advanced AngularJS - Nicolas Embleton
 
Javascript Module Patterns
Javascript Module PatternsJavascript Module Patterns
Javascript Module Patterns
 
Vaadin Components @ Angular U
Vaadin Components @ Angular UVaadin Components @ Angular U
Vaadin Components @ Angular U
 
Enjoy the vue.js
Enjoy the vue.jsEnjoy the vue.js
Enjoy the vue.js
 
Using ReactJS in AngularJS
Using ReactJS in AngularJSUsing ReactJS in AngularJS
Using ReactJS in AngularJS
 
From Back to Front: Rails To React Family
From Back to Front: Rails To React FamilyFrom Back to Front: Rails To React Family
From Back to Front: Rails To React Family
 
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
 
Rails + Webpack
Rails + WebpackRails + Webpack
Rails + Webpack
 

Similaire à Reactive Type safe Webcomponents with skateJS

WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...Fabio Franzini
 
Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenerytoddbr
 
ReactJS for Programmers
ReactJS for ProgrammersReactJS for Programmers
ReactJS for ProgrammersDavid Rodenas
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCpootsbook
 
Design Summit - UI Roadmap - Dan Clarizio, Martin Povolny
Design Summit - UI Roadmap - Dan Clarizio, Martin PovolnyDesign Summit - UI Roadmap - Dan Clarizio, Martin Povolny
Design Summit - UI Roadmap - Dan Clarizio, Martin PovolnyManageIQ
 
jQuery (DrupalCamp Toronto)
jQuery (DrupalCamp Toronto)jQuery (DrupalCamp Toronto)
jQuery (DrupalCamp Toronto)jeresig
 
Web Components v1
Web Components v1Web Components v1
Web Components v1Mike Wilcox
 
ITB2019 ColdBox APIs + VueJS - powering Mobile, Desktop and Web Apps with 1 V...
ITB2019 ColdBox APIs + VueJS - powering Mobile, Desktop and Web Apps with 1 V...ITB2019 ColdBox APIs + VueJS - powering Mobile, Desktop and Web Apps with 1 V...
ITB2019 ColdBox APIs + VueJS - powering Mobile, Desktop and Web Apps with 1 V...Ortus Solutions, Corp
 
ActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group PresentationActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group Presentationipolevoy
 
From Backbone to Ember and Back(bone) Again
From Backbone to Ember and Back(bone) AgainFrom Backbone to Ember and Back(bone) Again
From Backbone to Ember and Back(bone) Againjonknapp
 
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)Doris Chen
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyDavid Padbury
 
Andy Bosch - JavaServer Faces in the cloud
Andy Bosch -  JavaServer Faces in the cloudAndy Bosch -  JavaServer Faces in the cloud
Andy Bosch - JavaServer Faces in the cloudAndy Bosch
 
How Bitbucket Pipelines Loads Connect UI Assets Super-fast
How Bitbucket Pipelines Loads Connect UI Assets Super-fastHow Bitbucket Pipelines Loads Connect UI Assets Super-fast
How Bitbucket Pipelines Loads Connect UI Assets Super-fastAtlassian
 
Geek Moot '09 -- Smarty 101
Geek Moot '09 -- Smarty 101Geek Moot '09 -- Smarty 101
Geek Moot '09 -- Smarty 101Ted Kulp
 

Similaire à Reactive Type safe Webcomponents with skateJS (20)

End-to-end testing with geb
End-to-end testing with gebEnd-to-end testing with geb
End-to-end testing with geb
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
 
Going web native
Going web nativeGoing web native
Going web native
 
Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenery
 
ReactJS for Programmers
ReactJS for ProgrammersReactJS for Programmers
ReactJS for Programmers
 
Angularjs
AngularjsAngularjs
Angularjs
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
 
Design Summit - UI Roadmap - Dan Clarizio, Martin Povolny
Design Summit - UI Roadmap - Dan Clarizio, Martin PovolnyDesign Summit - UI Roadmap - Dan Clarizio, Martin Povolny
Design Summit - UI Roadmap - Dan Clarizio, Martin Povolny
 
jQuery (DrupalCamp Toronto)
jQuery (DrupalCamp Toronto)jQuery (DrupalCamp Toronto)
jQuery (DrupalCamp Toronto)
 
Web Components v1
Web Components v1Web Components v1
Web Components v1
 
ITB2019 ColdBox APIs + VueJS - powering Mobile, Desktop and Web Apps with 1 V...
ITB2019 ColdBox APIs + VueJS - powering Mobile, Desktop and Web Apps with 1 V...ITB2019 ColdBox APIs + VueJS - powering Mobile, Desktop and Web Apps with 1 V...
ITB2019 ColdBox APIs + VueJS - powering Mobile, Desktop and Web Apps with 1 V...
 
ActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group PresentationActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group Presentation
 
Extend sdk
Extend sdkExtend sdk
Extend sdk
 
From Backbone to Ember and Back(bone) Again
From Backbone to Ember and Back(bone) AgainFrom Backbone to Ember and Back(bone) Again
From Backbone to Ember and Back(bone) Again
 
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight Guy
 
Andy Bosch - JavaServer Faces in the cloud
Andy Bosch -  JavaServer Faces in the cloudAndy Bosch -  JavaServer Faces in the cloud
Andy Bosch - JavaServer Faces in the cloud
 
How Bitbucket Pipelines Loads Connect UI Assets Super-fast
How Bitbucket Pipelines Loads Connect UI Assets Super-fastHow Bitbucket Pipelines Loads Connect UI Assets Super-fast
How Bitbucket Pipelines Loads Connect UI Assets Super-fast
 
HTML 5 - Overview
HTML 5 - OverviewHTML 5 - Overview
HTML 5 - Overview
 
Geek Moot '09 -- Smarty 101
Geek Moot '09 -- Smarty 101Geek Moot '09 -- Smarty 101
Geek Moot '09 -- Smarty 101
 

Dernier

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
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
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
 
🐬 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
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Evaluating the top large language models.pdf
Evaluating the top large language models.pdfEvaluating the top large language models.pdf
Evaluating the top large language models.pdfChristopherTHyatt
 
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
 
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
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
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
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
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
 
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
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdflior mazor
 
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
 

Dernier (20)

Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
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
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Evaluating the top large language models.pdf
Evaluating the top large language models.pdfEvaluating the top large language models.pdf
Evaluating the top large language models.pdf
 
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
 
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
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
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...
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
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
 
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
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
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
 

Reactive Type safe Webcomponents with skateJS