static: add argument support to Router and add RouteMatch
This commit is contained in:
parent
1432f0648f
commit
feabd38173
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -24,7 +24,7 @@ export class Route {
|
|||
url: RegExp;
|
||||
|
||||
private element?: TemplateResult;
|
||||
private callback?: () => TemplateResult;
|
||||
private callback?: (args: { [key: string]: string; }) => TemplateResult;
|
||||
|
||||
constructor(url: RegExp, element?: TemplateResult) {
|
||||
this.url = url;
|
||||
|
@ -40,9 +40,14 @@ export class Route {
|
|||
return this;
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
then(render: (args: { [key: string]: string; }) => TemplateResult): Route {
|
||||
this.callback = render;
|
||||
return this;
|
||||
}
|
||||
|
||||
render(args: { [key: string]: string; }): TemplateResult {
|
||||
if (this.callback) {
|
||||
return this.callback();
|
||||
return this.callback(args);
|
||||
}
|
||||
if (this.element) {
|
||||
return this.element;
|
||||
|
@ -51,16 +56,36 @@ export class Route {
|
|||
}
|
||||
}
|
||||
|
||||
export const SLUG_REGEX = "[-a-zA-Z0-9_]+";
|
||||
export const ROUTES: Route[] = [
|
||||
// Prevent infinite Shell loops
|
||||
new Route(new RegExp("^/$")).redirect("/-/overview/"),
|
||||
new Route(new RegExp("^/applications/$"), html`<h1>test</h1>`),
|
||||
new Route(new RegExp(`^/$`)).redirect("/-/overview/"),
|
||||
new Route(new RegExp(`^/applications/$`), html`<h1>test</h1>`),
|
||||
new Route(new RegExp(`^/-/applications/(?<slug>${SLUG_REGEX})/$`)).then((args) => {
|
||||
return html`<h1>test</h1>
|
||||
|
||||
<span>${args.slug}</span>`;
|
||||
}),
|
||||
];
|
||||
|
||||
class RouteMatch {
|
||||
route: Route;
|
||||
arguments?: RegExpExecArray;
|
||||
fullUrl?: string;
|
||||
|
||||
constructor(route: Route) {
|
||||
this.route = route;
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
return this.route.render(this.arguments!.groups || {});
|
||||
}
|
||||
}
|
||||
|
||||
@customElement("pb-router-outlet")
|
||||
export class RouterOutlet extends LitElement {
|
||||
@property()
|
||||
activeRoute?: Route;
|
||||
current?: RouteMatch;
|
||||
|
||||
@property()
|
||||
defaultUrl?: string;
|
||||
|
@ -98,28 +123,35 @@ export class RouterOutlet extends LitElement {
|
|||
window.location.hash = `#${activeUrl}`;
|
||||
return;
|
||||
}
|
||||
let selectedRoute: Route | null = null;
|
||||
let matchedRoute: RouteMatch | null = null;
|
||||
ROUTES.forEach((route) => {
|
||||
if (route.url.exec(activeUrl)) {
|
||||
selectedRoute = route;
|
||||
console.log(`matching ${activeUrl} against ${route.url}`);
|
||||
const match = route.url.exec(activeUrl);
|
||||
if (match != null) {
|
||||
matchedRoute = new RouteMatch(route);
|
||||
matchedRoute.arguments = match;
|
||||
matchedRoute.fullUrl = activeUrl;
|
||||
return;
|
||||
}
|
||||
});
|
||||
if (!selectedRoute) {
|
||||
if (!matchedRoute) {
|
||||
console.log(
|
||||
`passbook/router: route "${activeUrl}" not defined, defaulting to shell`
|
||||
);
|
||||
selectedRoute = new Route(
|
||||
const route = new Route(
|
||||
RegExp(""),
|
||||
html`<pb-site-shell url=${activeUrl}>
|
||||
<div slot="body"></div>
|
||||
</pb-site-shell>`
|
||||
);
|
||||
matchedRoute = new RouteMatch(route);
|
||||
matchedRoute.arguments = route.url.exec(activeUrl)!;
|
||||
matchedRoute.fullUrl = activeUrl;
|
||||
}
|
||||
this.activeRoute = selectedRoute;
|
||||
this.current = matchedRoute;
|
||||
}
|
||||
|
||||
render() {
|
||||
return this.activeRoute?.render();
|
||||
return this.current?.render();
|
||||
}
|
||||
}
|
||||
|
|
Reference in New Issue