WebCell
WebCell copied to clipboard
Web Components engine based on VDOM, JSX, MobX & TypeScript
WebCell
Web Components engine based on VDOM, JSX, MobX & TypeScript
Usage
Demo & GitHub template: https://web-cell.dev/scaffold/
Project bootstrap
Command
npm init -y
npm install web-cell
npm install parcel -D
package.json
{
"scripts": {
"start": "parcel source/index.html --open",
"build": "parcel build source/index.html --public-url ."
}
}
source/index.html
<script
crossorigin
src="https://polyfill.app/api/polyfill?features=es.array.flat,es.object.from-entries"
></script>
<script src="https://cdn.jsdelivr.net/npm/@webcomponents/[email protected]/webcomponents-bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@webcomponents/[email protected]/custom-elements-es5-adapter.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/index.min.js"></script>
<script src="source/SubTag.tsx"></script>
<script src="source/TestTag.tsx"></script>
<sub-tag></sub-tag>
<test-tag></test-tag>
Simple component
source/SubTag.tsx
import { WebCellProps, WebCell, createCell, component } from 'web-cell';
export function InlineTag({ defaultSlot }: WebCellProps) {
return <span>{defaultSlot}</span>;
}
@component({
tagName: 'sub-tag'
})
export class SubTag extends WebCell() {
render() {
return <InlineTag>test</InlineTag>;
}
}
Advanced component
source/TestTag.tsx
import {
WebCellProps,
WebCell,
createCell,
component,
attribute,
observer,
on,
Fragment
} from 'web-cell';
import { observable } from 'mobx';
import { SubTag } from './SubTag';
export interface TestTagProps extends WebCellProps {
topic?: string;
}
class State {
@observable
status = '';
}
@component({
tagName: 'test-tag',
mode: 'open'
})
@observer
export class TestTag extends WebCell<TestTagProps>() {
@attribute
@observable
topic = 'Test';
state = new State();
onClick = () => (this.topic = 'Example');
@on('click', ':host h1')
onDelegate() {
this.state.status = 'active';
}
render() {
const { topic } = this,
{ status } = this.state;
return (
<>
<style>
{stringifyCSS({
'.topic': {
color: 'lightblue'
},
'.topic.active': {
color: 'lightpink'
}
})}
</style>
<h1 title={topic} className={`topic ${status}`}>
{topic}
<img alt={topic} onClick={this.onClick} />
<SubTag />
</h1>
</>
);
}
}
Basic knowledge
- Web components
- Custom elements
- Shadow DOM
- Element Internals
- CSS variables
- ECMAScript 6+
- TypeScript 4+
Life Cycle hooks
Scaffolds
Ecosystem
We recommend these libraries to use with WebCell:
-
State management: MobX (also powered by TypeScript & Decorator)
-
Router: Cell Router
-
UI components
- BootCell (based on BootStrap v4)
- Material Cell (based on Material Design)
- GitHub Web Widget
-
HTTP request: KoAJAX (based on Koa-like middlewares)
-
Utility: Web utility (Methods & Types)
-
Event stream: Iterable Observer (Observable proposal)
-
MarkDown integration: MarkCell (MDX implement)