diff --git a/index.d.ts b/index.d.ts index 094881bd..4c5c9368 100644 --- a/index.d.ts +++ b/index.d.ts @@ -423,7 +423,16 @@ declare module '@lightningjs/blits' { watch?: W & ComponentContext } - export interface ApplicationConfig

extends ComponentConfig { + export interface RouterHooks { + beforeEach?: (to: Route, from: Route) => string | Route | Promise; + } + + export interface RouterConfig { + /** + * Register hooks for the router + */ + hooks?: RouterHooks, + /** * Routes definition * @@ -440,6 +449,33 @@ declare module '@lightningjs/blits' { routes?: Route[] } + export type ApplicationConfig

= ComponentConfig & ( + { + /** + * Router Configuration + */ + router?: RouterConfig, + routes?: never + } + | + { + router?: never + /** + * Routes definition + * + * @example + * + * ```js + * routes: [ + * { path: '/', component: Home }, + * { path: '/details', component: Details }, + * { path: '/account', component: Account }, + * ] + * ``` + */ + routes?: Route[] + } + ) export interface Transition { /** diff --git a/src/component/setup/index.js b/src/component/setup/index.js index 113838fc..53a8b675 100644 --- a/src/component/setup/index.js +++ b/src/component/setup/index.js @@ -20,7 +20,7 @@ import setupMethods from './methods.js' import setupState from './state.js' import setupComputed from './computed.js' import setupInput from './input.js' -import setupRoutes from './routes.js' +import setupRouter from './routes.js' import setupWatch from './watch.js' import { registerHooks } from '../../lib/hooks.js' @@ -53,8 +53,9 @@ export default function (component, config) { // // setup watchers if (config.watch) setupWatch(component, config.watch) - // // setup routes - if (config.routes) setupRoutes(component, config.routes) + // // setup router + const routerConfig = config.router !== undefined ? config.router : config.routes + if (routerConfig !== undefined) setupRouter(component, routerConfig) // // setup input if (config.input) setupInput(component, config.input) diff --git a/src/component/setup/routes.js b/src/component/setup/routes.js index 9166c7b0..a4d22418 100644 --- a/src/component/setup/routes.js +++ b/src/component/setup/routes.js @@ -17,7 +17,12 @@ import symbols from '../../lib/symbols.js' -export default (component, routes) => { +export default (component, data) => { + let routes = data + if (Array.isArray(data) === false) { + component[symbols.routerHooks] = data.hooks + routes = data.routes + } component[symbols.routes] = [] Object.keys(routes).forEach((key) => { // todo: validate routes[key] for expected format etc. diff --git a/src/lib/symbols.js b/src/lib/symbols.js index 85d5fe76..09e55e9c 100644 --- a/src/lib/symbols.js +++ b/src/lib/symbols.js @@ -20,6 +20,7 @@ export default { ready: Symbol('ready'), renderer: Symbol('renderer'), routes: Symbol('routes'), + routerHooks: Symbol('routerHooks'), settings: Symbol('settings'), state: Symbol('state'), stateKeys: Symbol('stateKeys'), diff --git a/src/router/router.js b/src/router/router.js index 36879a82..bd3f6e3a 100644 --- a/src/router/router.js +++ b/src/router/router.js @@ -135,8 +135,22 @@ export const navigate = async function () { } currentRoute = route - let beforeHookOutput if (route) { + let beforeEachResult + if (this.parent[symbols.routerHooks]) { + const hooks = this.parent[symbols.routerHooks] + if (hooks.beforeAll) { + beforeEachResult = await hooks.beforeAll(route, previousRoute) + if (isString(beforeEachResult)) { + to(beforeEachResult) + return + } + } + } + // If the resolved result is an object, assign it to the target route object + route = isObject(beforeEachResult) ? beforeEachResult : route + + let beforeHookOutput if (route.hooks) { if (route.hooks.before) { beforeHookOutput = await route.hooks.before.call(this.parent, route, previousRoute)