UNPKG

storybook-vue3-router

Version:

A Storybook decorator that allows you to build stories for your routing-aware components.

180 lines (170 loc) 5.52 kB
'use strict'; var vue = require('vue'); var vueRouter = require('vue-router'); var actions = require('storybook/actions'); const Home = { template: ` <div> <h2>Home</h2> <div style="display: flex; gap: 1em"> <router-link to="/">Home</router-link> <router-link to="/about">About</router-link> </div> </div> ` }; const About = { template: ` <div> <h2>About</h2> <div style="display: flex; gap: 1em"> <router-link to="/">Home</router-link> <router-link to="/about">About</router-link> </div> </div> ` }; const defaultRoutes = [ { path: "/", name: "home", component: Home, beforeEnter: (to, from) => actions.action("beforeEnter")({ to: to.fullPath, from: from.fullPath }) }, { path: "/about", name: "about", component: About, beforeEnter: (to, from) => actions.action("beforeEnter")({ to: to.fullPath, from: from.fullPath }) } ]; function globalRouterGuardFn(router, beforeEach, forceReload = false) { if (typeof beforeEach === "function") { if (forceReload) { router.go(0); return; } router.beforeEach((to, from, next) => beforeEach(to, from, next)); } } function initialRoute(router, initialRoute2) { router.replace(initialRoute2 || "/"); } function resetRoutes(router, newRoutes) { const oldRoutes = router.getRoutes(); oldRoutes.forEach((route) => { router.removeRoute(route.name); }); newRoutes.forEach((route) => { router.addRoute(route); }); } function getFromArgs(args, options) { let filtered = {}; options.forEach((option) => { filtered = { ...filtered, [option]: args[option] }; }); return filtered; } function withVueRouter(routes = defaultRoutes, options) { return () => ({ setup() { const { app } = vue.getCurrentInstance().appContext; let router; const existingRouter = app.config.globalProperties.$router; const existingRoute = app.config.globalProperties.$route; if ((!existingRouter || existingRouter.isMocked === true) && (!existingRoute || existingRoute.isMocked === true)) { router = vueRouter.createRouter({ history: vueRouter.createWebHashHistory(), routes, ...options?.vueRouterOptions }); globalRouterGuardFn(router, options?.beforeEach); app.use(router); } else { router = existingRouter; resetRoutes(router, routes); globalRouterGuardFn(existingRouter, options?.beforeEach, true); } initialRoute(router, options?.initialRoute); }, template: "<story/>" }); } function withAsyncVueRouter(routes = defaultRoutes, options) { return () => ({ async setup() { const { app } = vue.getCurrentInstance().appContext; let router; const existingRouter = app.config.globalProperties.$router; const existingRoute = app.config.globalProperties.$route; if ((!existingRouter || existingRouter.isMocked === true) && (!existingRoute || existingRoute.isMocked === true)) { router = vueRouter.createRouter({ history: vueRouter.createWebHashHistory(), routes, ...options?.vueRouterOptions }); globalRouterGuardFn(router, options?.beforeEach); app.use(router); } else { router = existingRouter; resetRoutes(router, routes); globalRouterGuardFn(existingRouter, options?.beforeEach, true); } initialRoute(router, options?.initialRoute); await router.isReady(); }, template: ` <story/> ` }); } function withMockRouter(options) { return (_, ctx) => ({ setup() { const { app } = vue.getCurrentInstance().appContext; const existingRouter = app.config.globalProperties.$router; const existingRoute = app.config.globalProperties.$route; const forceReload = existingRouter && existingRouter.isMocked !== true && (existingRoute && existingRoute.isMocked !== true); if (forceReload) { existingRouter.go(0); return; } else { app.config.globalProperties.$router = { isMocked: true, // !IMPORTANT this line is required to ensure the full vue-router implementation can initialize push: async (location) => { actions.action("$router.push()")(location); }, replace: async (location) => { actions.action("$router.replace()")(location); }, go: (n) => { actions.action("$router.go()")(n); }, back: () => { actions.action("$router.back()")("back"); }, forward: () => { actions.action("$router.forward()")("forward"); } }; app.config.globalProperties.$route = { isMocked: true, // !IMPORTANT this line is required to ensure the full vue-router implementation can initialize path: ctx.args?.path || "/", fullPath: `/#${ctx.args?.path}`, name: ctx.args?.name || "home", meta: options.meta ? getFromArgs(ctx.args, options.meta) : {}, params: options.params ? getFromArgs(ctx.args, options.params) : {}, query: options.query ? getFromArgs(ctx.args, options.query) : {} }; } }, template: "<story/>" }); } exports.asyncVueRouter = withAsyncVueRouter; exports.mockRouter = withMockRouter; exports.vueRouter = withVueRouter; //# sourceMappingURL=index.cjs.map