From 3c525af917bcc4c9b12a0072057dbdab66d25fe2 Mon Sep 17 00:00:00 2001 From: taskylizard <75871323+taskylizard@users.noreply.github.com> Date: Fri, 17 Nov 2023 13:26:59 +0530 Subject: [PATCH] Show progress on route change --- .vitepress/theme/composables/nprogress.ts | 23 +++++++ .vitepress/theme/index.ts | 5 +- .vitepress/theme/style.css | 82 +++++++++++++++++++++++ package.json | 2 + pnpm-lock.yaml | 23 +++++-- 5 files changed, 130 insertions(+), 5 deletions(-) create mode 100644 .vitepress/theme/composables/nprogress.ts diff --git a/.vitepress/theme/composables/nprogress.ts b/.vitepress/theme/composables/nprogress.ts new file mode 100644 index 000000000..89e6c8d8e --- /dev/null +++ b/.vitepress/theme/composables/nprogress.ts @@ -0,0 +1,23 @@ +import nprogress, { type NProgress } from "nprogress"; +import type { EnhanceAppContext } from "vitepress"; + +export function loadProgress(router: EnhanceAppContext["router"]): NProgress { + if (typeof window === "undefined") return; + + setTimeout(() => { + nprogress.configure({ showSpinner: false }); + + const cacheBeforeRouteChange = router.onBeforeRouteChange; + const cacheAfterRouteChange = router.onAfterRouteChanged; + router.onBeforeRouteChange = (to) => { + nprogress.start(); + cacheBeforeRouteChange?.(to); + }; + router.onAfterRouteChanged = (to) => { + nprogress.done(); + cacheAfterRouteChange?.(to); + }; + }); + + return nprogress; +} diff --git a/.vitepress/theme/index.ts b/.vitepress/theme/index.ts index 46780d753..b0c8eac14 100644 --- a/.vitepress/theme/index.ts +++ b/.vitepress/theme/index.ts @@ -1,11 +1,14 @@ import { type Theme } from "vitepress"; import DefaultTheme from "vitepress/theme"; import Layout from "./Layout.vue"; +import { loadProgress } from "./composables/nprogress"; import "./style.css"; import "uno.css"; export default { extends: DefaultTheme, Layout, - enhanceApp({ app, router, siteData }) {}, + enhanceApp({ router }) { + loadProgress(router); + }, } satisfies Theme; diff --git a/.vitepress/theme/style.css b/.vitepress/theme/style.css index 37df70a9b..88dd30632 100644 --- a/.vitepress/theme/style.css +++ b/.vitepress/theme/style.css @@ -143,3 +143,85 @@ width: 0px; white-space: pre-wrap; } + +/* Make clicks pass-through */ +#nprogress { + pointer-events: none; +} + +#nprogress .bar { + background: var(--vp-c-brand-1); + position: fixed; + z-index: 1031; + top: 0; + left: 0; + width: 100%; + height: 2px; +} + +/* Fancy blur effect */ +#nprogress .peg { + display: block; + position: absolute; + right: 0px; + width: 100px; + height: 100%; + box-shadow: + 0 0 10px var(--vp-c-brand-1), + 0 0 5px var(--vp-c-brand-1); + opacity: 1; + + -webkit-transform: rotate(3deg) translate(0px, -4px); + -ms-transform: rotate(3deg) translate(0px, -4px); + transform: rotate(3deg) translate(0px, -4px); +} + +/* Remove these to get rid of the spinner */ +#nprogress .spinner { + display: block; + position: fixed; + z-index: 1031; + top: 15px; + right: 15px; +} + +#nprogress .spinner-icon { + width: 18px; + height: 18px; + box-sizing: border-box; + + border: solid 2px transparent; + border-top-color: var(--vp-c-brand); + border-left-color: var(--vp-c-brand); + border-radius: 50%; + + -webkit-animation: nprogress-spinner 400ms linear infinite; + animation: nprogress-spinner 400ms linear infinite; +} + +.nprogress-custom-parent { + overflow: hidden; + position: relative; +} + +.nprogress-custom-parent #nprogress .spinner, +.nprogress-custom-parent #nprogress .bar { + position: absolute; +} + +@-webkit-keyframes nprogress-spinner { + 0% { + -webkit-transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(360deg); + } +} +@keyframes nprogress-spinner { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} diff --git a/package.json b/package.json index ae54c9a81..4e60e82fa 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "itty-fetcher": "^0.9.4", "nitro-cors": "^0.7.0", "nitropack": "latest", + "nprogress": "^0.2.0", "pathe": "^1.1.1", "unocss": "^0.57.1", "vitepress": "1.0.0-rc.25", @@ -33,6 +34,7 @@ "@iconify-json/twemoji": "^1.1.12", "@taskylizard/eslint-config": "^1.0.3", "@types/node": "^20.8.9", + "@types/nprogress": "^0.2.3", "eslint": "^8.53.0", "prettier": "^3.0.3" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c46cbae83..390345fb9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -25,6 +25,9 @@ dependencies: nitropack: specifier: latest version: 2.7.2 + nprogress: + specifier: ^0.2.0 + version: 0.2.0 pathe: specifier: ^1.1.1 version: 1.1.1 @@ -33,7 +36,7 @@ dependencies: version: 0.57.1(postcss@8.4.31)(vite@4.5.0) vitepress: specifier: 1.0.0-rc.25 - version: 1.0.0-rc.25(patch_hash=3rmcuf2hcpfiqvpp6fmjf4ydmq)(@algolia/client-search@4.20.0)(@types/node@20.8.9)(postcss@8.4.31)(search-insights@2.9.0)(typescript@5.2.2) + version: 1.0.0-rc.25(patch_hash=3rmcuf2hcpfiqvpp6fmjf4ydmq)(@algolia/client-search@4.20.0)(@types/node@20.8.9)(nprogress@0.2.0)(postcss@8.4.31)(search-insights@2.9.0)(typescript@5.2.2) vue: specifier: ^3.3.7 version: 3.3.7(typescript@5.2.2) @@ -57,6 +60,9 @@ devDependencies: '@types/node': specifier: ^20.8.9 version: 20.8.9 + '@types/nprogress': + specifier: ^0.2.3 + version: 0.2.3 eslint: specifier: ^8.53.0 version: 8.53.0 @@ -1650,6 +1656,10 @@ packages: resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} dev: true + /@types/nprogress@0.2.3: + resolution: {integrity: sha512-k7kRA033QNtC+gLc4VPlfnue58CM1iQLgn1IMAU8VPHGOj7oIHPp9UlhedEnD/Gl8evoCjwkZjlBORtZ3JByUA==} + dev: true + /@types/resolve@1.20.2: resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} dev: false @@ -2202,7 +2212,7 @@ packages: - vue dev: false - /@vueuse/integrations@10.5.0(focus-trap@7.5.4)(vue@3.3.7): + /@vueuse/integrations@10.5.0(focus-trap@7.5.4)(nprogress@0.2.0)(vue@3.3.7): resolution: {integrity: sha512-fm5sXLCK0Ww3rRnzqnCQRmfjDURaI4xMsx+T+cec0ngQqHx/JgUtm8G0vRjwtonIeTBsH1Q8L3SucE+7K7upJQ==} peerDependencies: async-validator: '*' @@ -2246,6 +2256,7 @@ packages: '@vueuse/core': 10.5.0(vue@3.3.7) '@vueuse/shared': 10.5.0(vue@3.3.7) focus-trap: 7.5.4 + nprogress: 0.2.0 vue-demi: 0.14.6(vue@3.3.7) transitivePeerDependencies: - '@vue/composition-api' @@ -5438,6 +5449,10 @@ packages: set-blocking: 2.0.0 dev: false + /nprogress@0.2.0: + resolution: {integrity: sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==} + dev: false + /nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} dependencies: @@ -6940,7 +6955,7 @@ packages: fsevents: 2.3.3 dev: false - /vitepress@1.0.0-rc.25(patch_hash=3rmcuf2hcpfiqvpp6fmjf4ydmq)(@algolia/client-search@4.20.0)(@types/node@20.8.9)(postcss@8.4.31)(search-insights@2.9.0)(typescript@5.2.2): + /vitepress@1.0.0-rc.25(patch_hash=3rmcuf2hcpfiqvpp6fmjf4ydmq)(@algolia/client-search@4.20.0)(@types/node@20.8.9)(nprogress@0.2.0)(postcss@8.4.31)(search-insights@2.9.0)(typescript@5.2.2): resolution: {integrity: sha512-1dqWiHNThNrVZ08ixmfEDBEH+764KOgnev9oXga/x6cN++Vb9pnuu8p3K6DQP+KZrYcG+WiX7jxal0iSNpAWuQ==} hasBin: true peerDependencies: @@ -6958,7 +6973,7 @@ packages: '@vitejs/plugin-vue': 4.3.1(vite@4.5.0)(vue@3.3.7) '@vue/devtools-api': 6.5.1 '@vueuse/core': 10.5.0(vue@3.3.7) - '@vueuse/integrations': 10.5.0(focus-trap@7.5.4)(vue@3.3.7) + '@vueuse/integrations': 10.5.0(focus-trap@7.5.4)(nprogress@0.2.0)(vue@3.3.7) focus-trap: 7.5.4 mark.js: 8.11.1 minisearch: 6.2.0