Light-weight Web Components framework (with MVVM support) based on ECMAScript 2018 & Decorator proposal, powered by the practice & experience from developing EWA v1.0 ~ 4.0.
npm init web-cell path/to/your_project \
--remote https://git-example.com/your_id/repo_name.git
web-cell new your-tag attr1,attr2
(More configuration & template files can be found in the document of WebCell DevCLI)
Create files as shown below in path/to/your-component
directory:
Template syntax of Data binding
<template>
<textarea onchange="${host.trigger.bind( host )}">
Hello, ${view.name}!
</textarea>
<img src="${host.constructor.icon}">
<table>
<tbody data-view="specification"><template>
<tr>
<td></td><td>${view.name}</td>
</tr>
<template></tbody>
</table>
<slot></slot>
</template>
textarea {
font-style: italic;
}
tbody {
counter-reset: index;
}
tr > td:first-child::before {
counter-increment: index;
content: counter( index );
}
{
"name": "Web components",
"specification": [
{"name": "HTML 5.3"},
{"name": "DOM 4.1"},
{"name": "ECMAScript 2018"},
{"name": "Decorator proposal"}
]
}
<svg></svg>
import {
component, blobURI, mapProperty, mapData, on, at, debounce
} from 'web-cell';
import template from './index.html';
import style from './index.css';
import data from './index.json';
import icon from './icon.svg';
@component({ // Register this class as a Custom Element,
template, style, data // then define static properties
})
export default class YourComponent extends HTMLElement {
constructor() {
super().construct(); // This method is required,
// it makes building Shadow DOM easier.
}
@blobURI // Convert Data URL to Object URL, then cache it
static get icon() { return icon; }
@mapProperty // Assign parsed value of Attribute to Property with the same name
static get observedAttributes() { return ['value', 'name']; }
@mapData // Assign Property value to Data with the same name
attributeChangedCallback() { }
/**
* Do something after Outside nodes changing
*
* @param {Node[]} assigned - Nodes pluged into a slot
* @param {HTMLSlotElement} slot
* @param {?String} name - `name` attribute of `slot`
*/
slotChangedCallback(assigned, slot, name) { }
/**
* @param {Object} newData
* @param {Object} oldData
* @param {View} view
*
* @return {?Boolean} `false` can prevent the view of this Component to rerender
*/
viewUpdateCallback(newData, oldData, view) { }
/**
* @param {Object} data
* @param {View} view
*/
viewChangedCallback(data, view) { }
@on('input', ':host textarea')
@debounce()
countLength(event, target) {
console.log(`Input length: ${target.value.length}`);
}
@at(':host *')
onAny(event, target) { }
get value() { return this.$('textarea')[0].value }
set value(raw) { this.$('textarea')[0].value = raw; }
}
and then preview them during development with:
web-cell preview
Bundle components to a package with JS modules in it:
web-cell pack
-
cell-common Common components
-
Material Cell based on Material Design lite v1.3
-
GitHub Web widget forked from GitHub jQuery Repo widget
WebCell logo by Shi Yao & Xie JiaQi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License .
Based on a work at https://web-cell.dev/WebCell/ .