UNPKG

@lwce/router

Version:
104 lines (82 loc) 2.32 kB
import { LightningElement, api, createContextProvider } from "lwc"; import { createBrowserHistory } from "history"; import matchPath from "./matchPath.js"; import { history } from "../../../wire-adapters/history"; const historyContextProvider = createContextProvider(history); export default class Router extends LightningElement { @api base = ""; routes = []; @api getHistory() { return this.history; } constructor() { super(); this.addEventListener( "lwcerouter_addrouteeventlistener", this.addRoute.bind(this) ); this.addEventListener( "lwcerouter_removeeventlistener", this.removeRoute.bind(this) ); this.history = createBrowserHistory(); this.unlisten = this.history.listen((location) => { this.checkRoutes(location); }); } connectedCallback() { historyContextProvider(this, { consumerConnectedCallback: (consumer) => { consumer.provide(this.history); }, }); } disconnectedCallback() { this.unlisten(); } addRoute(event) { event.stopPropagation(); this.routes.push({ ...event.detail, }); this.checkRoutes(window.location); } removeRoute(event) { event.stopPropagation(); const indexToRemove = this.routes.findIndex( (route) => route.path === event.detail.path && route.callback === event.detail.callback ); if (indexToRemove === -1) console.warn("Cannot find route to remove!"); else this.routes.splice(indexToRemove, 1); this.checkRoutes(window.location); } checkRoutes(location) { let aRouteMatched = false; this.routes.forEach((route) => { if (route.default) return; if (route.path === "*") { aRouteMatched = true; return route.callback({ found: true }); } const found = matchPath(location.pathname, { ...route, path: this.base + route.path, }); if (found) { aRouteMatched = true; route.callback({ found: true, data: found.params }); } else { route.callback({ found: false }); } }); this.routes.forEach((route) => { if (route.default) { route.callback({ found: !aRouteMatched }); } }); } navigate(e) { this.history.push(this.base + e.detail); } }