Package Exports
- custom-elements-router
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (custom-elements-router) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Router for custom elements
The router is very similar to react-router.
Contents
How to install
First of all you need to install custom-elements-jsx
module and configure it. Here is the library. You must configure babel like it is described in the README.md of the custom-elements-jsx
.
Then you can install custom-elements-router
:
$ npm install --save custom-elements-router
or
$ yarn add custom-elements-router
Usage
You need to import custom-elements-router
once to get access to all custom elements from the library. For example, you can import it in your root index.js file:
import jsx from "custom-elements-jsx";
import "custom-elements-router";
import createHistory from "history/createBrowserHistory";
const browserHistory = createHistory();
const app = (
<custom-router history={browserHistory}>
<custom-switch>
<custom-route path="/" component="main-page" />
</custom-switch>
</custom-router>
);
const root = document.getElementById("root");
root.appendChild(app);
Or you can wrap your custom element by the custom-router
:
import jsx from "custom-elements-jsx";
import "custom-elements-router";
import createHistory from "history/createBrowserHistory";
import "./app.js";
const browserHistory = createHistory();
const app = (
<custom-router history={browserHistory}>
<app-page />
</custom-router>
);
const root = document.getElementById("root");
root.appendChild(app);
Inside of <app-page />
you will get context
object that you must pass to other custom elements from custom-elements-router
:
import jsx, { Component } from "custom-elements-jsx";
class AppPage extends Component {
render() {
const { context } = this.props;
return (
<custom-switch context={context}>
<custom-route path="/" component="main-page" />
<custom-route path="/users" exact component="users-page" />
</custom-switch>
);
}
}
if (!window.customElements.get("app-page"))
window.customElements.define("app-page", AppPage);
<custom-switch>
chooses one of his children with correct path
property. Other children will not be rendered.
If you use custom-route
outside of custom-switch
then all routes will be rendered, but only one custom-route
will have children. Other routes will be empty.
<custom-route>
receives the same props as <Route>
from react-router
library: path
, exact
, component
, render
. Also it receives context
prop. You should remember about this if you user <coustom-route>
outside of <custom-switch>
or <custom-router>
.
In the path
property you should specify full path. Also you can specify variable, for example userId
:
<custom-route path="/users/:userId" component="user-page" />
Then you will get userId
from context
object inside of <user-page>
:
import jsx, { Component } from "custom-elements-jsx";
class UserPage extends Component {
render() {
const { context } = this.props;
const { userId } = context.match.params;
return null;
}
}
The context
object has following props: history
, match
, location
, staticContext
. The same props as in react-router
library.
You can find pathname
from this.props.context.location.pathname
.
If you specify the exact
property then exact match will be found for this route. Otherwise entry will be found. It can be usefull if you want to use <custom-route>
inside of your custom element.
import jsx, { Component } from 'custom-elements-jsx'
// root index.js
cosnt app = (
<custom-router history={browserHistory}>
<custom-route path="/" component="home-page" />
</custom-router>
)
// homePage.js
class HomePage extends Component {
render() {
const { context } = this.props
return (
<custom-switch context={context}>
<custom-route path="/users" exact component="users-page" />
<custom-route path="/settings" exact component="settings-page" />
</custom-switch>
)
}
}
In the component
property you should specify name of your custom element. You should define this element before using in the component
. Type of component
property is string.
Also you can specify render
property. This is a function that receives props as first argument. This function must return HTMLElement:
import jsx, { Component } from "custom-elements-jsx";
const app = (
<custom-router history={browserHistory}>
<custom-route
path="/"
name="John"
render={props => <div>{props.name}</div>}
/>
</custom-router>
);
You will get:
<custom-router>
<custom-route>
<div>John</div>
</custom-route>
</custom-router>
If you specify both props component
and render
then render
will be used.
You have 2 links in the <custom-elements-router
: <custom-link>
and <custom-nav-link>
. You must pass the context
object to both of it. This links receive the same props as links in react-router
library.
You can use <custom-redirect>
this way:
import jsx from "custom-elements-jsx";
import "custom-elements-router";
import createHistory from "history/createBrowserHistory";
const browserHistory = createHistory();
const element = (
<custom-router history={history}>
<custom-switch>
<custom-route path="/" exact component="page-home" />
<custom-route path="/users" exact component="page-users" />
<custom-redirect from="/" to="/users" />
</custom-switch>
</custom-router>
);
This application understands only 2 routes: /
and /users
. Other routes will be redirected to the /users
route, cause <custom-redirect>
doesn't have exact
property. But you can specify this property you need.
Features
There is an another way to use <custom-router>
without <custom-switch>
and <custom-route>
. You can pass array of routes as a property routes
to the <custom-router>
.
// root index.js
import jsx, { Component } from "custom-elements-jsx";
import "custom-elements-router";
import createHistory from "history/createBrowserHistory";
const browserHistory = createHistory();
const routes = [
{
path: "/",
component: "root-page",
routes: [
{
path: "/users",
component: "users-page",
exact: true
},
{
path: "/settings",
component: "settings-page",
exact: true
}
]
}
];
const app = <custom-router history={browserHistory} routes={routes} />;
const root = document.getElementById("root");
root.appendChild(app);
Each component (root-page
, users-page
, etc) will get 2 props: context
and route
. route
is an object from routes
array. For example, component root-page
will get following object as route
property:
{
path: "/",
component: "root-page",
routes: [
{
path: "/users",
component: "users-page",
exact: true
},
{
path: "/settings",
component: "settings-page",
exact: true
}
]
}
But users-page
will get:
{
path: "/users",
component: "users-page",
exact: true
}
You can render nested routes inside of root-page
using function renderRoutes()
:
import jsx, { Component } from "custom-elements-jsx";
import { renderRoutes } from "custom-elements-router";
class RootPage extends Component {
render() {
const { route, context } = this.props;
return renderRoutes(route.routes, context);
}
}
if (!window.customElements.get("root-page"))
window.customElements.define("root-page", RootPage);
You must pass the context
object to the renderRoutes()
function.
Also you have matchRoutes()
function. This is the same function like in the react-router
library.
You can use custom-redirect
in the array of routes:
import jsx from "custom-elements-jsx";
import "custom-elements-router";
import createHistory from "history/createBrowserHistory";
const browserHistory = createHistory();
const routes = [
{
path: "/",
component: "page-home",
exact: true
},
{
path: "/users",
component: "page-users",
exact: true
},
{
from: "/",
component: "custom-redirect",
to: "/users"
}
];
const element = <custom-router history={browserHistory} routes={routes} />;
It works like It was described above.
If you don't want to pass history to the <custom-router>
element you can use <custom-browser-router>
. Browser history will be created inside of this element.
Also you have <custom-hash-router>
and <custom-memory-router>
. They are the same like in react-router
library. All of it receive the same props as <custom-router>
element.
How to test
To test this library you need to install Chrome browser if you still don`t have. Then you need to run:
npm install && npm run test
or
yarn && yarn test
If you want to run tests in watching mode you need to use test:watch
except test
command.