Yes
Let me explain, no there is too much. Let me sum up.
We'll get to that.
Divide apps into problem spaces and group code around these problem spaces. Do not group around technology.
A component must not rely on the inferred existence of a particular state in the application. Any dependency should be provided to the component explicitly.
myElement.configurate = function (config) {
let defaults = {
some: 'thing'
},
settingsAttr = JSON.parse(
myElement.getAttribute('settings')
);
let settings = _.extend({}, defaults, settingsAttr, config);
}
myElement.configurate = function (config) {
let defaults = {
some: 'thing'
},
settingsAttr = JSON.parse(
myElement.getAttribute('settings')
);
let settings = Object.assign({}, defaults, settingsAttr, config);
}
myElement.configurate = function (config) {
let defaults = {
some: 'thing'
},
settingsAttr = myElement.getAttribute('settings') || '{}';
try { settingsAttr = JSON.parse(settingsAttr); }
catch(e) { settingsAttr = {}; }
let settings = Object.assign({}, defaults, settingsAttr, config);
}
In order to be reusable, a component must be:
Your code is not reusable if it fails any of these tests.
A component is repeatable if it is easy to create multiple instances of it.
'Instance' in this case does not need to carry with it all the bagage it noramlly does in an OOP context.
A component is configurable if it can be easily appropriated for a given task.
A component is extensible if additional functionality can be easily and unobtrusively added. This may be in the form of event hooks, lifecycle hooks or an extensibility api.
A component is composable if it can be easily combined with other components to create new, more complex ones.
<link rel="stylesheet" href="styles.css" />
<div class="class">
Any valid HTML can go in an HTML Import file.
</div>
<script src="some-file.js"></script>
<link rel="import" href="/path/to/my/web-component.html" />
use it
create it
Living without
Living without
Many have seen ShadowDOM as a means of explaining aspects of how the web -- specifically HTML -- works.
<select>
<audio>/<video>
<details>
let shadowHost = document.querySelector('#needsShadow'),
shadowChild = document.createElement('p');
shadowHost.createShadowRoot();
shadowHost.shadowRoot.append(shadowChild);
just replace all references to `this.shadowRoot` with `this`.
Living without
Living without
HTML Templates are supported by every major evergreen browser.
It's ridiculously easy to polyfill*
*OK, it's more like a patch as the contents won't be inert, but it's better than writing code around it and we're coding for the future right? RIGHT?
<template>
<p>Any <strong>HTML</strong>.</p>
<p>Seriously, <em>any</em> <abbr>HTML<abbr></p>
</template>
build it
var el = document.querySelector(div),
fragment = document.importNode(
document.querySelector('template').content,
true
);
el.appendChild(fragment);
use it
Living without
Define Custom Semantic Elements as Components
React to lifecycle events
All other standard events are available to you.
Receive config through attributes (events?)
Expose information via custom events.
This is where the real power is.
Lifecycle callbacks are RAD!*
*All though technically you don't even need this. Mutation Observers can be made to accomplish the same thing. In fact, this is how Custom Elements is polyfilled.
const awesomePrototype = Object.create(HTMLElement, {
// assign methods and properties
});
awesomePrototype.createdCallback = function () { ... };
awesomePrototype.attachedCallback = function () { ... };
awesomePrototype.detachedCallback = function () { ... };
awesomePrototype.attributeChangedCallback = function (attrName, prevVal, currVal) { ... };
document.registerElement('awe-some', {
prototype: awesomePrototype
});
built it.
<awe-some rad="SORT">
<p>Composed DOM</p>
<p>AKA Light DOM</p>
</awe-smome>
use it.
const awesomePrototype = Object.create(HTMLElement, {
rad: {
get() {
return this.getAttribute('rad');
},
set(val) {
return this.setAttribute('rad', val);
}
}
});
document.registerElement('awe-some', {
prototype: awesomePrototype
});
pro tip: bind attributes to properies with getters/setters.
(loud applause!)