npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@capitec/omni-router

v0.3.1

Published

Framework agnostic, zero dependency, client-side web component router

Downloads

634

Readme


Introduction

Omni Router is a simple client-side page router for single page application (SPA) web component projects that enable you to add animated URL based page navigation to your web app.

Core features of the library include:

  • Framework Agnostic - The router is provided as a standard HTML web components, that can be used in VanillaJS or within any framework, e.g. Lit, React, Vue, Angular, etc.
  • Web Components - The router has been specifically built to route pages built using web components.
  • Lazy Loading - Web component pages can be lazy loaded using import('...').
  • Route Guards - Routes can be protected using guard functions that prevent routing based on your app logic, e.g. check if the user is logged in.
  • Animations - Pages can be animated in and out of view when routing, e.g. fade, slide, pop, etc.
  • Browser History - Integrates with the browser history API to push, pop, and replace paths.
  • Mobile Friendly - Navigating back reverses the route load animation, allowing mobile-like user experiences e.g. sliding routes in and out.
  • Lightweight - The library is small and comes with zero dependencies, minimizing bloat to your project.

Usage

1️⃣   Install the library in your project.

npm install @capitec/omni-router

2️⃣   Specify a base href location in your index.html to use as root for page navigation.

<base href="/">

3️⃣   Import the Router package.

// JS import
import '@capitec/omni-router';

// or HTML import
<script type="module" src="/node_modules/omni-router/dist/index.js"></script>

4️⃣   Place the <omni-router> tag in your web page, all routes will be rendered in this container.

<omni-router></omni-router>

5️⃣   Define the pages you will route to.

// Register the app routes.
Router.addRoute({
    name: 'view-fade',
    title: 'Fade',
    path: '/fade',
    animation: 'fade',
    load: () => import('./views/ViewFade'),
    isDefault: true
});

// Load the route matching the current browser path.
Router.load();

💡 Example

This example sets up a simple web page containing the Omni Router. Routes are registered on page load to navigate to individual web component pages using fade, slide, and pop animations.

<!DOCTYPE html>

<html lang="en">
    <head>
        <meta charset="utf-8">

        <title>Omni Router Demo</title>

        <base href="/">

        <script type="module">
            import { Router } from '@capitec/omni-router';

            // Register the app routes.
            Router.addRoute({
                name: 'view-fade',
                title: 'Fade',
                path: '/fade',
                animation: 'fade',
                load: () => import('./views/ViewFade'),
                isDefault: true
            });

            Router.addRoute({
                name: 'view-slide',
                title: 'Slide',
                path: '/slide',
                animation: 'slide',
                load: () => import('./views/ViewSlide')
            });

            Router.addRoute({
                name: 'view-pop',
                title: 'Pop',
                path: '/pop',
                animation: 'pop',
                load: () => import('./views/ViewPop')
            });

            Router.addRoute({
                name: 'view-guarded',
                title: 'Guarded Route',
                path: '/guarded',
                load: () => import('./views/ViewGuarded'),
                guard: () => !this._isUserLoggedIn()
            });

            Router.addRoute({
                name: 'view-fallback',
                title: 'Fallback Route',
                path: '/error404',
                load: () => import('./views/ViewFallback'),
                isFallback: true
            });

            // Load the route matching the current browser path.
            Router.load();
        </script>

        <script type="module" src="./AppShell.js"></script>
    </head>

    <body>
        <omni-router></omni-router>
    </body>
</html>
// view/ViewFade.js

import { Router } from '@capitec/omni-router';

class ViewFade extends HTMLElement {

    constructor() {

        super();

        // Create the DOM content template.
        const template = document.createElement('template');
        template.innerHTML = `
            <style>
                :host {
                    .background-color: white;
                }
            </style>

            <h1>Hello World</h1>

            <button id="back">⬅ Go Back</button>
        `;

        // Create a shadow root for the content.
        this.attachShadow({ mode: 'open' });

        // Add the template content to the shadow root.
        this.shadowRoot.appendChild(template.content.cloneNode(true));

        // Register element event listeners.
        this.shadowRoot.querySelector('#back').addEventListener('click', () => Router.pop());
    }
}

customElements.define('view-fade', ViewFade);

🚩 Framework Starter Projects

Starter projects are available in the examples directory for the following frameworks:

API Reference

Route Object

The Route object contains the following properties:

