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

@voliware/router-element

v2.7.1

Published

A simple router element built with custom elements

Downloads

49

Readme

What

Two simple elements, <router-element> and <route-element> that manage your page's view state and address bar history. You can use these elements to create an SPA or just a simple element with many nested views.

Example

<router-element nav="#nav1, #nav2">
    <route-element url="/" ></route-element>
    <route-element url="/users/login" display="flex"></route-element>
    <route-element url="/users/register"></route-element>
    <route-element url="/users/account/settings"></route-element>
    <route-element url="/movies"></route-element>
    <route-element url="/games"></route-element>
</router-element>

This is an example of a simple SPA. At the top is a <router-element> which will manage the routing, address bar, and history. The rest of the elements are <route-element>s which organize views by URL. The only function call that may be needed is route(url). This can be called from <router-element>.

const router = document.querySelector('router-element');
router.route('/users/account/settings');

This will reveal the /users/account/settings route and hide all others, which are hidden by default. Unless configured otherwise, the router will also reveal partial results. For example, if route('/users/accounts/settings/badroute') is called, it will route to /users/account/settings as it is the closest match.

Events

You can listen to the <router-element> event router.routed to take some action when a URL has been routed.

const router = document.querySelector('router-element');
router.addEventListener('router.routed', event => {
    console.log(`Went to this ${event.detail} route`);
});
router.route('/users/account/settings');

You can listen to the <router-element> event router.notfound to take some action when a URL has not been found.

const router = document.querySelector('router-element');
router.addEventListener('router.notfound', event => {
    console.log(`${event.detail} route does not exist!`);
});
router.route('/users/badurl');

You can listen to the <router-element> event router.beforeroute to take some action before a route is routed to. It also provides the ability to block a route from routing.

const router = document.querySelector('router-element');
router.addEventListener('router.beforeroute', event => {
    if(event.detail.url === 'restricted'){
        event.detail.cancel = true;
    }
});
router.route('/restricted');

If you have a nested element inside a <route-element> and it does something that should trigger a route change, you can simply dispatch a route event with the static route method. The <router-element> will handle it.

const btn = document.getElementById('button');
btn.addEventListener('click', () => {
    RouterElement.route(this, '/users/friends');
    // Same as this
    // this.dispatchEvent(new CustomEvent('router.route', {detail: '/users/friends', bubbles: true}));
});

Options

You can set the display attribute for <route-element> to change what display style it uses when it is revealed

<!-- When this route is displayed, it will use the flex style -->
<route-element url="/users/stats" display="flex"></route-element>

You can set some attributes for <router-element> for some minor behaviour differences

<router-element back="false"> will prevent intercepting the back navigation action from changing the current route.

<router-element history="false"> will prevent routing from updating the address bar.

<router-element partial="false"> will prevent routing to the best match possible if the exact route URL is not found.

<router-element auto="false"> will prevent the router from routing to the window location pathname on page load. To instead do this manually, call initialize() whenever your application is ready.

const router = document.querySelector('router-element');
router.initialize(); 

Navs

The <router-element> can also connect to one or more simple navigation elements. For example, suppose the following navigational HTML

<div id="navtop">
    <div url="/" class="route-element-nav"></div>
    <div url="/users" class="route-element-nav">
        <div url="/users/account" class="route-element-nav">
            <div url="/users/account/settings" class="route-element-nav"></div>
        </div>
    </div>
    <div url="/movies" class="route-element-nav"></div>
    <div url="/games" class="route-element-nav"></div>
</div>

Notice how each nav in question has a class="route-element-nav" and a url. These are the only attributes required to be a valid navigation element. To connect this nav to a <route-element> add a nav="" attribute with one or more ids. Multiple ids are supported in the case that there may be two identical menus in the HTML, such as a top and bottom navigation system.

<router-element nav="#navtop, #navbottom"></router-element>

When a url is navigated to, <router-element> will set the appropriate nav's class to route-element-nav-active and remove the same class from all others. The only other step is to define a class in your stylesheet somewhere like

.route-element-nav-active {
    color: white;
}

Don'ts!

  • Don't have more than one of the same route! URLs should be unique, as designed.

For Your Information

  1. Adding routes dynamically will call a function which will recapture all <route-element>s
  2. Custom elements that extend RouteElement are also supported as each child is checked to be an instanceof RouteElement
  3. Changing url attributes also triggers a call to recapture all routes

Install or include

npm install @voliware/router-element

You can then build it into your own distribution file or serve it via

./node_modules/@voliware/router-element/dist/router-element.min.js

./node_modules/@voliware/router-element/dist/router-element.min.css

Or you can use a CDN

<script src="https://cdn.jsdelivr.net/npm/@voliware/router-element/dist/router-element.min.js"></script>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@voliware/router-element/dist/router-element.min.css"/>

Or you can simply download the files in the /dist folder off the repo.

Tests

Run npm run test.

Future

Fragmented <route-element>s that aren't all organized in the HTML as direct children. This would be useful for HTML that resides in one file and has become very nested.