Trey Shugart
DogeScripter, Atlassian
Web Components are a collection of standards that allow the building, and use of, reusable components made with HTML, CSS and JavaScript.
<div> soup anyone?
<hangout-contacts>
<hangout-contact
src="dont-eat-the-yellow-snow.png"
name="Frank Zappa"
last-message="Frank: Freak Out!"
></hangout-contact>
...
</hangout-contacts>
skate.js
You've got some tabs
<ul class="tabs">
<li><a href="#tab1">Tab 1</a></li>
<li><a href="#tab2">Tab 2</a></li>
</ul>
But they only work on DOMReady
jQuery(function ($) {
$('.tabs').tabs();
});
Just wrap it with Skate!
skate('tabs', {
type: skate.types.CLASS,
ready: function (element) {
jQuery(element).tabs();
}
});
Input or textarea needs to clear when ESC is pressed
<input type="text" data-clear-on-esc>
// or
<textarea data-clear-on-esc></textarea>
Create an attribute component!
skate('data-clear-on-esc', {
type: skate.types.ATTR,
events: {
keyup: function (element, e) {
if (e.keyCode === 27) {
element.value = '';
}
}
}
});
You want an auto-complete element
<auto-complete url="some/service.json"></auto-complete>
Add a tag binding
var AutoComplete = skate('auto-complete', {
type: skate.types.TAG,
events: {
'keyup input[type="text"]': function (element, e) {
showSomeSuggestions(
element.getAttribute('url'),
e.target.value
);
}
},
template: '<input type="text">'
});
Element constructors!!
var autoComplete = new AutoComplete();
autoComplete.setAttribute('url', 'some/service.json');
Class, attribute and tag bindings
skate('my-component', {
// binds to classes, attributes and tags by default
type: skate.types.ANY
});
Congruent API
Except:
// Component does not support custom elements.
var MyComponent = skate('my-component', {
type: skate.types.NOTAG
});
// Will throw an exception!
var myComponent = new MyComponent();
Lifecycle callbacks
skate('my-component', {
ready: calledBeforeVisible,
insert: calledAfterVisible,
remove: calledAfterRemoval
});
* ready(), if specified, prevents element from showing until done
Async ready()
ready: function asyncReady (element, done) {
doSomethingAsync().then(done);
}
* Specifying "done" makes callback async
Prototype properties / methods
skate('my-component', {
prototype: {
someMethod: function () {
// "this" refers to the element
console.log(this);
}
}
});
Somewhere else...
document.getElementById('my-component').someMethod();
Awesome attribute API
skate('my-component' {
attributes: function handleAnyAttributeChange (element, change) {
console.log(change);
// type: 'insert, update or remove',
// name: 'attribute-name',
// newValue: 'new attribute value, undefined if just removed',
// oldValue: 'old attribute value, undefined if just inserted'
}
});
or
attributes: {
'attribute-name': handleInsertAndUpdate
}
or even
attributes: {
'attribute-name': {
insert: handleInsert,
update: handleUpdate,
remove: handleRemove
}
}
Events
skate('my-component', {
events: {
click: function handleClick (element, e) {
...
}
}
});
Event delegation, Backbone style!
events: {
'click .delegate[selector]': function handleDelegateClick (element, e) {
// use `e.target` to get the delegate
}
}
ShadowDOM-style templating by default
skate('my-component', {
template: '<article>' +
'<h2><content select=".heading"></content></h2>' +
'<section><content></content></section>' +
'</article>'
});
HTML before
<my-component>
<span class="heading">My Heading</span>
<p>First paragraph.</p>
<p>Second paragraph.</p>
</my-component>
HTML after
<my-component>
<article>
<h2><span class="heading">My Heading</span></h2>
<section>
<p>First paragraph.</p>
<p>Second paragraph.</p>
</section>
</article>
</my-component>
Custom templating
skate('data-handlebars', {
template: function (element) {
var template = Handlebars.compile(element.innerHTML);
element.innerHTML = template({
title: 'Handlebars',
body: 'However, you can use anything you want: React, Mustache, Jade, etc.'
});
}
});
HTML before
<div data-handlebars>
<h1>{{ title }}</h1>
<p>{{ body }} </p>
</div>
HTML after
<div data-handlebars>
<h1>Handlebars</h1>
<p>However, you can use anything you want: React, Mustache, Jade, etc.</p>
</div>
Thanks!
github.com/skatejs/skatejs