Skip to content

Decorator based Router component framework, powered by WebCell

EasyWebApp/cell-router

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

37 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Cell Router

Web Component Router based on WebCell & MobX

NPM Dependency CI & CD

NPM

Demo

https://web-cell.dev/cell-router/preview/

Feature

  • Route Component as a Page Configuration

  • Path Matching with new URLPattern() (* for HTTP 404)

  • Page Link (support <a />, <area /> & <form />)

    • <a href="route/path">Page title</a>
    • <a href="route/path" title="Page title">Example page</a>
    • <a href="#page-section">Page section</a> (Scroll to an Anchor smoothly)
    • <form method="get" action="route/path" /> (Form Data processed by new URLSearchParams())
    • custom component with href property
  • Path Mode: location.hash (default) & history.pushState()

  • Async Loading (based on async/await or import() ECMAScript syntax)

  • View Transition API based Page Transition Animation

Version

SemVer status WebCell API async page page transition nested router
4.x ✅ >=3.1 HTML tags (+ JSON) ✅ ✅ ❌
3.x ❌ 3.x HTML tags ✅ ✅ ❌
2.x ❌ 2.x HTML tag + JSON ✅ ✅ ✅
>=2.0.0-alpha.0 <2 ❌ 2.x abstract class + JSON ✅ ❌ ✅
1.x ❌ 1.x abstract class + ES decorators ❌ ❌ ❌
>=0.9 <1.0 ❌ 0.x abstract class + ES decorators ❌ ❌ ❌
<0.9 ❌ 0.x class + HTML tags ❌ ❌ ❌

Installation

Command

npm install dom-renderer web-cell cell-router
npm install parcel @parcel/config-default @parcel/transformer-typescript-tsc -D

tsconfig.json

{
    "compilerOptions": {
        "target": "ES6",
        "useDefineForClassFields": true,
        "jsx": "react-jsx",
        "jsxImportSource": "dom-renderer"
    }
}

.parcelrc

{
    "extends": "@parcel/config-default",
    "transformers": {
        "*.{ts,tsx}": ["@parcel/transformer-typescript-tsc"]
    }
}

Usage

Sync Pages

source/index.tsx

import { DOMRenderer } from 'dom-renderer';
import { FC } from 'web-cell';
import { createRouter, PageProps } from 'cell-router';

const { Router, Route, Link } = createRouter();

const TestPage: FC<PageProps> = ({ className, style, path, history, ...data }) => (
    <ul {...{ className, style }}>
        <li>Path: {path}</li>
        <li>Data: {JSON.stringify(data)}</li>
    </ul>
);

new DOMRenderer().render(
    <>
        <nav>
            <Link to="test?a=1">Test</Link>
            <Link to="example/2">Example</Link>
        </nav>
        <Router>
            <Route path="" component={() => <h1>Home Page</h1>} />
            <Route path="test" component={TestPage} />
            <Route path="example/:id" component={TestPage} />
            <Route path="*" component={() => <h1>404 Not Found</h1>} />
        </Router>
    </>
);

Async Pages

tsconfig.json

{
    "compilerOptions": {
        "module": "ES2020"
    }
}

source/Dynamic.tsx

import { FC } from 'web-cell';
import { PageProps } from 'cell-router';

const DynamicPage: FC<PageProps> = ({ path, id, ...props }) => (
    <div {...props}>
        <h1>Dynamic</h1>
        <pre>
            <code>{JSON.stringify({ path, id, ...props }, null, 4)}</code>
        </pre>
    </div>
);
export default DynamicPage;

source/Async.tsx

import { FC, observer } from 'web-cell';
import { sleep } from 'web-utility';
import { PageProps } from 'cell-router';

export const AsyncPage: FC<PageProps> = observer(async props => {
    await sleep();

    return (
        <div {...props}>
            <h1>Async</h1>
            <pre>
                <code>{JSON.stringify(props, null, 4)}</code>
            </pre>
        </div>
    );
});

source/index.tsx

import { DOMRenderer } from 'dom-renderer';
import { FC, lazy } from 'web-cell';
import { createRouter, PageProps } from 'cell-router';

import { AsyncPage } from './Async';

const { Router, Route, Link } = createRouter();

const SyncPage: FC<PageProps> = ({ className, style, path, history, ...data }) => (
    <ul {...{ className, style }}>
        <li>Path: {path}</li>
        <li>Data: {JSON.stringify(data)}</li>
    </ul>
);
const DynamicPage = lazy(() => import('./Dynamic'));

new DOMRenderer().render(
    <>
        <nav>
            <Link to="sync?a=1">Sync</Link>
            <Link to="dynamic/2">Dynamic</Link>
            <Link to="async/3">Async</Link>
        </nav>
        <Router>
            <Route path="sync" component={SyncPage} />
            <Route path="dynamic/:id" component={DynamicPage} />
            <Route path="async/:id" component={AsyncPage} />
        </Router>
    </>
);

Custom Link Component

import { Button } from 'boot-cell';
import { createRouter } from 'cell-router';
import { DOMRenderer } from 'dom-renderer';

const { Router, Route, Button: XButton } = createRouter({ linkTags: { Button } });

new DOMRenderer().render(
    <>
        <XButton href="route/path">Example Page</XButton>
        <Router>
            <Route path="route/path" component={() => <h1>Example Page</h1>} />
        </Router>
    </>
);

About

Decorator based Router component framework, powered by WebCell

Topics

Resources

Contributing

Stars

Watchers

Forks

Sponsor this project

Packages

No packages published

Contributors 2

  •  
  •