| Property | Type | Description | | -------- | ---- | ----------- | | name | string | The unique identifier for the route, must be the tag name of the web component if tag is not set. | | tag | string | Optional, the registered custom-element tag name for your page web component, e.g. 'view-login' | | path | string | The relative URL path for the route to set in the browser navigation bar, e.g. '/login' | | title | string | The window title to show when the route is loaded, e.g. 'Login' | | animation | string | Optional, animation to apply when loading the route. Can be one of fade, slide, pop | cache | boolean | Optional, indicator if the route template should be cached and reused, or recreated every time the route is navigated to. | load | function | Optional, function to execute before navigating to the route. Typically used to lazy load the page web component, e.g. () => import('./views/ViewLogin') | | guard | function | Optional, function to execute to check if a route may be navigated to. Typically used to limit access to routes., e.g. () => !this._isUserLoggedIn() | | isDefault | boolean | Optional, flag to set this route as the default route to load when the browser URL path is empty or default, e.g. /. Note: can only be applied to 1 route. | | isFallback | boolean | Optional, flag to set this route as the fallback route to load when the user attempts to navigate to a route that does not exist, e.g. a 404 page. Note: can only be applied to 1 route. |

Path Patterns

The router supports URL paths for the following patterns:

| Pattern | Example | Matches | Description | | ------- | ------- | ------- | ----------- | | /part | /hello/world | /hello/world | A static path part, will be matched exactly. | | /:param | /hello/:place | /hello/world | A required path parameter. | | /:param? | /hello/:place? | /hello/hello/world | An optional path parameter |

Note: Path part parameters must be valid URL characters including: Period (.), Dash (-), Characters (a-Z), Numbers (0-9).

Styling

The router styling can be customized using the following CSS Custom Properties:

| CSS Variable | Default Value | Description | | ------------ | ------------- | ----------- | | --omni-router-animation-duration | 300ms | The duration it takes for route pages to be animated into view. | | --omni-router-animation-z-index | 1000000 | The z-index to apply to the page being routed to. Set to a value higher than your app's highest z-index value to prevent elements from appearing above the page while routing. |

Router Tag

The <omni-router> tag dispatches the following events, that may be useful to subscribe to when wanting to apply changes to a page while a route is lazy loading, e.g. show a loading indicator.

| Event | Description | | ----- | ----------- | | navigation-started | Fired before the route starts navigating, e.g. after guard is successful, but before load is called. | | navigation-started | Fired after the route page has completely rendered on screen, e.g. after it was fully animated in. |

The <omni-router> tag provides the following functions:

| Function | Description | | -------- | ----------- | | clearCache(): void | Clear the cache of route components. |

Router Class

Full API documentation available here.

The Router class provides the following properties and functions:

| Property | Description | | -------- | ----------- | | get currentLocation(): RoutedLocation \| undefined | Get the currently location routed to. | | get previousLocation(): RoutedLocation \| undefined | Get the previous location routed to. | | get defaultRoute(): Route \| undefined | Get the route that should be rendered when navigating to the app base URL. | | get fallbackRoute(): Route \| undefined | Get the route that should be rendered when navigating to a route that does not exist. |

| Function | Description | | -------- | ----------- | | addEventListener(eventName: RouterEventType, callback: () => void): void | Registers a callback function to be invoked when the router dispatches an event. | | removeEventListener(eventName: RouterEventType, callback: () => void): void | Removes a callback function from the list of functions to be invoked when the router dispatches an event. | | addRoute(route: Route): void | Add a route from the list of navigable routes. | | remove(name: string): void | Remove a route from the list of navigable routes. | | getRouteForPath(pathOrUrl: string): Route \| null | Get the registered route for the given path. | | setDefault(name: string): boolean | Set the route that should be rendered when navigating to the app base URL. | | setFallback(name: string): boolean | Set the route that should be rendered when navigating to a route that does not exist. | | load(): Promise<boolean> | Navigate to the current browser URL path. | | push(path: string, state = {}, animateOut = false): Promise<boolean> | Push a new path onto the browser history stack and render it's registered route. | | replace(path: string, state = {}, animateOut = false): Promise<boolean> | Update the current path in the browser history stack with a new path and render it's registered route. | | pop(delta?: number): Promise<boolean> | Pops the current path in the browser history stack and navigate the previous path, or specified number pages back. | | popToPath(path: string, before = false): Promise<boolean> | Pops back in history to a previous path, removing all paths after this point from the stack. |

Contributors

Made possible by these fantastic people. 💖

See the CONTRIBUTING.md guide to get involved.

License

Licensed under MIT