riot-view-router is a lightweight, extensive state based riot.js router for tag views. It was designed after the ui-router project, with all the quirks of riot.js.
This project makes use of the HTML5 history api, using pushState
under the hood; in other words this is a client sided router.
Chome | Edge | Firefox | Opera | Safari |
---|---|---|---|---|
5.0+ ✔ | ✔ | 4.0+ ✔ | 11.50+ ✔ | 5.0+ ✔ |
This project only supports riot.js 3, support for previous versions is not available.
- riot-todo: Todo web app created with riot.js, skeletoncss, animate.css, and foundation-icons.
To install via Bower, simply do the following:
bower install riot-view-router
To install via NPM:
npm install riot-view-router
For a quick start using jsdelivr:
<script src="https://cdn.jsdelivr.net/npm/riot-view-router/dist/riot-view-router.min.js"></script>
riot-view-router supports the following settings,
*default
;string
: Default state for router to navigate to on start if route not matched.
debugging
;bool
: Will default to true, spits errors and warnings to console.
href
;string
: Will default to originating location, router will operate off of this.
fragments
;bool
: Will default to true, adds support for fragment identification.
fallback
;string
: Will default to fallback, state to fallback to on mismatch.
title
;string
: Title prefix for routes using a page title.
marker
;string
: Marker for mounting views, default isr-view
.
<r-view />
or
<div r-view></div>
States are composed of the following properties,
*name
;string
: State name.
*route
;string
: Route to match state by.
*tag
;string
: Tag to inject into rout view, mount.
title
;string
: Title suffix for routes.
onEnter(*handler)
;function
: Callback for entering state.
onLeave(*handler)
;function
: Callback for leaving state.
Using the mixin is then as simple as,
import riot from 'riot'
import Router from 'riot-view-router'
const router = new Router(riot, {
debugging: true,
default: 'home',
fallback: '404',
href: 'https://mysite.com/blogs'
})
router.add({
name: '404',
route: '/notfound',
tag:'not-found',
title: '404 Page Not Found',
onLeave: (state) => {
console.log('Leaving home')
}
})
router.add([
{
name: 'home',
route: '/',
tag:'home',
title: 'Hello World',
onEnter: (state) => {
console.log('Entering home')
}
},
{
name: 'profile',
route: '/profile/:username',
tag: 'profile',
title: '<username>\'s profile'
}
])
You may then access the Router
instance via your tags with router
like so,
<app>
<r-view></r-view>
this.router.start()
</app>
To navigate to a route within your riot tags, you may use r-sref
to reference a state on any element supporting a click event listener. r-sref
can be used with both complete routes and state names.
<sometag>
<button r-sref="/profile/{username}">Navigate to profile</button>
<a r-sref="about">About Page</a>
</sometag>
You may also use a general anchor tag, the router comes with a helper function baked in to help construct urls on the fly. It also supports url encoding.
<sometag>
<a href={ route(['profile', username]) }>Profile</a>
</sometag>
Both route and query string variables can also be accessed directly via the target tag with opts. Take for example navigating to the url .../!#/profile/john?views=1
with the route pattern /profile/:username
.
<profile>
<h1>
User: <small>{this.opts.username}</small>
</h1>
<h5>Views: {this.opts.qargs.views}</h5>
</profile>
The riot-view-router has a very simple, easily operable API.
add(*state)
: Create a new state for the given router instance.
navigate(*route, skipPush)
: Navigate to a given route.
push(name, opts)
: Invoke a state change. If arguments arent specified, automatically detect the state and extract opts from the defined state variables.
start()
: Start router, listen on window hash changes.
stop()
: Stop router, related listeners and lifecycle events.
reload()
: Reload current route.
on(*event, *handler)
: Register a lifecycle event (start, stop, navigation, push, transition).
This router supports the following observable events,
start
: Triggered when the router is started.
stop
: Triggered when the router is stopped.
reload
: Triggered when a route is reloaded.
navigate
: Trigerred when navigation occurs.
push
: Triggered when pushing a new state.
transition
: Triggered when transitioning into a new state, emits an optional argument state.
<Header>
<nav>
<ul>
<li each={ route in routes }
class={ is-active: route.active }
r-sref={ route.state }>
{ route.label }
</li>
</ul>
</nav>
<script type="es6">
const self = this
self.routes = [
{ label: 'Home', state: 'home', active: false },
{ label: 'About', state: 'about', active: false },
{ label: 'Help', state: 'help', active: false },
]
// middleware for toggling nav items
self.router.on('transition', state => {
self.routes.forEach(route => {
route.active = false
})
const s = self.routes.find(i => i.name == state.name)
if(s)
s.active = true
self.update()
})
</script>
</Header>
- John Nolette (john@neetgroup.net)
Contributing guidelines are as follows,
-
Any new features must include either a unit test, e2e test, or both.
- Branches for bugs and features should be structured like so,
issue-x-username
.
- Branches for bugs and features should be structured like so,
-
Before putting in a pull request, be sure to verify you've built all your changes.
Travis will build your changes before testing and publishing, but bower pulls from this repository directly.
-
Include your name and email in the contributors list.
Copyright (c) 2017 John Nolette Licensed under the MIT license.