sophie-router
v1.0.8-beta
Published
Provides simple components in order to have routing in your application
Downloads
19
Readme
Sophie Router
Provides simple components in order to have routing in your application. Ideal for single page applications where you need to handle the routing.
Part of the SPA framework Sophie
INSTALLATION
yarn add sophie-router
USAGE
Basically consist of an Application class you need to extend from. This will be your shared state across different pages.
Then you need to instantiate Resource Routers and associate to them Resources the first ones will match a wildcard for a path while the second ones are the concrete resource to run for a matching path. For example we have an application that consists of the home page, and two other pages.
We need to handle the following paths:
- /
- /page1
- /page2
So first we can create the ResourceRouter that will handle the root path
HomeResourceRouter.ts
import { AbstractResourceRouter } from 'sophie-router';
export const HOME_PATH = /^\/+$/g;
export class HomeResourceRouter extends AbstractResourceRouter
{
protected canRoute (pathName: string): boolean
{
return !!pathName.match(HOME_PATH);
}
}
Then the Resource
HomeResource.ts
import { AbstractApplication, AbstractResource } from 'sophie-router';
import { HOME_PATH } from './HomeResourceRouter';
export class HomeResource extends AbstractResource
{
public getPath (): RegExp
{
return HOME_PATH;
}
public run (app: AbstractApplication, pathName?: string, search?: string): void
{
console.log('Run Homepage');
}
}
The same for the other pages
PageResourceRouter.ts
import { AbstractResourceRouter } from 'sophie-router';
export const PAGE_PATH = /page\d?/g;
export class PageResourceRouter extends AbstractResourceRouter
{
protected canRoute (pathName: string): boolean
{
return !!pathName.match(PAGE_PATH);
}
}
Page1Resource.ts
import { AbstractApplication, AbstractResource } from 'sophie-router';
export class Page1Resource extends AbstractResource
{
public getPath (): RegExp
{
return /page1/g;
}
public run (app: AbstractApplication, pathName?: string, search?: string): void
{
console.log('Run Page 1');
}
}
Page2Resource.ts
import { AbstractApplication, AbstractResource } from 'sophie-router';
export class Page2Resource extends AbstractResource
{
public getPath (): RegExp
{
return /page2/g;
}
public run (app: AbstractApplication, pathName?: string, search?: string): void
{
console.log('Run Page 2');
}
}
Now we can create our Application, the one that we get in the run methods from the Resources
Application.ts
import { AbstractApplication } from 'sophie-router';
export class Application extends AbstractApplication
{
// Extend me ...
}
To finish we just need to create our index or entry point
index.ts
import {
AbstractApplication,
Framework,
AbstractResourceRouter,
AbstractResource
} from 'sophie-router';
import { Application } from './Application';
import { HomeResourceRouter } from './HomeResourceRouter';
import { PageResourceRouter } from './PageResourceRouter';
import { HomeResource } from './HomeResource';
import { Page1Resource } from './Page1Resource';
import { Page2Resource } from './Page2Resource';
// Instantiate objects
const application: AbstractApplication = new Application(); // Create our application
const framework: Framework = Framework.createInstance(application); // Create the framework that will handle the routing
// Create the resource routers
const homeResourceRouter: AbstractResourceRouter = new HomeResourceRouter();
const pageResourceRouter: AbstractResourceRouter = new PageResourceRouter();
// Create some resources for the routers
const homePage: AbstractResource = new HomeResource();
const page1: AbstractResource = new Page1Resource();
const page2: AbstractResource = new Page2Resource();
// Add resources to routers
homeResourceRouter.addResource(homePage);
pageResourceRouter.addResource(page1);
pageResourceRouter.addResource(page2);
// Register the routers in the framework
framework.registerResourceRouter(homeResourceRouter);
framework.registerResourceRouter(pageResourceRouter);
// Run the application
framework.run(location.pathname, location.search);
TIP: You need to handle the navigation in your application in order to have a SPA to avoid normal navigation and instead use the router, for that I recommend the following snippet
index.ts
// Add this to the imports
import { bubbleUpToTag } from "sophie-helpers";
// Add the next to the end of index.ts
const HTTP_PROTOCOL: string = 'http://';
const HTTPS_PROTOCOL: string = 'https://';
const MAIL_TO_PROTOCOL: string = 'mailto:';
document.addEventListener('click', (event) =>
{
const link = bubbleUpToTag(event.target as HTMLElement || event.srcElement as HTMLElement, 'a');
if (link)
{
const href = (link as HTMLLinkElement).getAttribute('href');
if (
href &&
href.substr(0, HTTP_PROTOCOL.length) !== HTTP_PROTOCOL &&
href.substr(0, HTTPS_PROTOCOL.length) !== HTTPS_PROTOCOL &&
href.substr(0, MAIL_TO_PROTOCOL.length) !== MAIL_TO_PROTOCOL)
{
event.stopPropagation();
event.preventDefault();
history.pushState({}, '', href);
framework.run(href);
}
}
});
window.onpopstate = () => {
framework.run(location.pathname, location.search);
};
Changelog
Contributing
License
This software is licensed under the terms of the MIT license. See LICENSE for the full license.