diff --git a/index.d.ts b/index.d.ts index 0bd00395..a52d35c3 100644 --- a/index.d.ts +++ b/index.d.ts @@ -626,6 +626,7 @@ declare module '@lightningjs/blits' { export interface RouterHooks { init?: () => Promise<> | void; beforeEach?: (to: Route, from: Route) => string | Route | Promise | void; + afterEach?: (to: Route, toComponent: ComponentBase, from: Route, fromComponent: ComponentBase) => string | Route | Promise | void; error?: (err: string) => string | Route | Promise | void; } @@ -749,6 +750,7 @@ declare module '@lightningjs/blits' { export interface RouteHooks { before?: (to: Route, from: Route) => string | Route | Promise; + after?: (to: Route, toComponent: ComponentBase, from: Route, fromComponent: ComponentBase) => string | Route | Promise; } export type Route = { diff --git a/src/router/router.js b/src/router/router.js index ec639eef..a99c4177 100644 --- a/src/router/router.js +++ b/src/router/router.js @@ -335,6 +335,7 @@ export const navigate = async function () { return } } + // add the previous route (technically still the current route at this point) // into the history stack when inHistory is true and we're not navigating back if ( @@ -459,6 +460,41 @@ export const navigate = async function () { const children = this[symbols.children] this.activeView = children[children.length - 1] + if (this.parent[symbols.routerHooks]) { + const hooks = this.parent[symbols.routerHooks] + if (hooks.afterEach) { + try { + // Get the previous view before it's removed + const previousView = + !reuse && children.length > 1 ? children[children.length - 2] : null + + await hooks.afterEach.call(this.parent, { + to: route, + toComponent: view, + from: previousRoute, + fromComponent: previousView, + }) + } catch (error) { + Log.error('Error in "AfterEach" Hook', error) + } + } + } + + if (route.hooks.after) { + try { + // Get the previous view before it's removed + const previousView = !reuse && children.length > 1 ? children[children.length - 2] : null + await route.hooks.after.call(this.parent, { + to: route, + toComponent: view, + from: previousRoute, + fromComponent: previousView, + }) + } catch (error) { + Log.error('Error or Rejected Promise in "After" Hook', error) + } + } + // set focus to the view that we're routing to (unless explicitly disabling passing focus) if (route.options.passFocus !== false) { focus ? focus.$focus() : /** @type {BlitsComponent} */ (view).$focus()