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

radiant-router

v0.11.0

Published

A router for Polymer that syncs the URL to a JavaScript object

Downloads

12

Readme

Radiant Router

The <radiant-router> is a custom element which synchronizes a URL to a JavaScript object and vice versa. It supports query parameters and path capturing.

Installation

NPM (Polymer 3):

npm install radiant-router

Bower (Polymer 1 and 2):

bower install --save MajorBreakfast/radiant-router

Demo

This router is used in production in the Wolf Service App (Spare parts catalog app for the heating, air handling and ventilation systems supplier Wolf GmbH).

How It Works

When the url property changes:

URL -----(1)---> routing              routeState
    <----(2)---- system  ----(2)---->

When the routeState object changes:

                 routing <---(1)----- routeState
URL <----(2)---- system  ----(2)---->
  • The routing system connects the url with the routeState bidirectionally.
  • The url property is meant to be synced to the URL bar, e.g. using <iron-location>. The routing system keeps the URL in a consitent state, this means that after it detects changes, it might further change the URL, e.g. to remove a trailing slash.
  • The routeState property is an object which is meant to be manipulated by the app. The routing system keeps the routeState object in a consistent state, this means that after it detects changes, it might further change the routeState object, e.g. to remove unknown properties. You can see in the example in the next section how the routeState object looks like.

How To Use

This section shows you how to use the <radiant-router>.

Polymer 3:

import { Element } from '../@polymer/polymer/polymer-element.js'
import '../@polymer/iron-location/iron-location.js'
import { RadiantRoute } from '../radiant-router/radiant-router.js'

class MyApp extends Element {
  static get template () {
    return `
      <iron-location hash="{{url}}"></iron-location>
      <radiant-router url="{{url}}"
                      route-state="{{routeState}}"
                      root-route="[[rootRoute]]"></radiant-router>
    `
  }

  static get is () { return 'my-app' }

  static get properties () {
    return {
      rootRoute: {
        type: Object,
        value: function () {
          return new RadiantRoute('')
            .add(new RadiantRoute('home'))
            .add(new RadiantRoute('about')
              .add(new RadiantRoute('terms-of-use'))
              .add(new RadiantRoute('imprint'))
            )
            .add(new RadiantRoute('catalog')
              .capturePath()
              .booleanQueryParam({ variableName: 'isSearchShown',
                                   queryParamName: 'search' })
              .stringQueryParam({ variableName: 'searchTerm',
                                  queryParamName: 'search-term' })
            )
        }
      }
    }
  }
}
customElements.define(RadiantRouter.is, RadiantRouter)

Polymer 1 and 2:

<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/iron-location/iron-location.html">
<link rel="import" href="../bower_components/radiant-router/radiant-router.html">

<dom-module id="my-app">
  <template>
    <iron-location hash="{{url}}"></iron-location>
    <radiant-router url="{{url}}"
                    route-state="{{routeState}}"
                    root-route="[[rootRoute]]"></radiant-router>
  </template>
  <script>
    Polymer({
      is: 'my-app',

      properties: {
        rootRoute: {
          type: Object,
          value: function () {
            return new RadiantRoute('')
              .add(new RadiantRoute('home'))
              .add(new RadiantRoute('about')
                .add(new RadiantRoute('terms-of-use'))
                .add(new RadiantRoute('imprint'))
              )
              .add(new RadiantRoute('catalog')
                .capturePath()
                .booleanQueryParam({ variableName: 'isSearchShown',
                                     queryParamName: 'search' })
                .stringQueryParam({ variableName: 'searchTerm',
                                    queryParamName: 'search-term' })
              )
          }
        }
      }
    })
  </script>
</dom-module>

<iron-location> is used to sync the url string to the url bar of the browser.

The routeState object looks like this:

{
  activeChild: 'about',
  queryParams: {},
  children: {
    home: { activeChild: null, queryParams: {}, children: {} },
    about: {
      activeChild: null,
      queryParams: {},
      children: {
        'terms-of-use': { activeChild: null, queryParams: {}, children: {} },
        imprint: { activeChild: null, queryParams: {}, children: {} }
      }
    },
    catalog: {
      activeChild: null,
      queryParams: { isSearchShown: false, searchTerm: 'My query' },
      children: {},
      path: ''
    }
  }
}

You can freely modify the routeState object in your application. You may:

  • Set the activeChild properties to change which routes are active.
  • Change properties of the queryParams objects.
  • Change the path property of the 'catalog' route (which has path capturing enabled)

All changes will be reflected back to the URL.

Tips and Tricks

How to Redirect

Redirecting can be implemented by setting up an observer to the routeState object.

The following code redirects from any unknown route to the 'home' route. Simply checking whether the activeChild property is null suffices, because the router automatically sets it to null whenever it encounters an unknown route.

static get observers () {
  return ['_onActiveChildRouteChange(routeState.activeChild)']
}
_onActiveChildRouteChange (routeName) {
  if (!routeName) { // null? => Redirect to home
    Promise.resolve().then(() => { this.set('routeState.activeChild', 'home') })
  }
}

Polymer expects that _onActiveChildRouteChange() doesn't change the value while it runs. Therefore the desired modification is done asynchronously using a Promise (Promises have microtask timing, i.e. the browser will not rerender in the meantime). More about Polymer's observers in the documentation chapter about observers.