diff --git a/public/assets/arrow.png b/public/assets/arrow.png
new file mode 100644
index 0000000..7fb1e0f
Binary files /dev/null and b/public/assets/arrow.png differ
diff --git a/src/App.js b/src/App.js
index 123c721..9e8002b 100644
--- a/src/App.js
+++ b/src/App.js
@@ -47,13 +47,14 @@ import Slots from './pages/Slots'
import MemoryGame from './pages/MemoryGame'
import Exponential from './pages/Exponential'
import Viewport from './pages/Viewport'
+import { RouterHookRoutes } from './pages/RouterHooks.js'
import Resize from './pages/Resize'
import LanguagePlugin from './pages/LanguagePlugin.js'
export default Blits.Application({
template: `
-
+
`,
@@ -110,6 +111,9 @@ export default Blits.Application({
{ path: '/examples/events', component: Events },
{ path: '/examples/slots', component: Slots },
{ path: '/examples/viewport', component: Viewport },
+
+ ...RouterHookRoutes,
+
{ path: '/examples/resize', component: Resize },
{ path: '/examples/languageplugin', component: LanguagePlugin },
// Benchmarks and stress tests
diff --git a/src/pages/Portal.js b/src/pages/Portal.js
index ebf564c..24066a4 100644
--- a/src/pages/Portal.js
+++ b/src/pages/Portal.js
@@ -197,6 +197,11 @@ export default Blits.Component('Portal', {
id: 'examples/viewport',
description: 'Lifecycle events when entering and leaving the viewport (margins)',
},
+ {
+ title: 'Router Hooks',
+ id: 'examples/router-hooks',
+ description: 'Example of router before hook',
+ },
{
title: 'Image resizing',
id: 'examples/resize',
diff --git a/src/pages/RouterHooks.js b/src/pages/RouterHooks.js
new file mode 100644
index 0000000..3c85350
--- /dev/null
+++ b/src/pages/RouterHooks.js
@@ -0,0 +1,278 @@
+import Blits from '@lightningjs/blits'
+
+const hookPageTemplate = {
+ template: `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `,
+ props: [
+ {
+ key: 'page',
+ cast: Object,
+ },
+ ],
+ computed: {
+ pageTitle() {
+ //compute page title from page data, if there's no page data use default title
+ return (this.page && this.page.title) || this.title
+ },
+ },
+ state() {
+ //default state template to indicate which directions will be available if they are defined when "extending"
+ return {
+ title: 'Start',
+ up: 'up',
+ right: 'right',
+ down: 'down',
+ left: 'left',
+ }
+ },
+}
+
+//landing page of the router hook example, contains 2 flow examples
+export const RouterHookPage = Blits.Component('RouterHookPage', {
+ ...hookPageTemplate,
+ state() {
+ return {
+ title: 'Start',
+ down: 'episode flow',
+ right: 'movie flow',
+ }
+ },
+ input: {
+ right() {
+ //trigger router to navigate to movie flow
+ this.$router.to('/examples/router-hooks/movie')
+ },
+ down() {
+ //trigger router to navigate to episode flow
+ this.$router.to('/examples/router-hooks/episode/1')
+ },
+ },
+})
+
+//movie flow page, with 2 directions left: back, right: rating
+const Movie = Blits.Component('RouterHookMovie', {
+ ...hookPageTemplate,
+ state() {
+ return {
+ title: 'Movie',
+ left: 'Back',
+ right: 'Rating',
+ }
+ },
+ input: {
+ left() {
+ //trigger router back navigation. Leads back to: /examples/router-hooks
+ this.$router.back()
+ },
+ right() {
+ //trigger router to navigate to rating page
+ this.$router.to('/examples/router-hooks/rating')
+ },
+ },
+})
+
+//movie flow page, with 2 directions left: back, right: Router example page landing
+const Rating = Blits.Component('RouterHookRating', {
+ ...hookPageTemplate,
+ state() {
+ return {
+ title: 'Rating',
+ left: 'Back',
+ right: 'TO START',
+ }
+ },
+ input: {
+ left() {
+ //trigger router back navigation. Leads back to: /examples/router-hooks/movie
+ this.$router.back()
+ },
+ right() {
+ //trigger router to navigate to router hook example page landing
+ this.$router.to('/examples/router-hooks/')
+ },
+ },
+})
+
+//movie flow page, with 2 directions left: back, right: next episode
+const Episode = Blits.Component('RouterHookEpisode', {
+ ...hookPageTemplate,
+ state() {
+ return {
+ title: 'Episode',
+ left: 'Back',
+ right: 'NEXT EPISODE',
+ }
+ },
+ input: {
+ left() {
+ //trigger router back navigation. Leads back to: /examples/router-hooks. Even when episode id > 1
+ this.$router.back()
+ },
+ right() {
+ //trigger router to navigate to the next episode, and NOT save current episode page in navigation history
+ this.$router.to(`/examples/router-hooks/episode/${this.page.id + 1}`, undefined, {
+ inHistory: false,
+ })
+ },
+ },
+})
+
+//custom page transitions for when the router navigates to router example pages
+const PageTransitions = {
+ slideInOutLeft: {
+ before: {
+ prop: 'x',
+ value: '100%',
+ },
+ in: {
+ prop: 'x',
+ value: 0,
+ duration: 400,
+ },
+ out: {
+ prop: 'x',
+ value: '-100%',
+ duration: 400,
+ },
+ },
+ slideInOutRight: {
+ before: {
+ prop: 'x',
+ value: '-100%',
+ },
+ in: {
+ prop: 'x',
+ value: 0,
+ duration: 400,
+ },
+ out: {
+ prop: 'x',
+ value: '100%',
+ duration: 400,
+ },
+ },
+ slideInOutUp: {
+ before: {
+ prop: 'y',
+ value: '100%',
+ },
+ in: {
+ prop: 'y',
+ value: 0,
+ duration: 400,
+ },
+ out: {
+ prop: 'y',
+ value: '-100%',
+ duration: 400,
+ },
+ },
+ slideInOutDown: {
+ before: {
+ prop: 'y',
+ value: '-100%',
+ },
+ in: {
+ prop: 'y',
+ value: 0,
+ duration: 400,
+ },
+ out: {
+ prop: 'y',
+ value: '100%',
+ duration: 400,
+ },
+ },
+}
+
+export const RouterHookRoutes = [
+ {
+ path: '/examples/router-hooks',
+ component: RouterHookPage,
+ hooks: {
+ async before(to, from) {
+ //change transition based on 'from' route
+ if (from && from.path === 'examples/router-hooks/movie') {
+ to.transition = PageTransitions.slideInOutRight
+ }
+ if (from && from.path === 'examples/router-hooks/rating') {
+ to.transition = PageTransitions.slideInOutLeft
+ }
+ if (from && from.path.indexOf('episode') > -1) {
+ to.transition = PageTransitions.slideInOutDown
+ }
+ return to
+ },
+ },
+ },
+ {
+ path: '/examples/router-hooks/episode/:id',
+ component: Episode,
+ hooks: {
+ before(to, from) {
+ //change transition based on 'from' route
+ if (from && from.path.indexOf('episode') > -1) {
+ to.transition = PageTransitions.slideInOutLeft
+ }
+ const { id } = to.params
+ //if id > 5 lead route back to router example page landing
+ if (id > 5) {
+ return '/examples/router-hooks/'
+ }
+ //set page data based on episode ID
+ to.data.page = {
+ id: parseInt(id),
+ title: `Episode ${id}`,
+ }
+ return to
+ },
+ },
+ transition: PageTransitions.slideInOutUp,
+ },
+ {
+ path: '/examples/router-hooks/movie',
+ component: Movie,
+ hooks: {
+ before(to, from) {
+ //change transition based on 'from' route
+ if (from && from.path === 'examples/router-hooks') {
+ to.transition = PageTransitions.slideInOutLeft
+ }
+ if (from && from.path === 'examples/router-hooks/rating') {
+ to.transition = PageTransitions.slideInOutRight
+ }
+ return to
+ },
+ },
+ },
+ {
+ path: '/examples/router-hooks/rating',
+ component: Rating,
+ transition: PageTransitions.slideInOutLeft,
+ },
+]