WebCell icon indicating copy to clipboard operation
WebCell copied to clipboard

Web Components engine based on VDOM, JSX, MobX & TypeScript

WebCell logo

WebCell

Web Components engine based on VDOM, JSX, MobX & TypeScript

NPM Dependency CI & CD

Anti 996 license jaywcjlove/sb

Slideshow Gitter

Edit WebCell demo

NPM

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 ."
    }
}

tsconfig.json

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

Life Cycle hooks

  1. connectedCallback

  2. disconnectedCallback

  3. attributeChangedCallback

  4. adoptedCallback

  5. updatedCallback

  6. formAssociatedCallback

  7. formDisabledCallback

  8. formResetCallback

  9. formStateRestoreCallback

Scaffolds

  1. Basic

  2. DashBoard

  3. Static site

Ecosystem

We recommend these libraries to use with WebCell:

Roadmap

More guides

  1. v2 to v3 migration
  2. Development contribution