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

@brightspace-ui-labs/lit-router

v3.2.0

Published

A Lit wrapper around the [Page.js Router](https://visionmedia.github.io/page.js/).

Downloads

3,983

Readme

@brightspace-ui-labs/lit-router

A Lit wrapper around the Page.js Router.

The aim of this library is to provide an easy way to define routes, lazy load the view, and react to changes to the route.

Installation

Install from NPM:

npm install @brightspace-ui-labs/lit-router

Usage

Route Registration

Registering routes defines the routing table used when determining the view to render.

When the URL matches a particular route's pattern, the view function is called and returns a Lit html literal to render.

import { registerRoutes } from '@brightspace-ui-labs/lit-router';

registerRoutes([
  {
    pattern: '/example',
    loader: () => import('./home.js'),
    view: () => html`<test-home></test-home>`
  },
  {
    pattern: '/example/:id',
    view: ctx => html`<test-id id=${ctx.params.id}></test-id>`
  },
  {
    pattern: '/example/foo/:bar',
    view: ctx => html`
      <test-foo bar=${ctx.params.bar}>
        ${ctx.search.name}
      </test-foo>
    `
  }
], options);

Route Properties

Each route has the following properties:

  • pattern (required): The Page.js route pattern on which to match
  • loader (optional): Allows for lazy-loading dependencies (e.g. importing view files) before rendering the view; must return a Promise
  • view (optional): Function that returns a Lit html literal to render
  • to (optional): String indicating a redirect path, using Page.js redirect(fromPath, toPath)

View Context

The view is provided a context object containing:

  • params: URL segment parameters (e.g. :id)
  • search: search query values
  • options: object passed by the entry-point
  • path: Pathname and query string (e.g. "/login?foo=bar")
  • pathname: Pathname void of query string (e.g. "/login")
  • hash: URL hash (e.g. "#hash=values")
  • route: route pattern given to the view in the router
  • title: title in the push state

Example:

{
  pattern: '/user/:id/:page' // search: ?semester=1
  view: ctx => html`
    <user-view
        id=${ctx.options.id}
        page=${ctx.params.page}
        semester=${ctx.search.semester}>
    </user-view>
  `
}

Options

Options are the second parameter passed to registerRoutes. The two tables below encompasses all of the attributes that the options object can use.

Page.js options:

| Name | Description | Default | | :------------------ | :---------------------------------------------------------------------: | ------: | | click | bind to click events | true | | popstate | bind to popstate | true | | dispatch | perform initial dispatch | true | | hashbang | add #! before urls | false | | decodeURLComponents | remove URL encoding from path components (query string, pathname, hash) | true |

Additional options:

| Name | Description | Default | | :--------- | :---------------------------------------------------: | ------: | | basePath | the path all other paths are appended too | '/' | | customPage | don't use the global page object (useful for testing) | false |

Multiple Route Loaders

Some complex applications have many sub applications, and in these scenarios it may be beneficial to delegate to multiple route loaders.

Example directory structure:

/src
| /components
|
| /app1
| | app1-view.js
| | route-loader.js
|
| /app2
| | app2-view.js
| | route-loader.js
|
| entry-point.js
| route-loader.js

The main route-loader in the root of the src directory should import the route-loader files in the subdirectories.

/* src/route-loader.js */
import { loader as app1Loader } from './app1/route-loader.js';
import { loader as app2Loader } from './app2/route-loader.js';
import { registerRoute } from '@brightspaceui-labs/router.js';

registerRoute([
  {
    pattern: '/',
    view: () => html`<entry-point></entry-point>`
  },
  app1Loader,
  app2Loader
])

/* src/page1/route-loader.js */
export const loader () => [
  {
    pattern: '/app1',
    loader: () => import('./app1-view.js'),
    view: () => html`<app-1></app-1>`
  }
]

RouteReactor

The RouteReactor is a Reactive Controller responsible for re-rendering the nested view when the route changes.

import { RouteReactor } from '@brightspace-ui-labs/router';

class EntryPoint extends LitElement {

  constructor() {
    super();
    this.route = new RouteReactor(this);
  }

  render() {
    // Options for the views. Can be used for attributes */
    const options = { };
    return this.route.renderView(options);
  }

}

A RouteReactor can also be used to react to changes to the URL. The available properties are the same as the context object passed to the views above.

import { RouteReactor } from '@brightspace-ui-labs/router';

class FooBar extends LitElement {

  constructor() {
    super();
    this.route = new RouteReactor(this);
  }

  render() {
    const userId = this.route.params.userId;
    const orgId = this.route.search['org-unit'];
    return html`<span> user: ${userId} orgUnit: ${orgId}</span>`;
  }

}

Helpers

Navigating and Redirecting

Page.js will hook into any <a> tags and handle the navigation automatically. However, to navigate manually use navigate(path):

import { navigate } from '@brightspace-ui-labs/router';

navigate('/');

To programmatically redirect to a page and have the previous history item be replaced with the new one, use redirect(path):

import { redirect } from '@brightspace-ui-labs/router';

redirect('/');

Testing Routing in Your Application

For testing page routing in your application, this template is recommended:

describe('Page Routing', () => {

  beforeEach(async () => {
    // Initialize the routes here or import a file
    // that calls registerRoutes and expose a way to recall it
    initRouter(); 
    entryPoint = await fixture(html`<!-- Your ViewReactor component here -->`);
    navigate('/'); // Reset tests back to the index, clears the url
  });

  afterEach(() => {
    RouterTesting.reset(); // creates a new router instance, clears any router related reactive controllers.
  });

  // Your tests here

});

Developing and Contributing

After cloning the repo, run npm install to install dependencies.

Testing

To run the full suite of tests:

npm test

Alternatively, tests can be selectively run:

# eslint
npm run lint

# unit tests
npm run test:unit

Running the demos

To start a @web/dev-server that hosts the demo pages and tests:

npm start

Versioning and Releasing

This repo is configured to use semantic-release. Commits prefixed with fix: and feat: will trigger patch and minor releases when merged to main.

To learn how to create major releases and release from maintenance branches, refer to the semantic-release GitHub Action documentation.