diff --git a/index.d.ts b/index.d.ts index 0bd00395..fe88227d 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 | undefined, fromComponent: ComponentBase | null) => 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 | undefined, fromComponent: ComponentBase | null) => string | Route | Promise; } export type Route = { diff --git a/src/router/router.js b/src/router/router.js index ec639eef..7c82222f 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 ( @@ -476,15 +477,17 @@ export const navigate = async function () { } let shouldAnimate = false + // Declare oldView in broader scope so it can be used in hooks below + let oldView = null // apply out out transition on previous view if available, unless // we're reusing the prvious page component if (previousRoute !== undefined && reuse === false) { // only animate when there is a previous route shouldAnimate = true - const oldView = this[symbols.children].splice(1, 1).pop() + oldView = this[symbols.children].splice(1, 1).pop() if (oldView) { - removeView(previousRoute, oldView, route.transition.out, navigatingBack) + await removeView(previousRoute, oldView, route.transition.out, navigatingBack) } } @@ -500,6 +503,37 @@ export const navigate = async function () { await setOrAnimate(holder, route.transition.in, shouldAnimate) } } + + if (this.parent[symbols.routerHooks]) { + const hooks = this.parent[symbols.routerHooks] + if (hooks.afterEach) { + try { + await hooks.afterEach.call( + this.parent, + route, // to + view, // toComponent + previousRoute, // from + oldView // fromComponent + ) + } catch (error) { + Log.error('Error in "AfterEach" Hook', error) + } + } + } + + if (route.hooks.after) { + try { + await route.hooks.after.call( + this.parent, + route, // to + view, // toComponent + previousRoute, // from + oldView // fromComponent + ) + } catch (error) { + Log.error('Error or Rejected Promise in "After" Hook', error) + } + } } else { Log.error(`Route ${route.hash} not found`) const routerHooks = this.parent[symbols.routerHooks]