From e979d679b20631e9dd17a331ad3bd63806de7503 Mon Sep 17 00:00:00 2001 From: Leo Vasanko Date: Tue, 5 May 2026 16:07:07 +0000 Subject: [PATCH] feat(frontend): add simultaneous slide transitions on directory navigation - Detect navigation direction (forward/backward) via router beforeEach guard - Store transition direction in Pinia for cross-component access - Wrap ExplorerView content in a CSS grid transition wrapper so old and new views overlap in the same grid cell during animation - Add slide-forward/slide-backward transition classes with translate3d for GPU-accelerated, simultaneous enter/leave without gaps - Keep fixed-position search loader outside the transition --- frontend/src/assets/main.css | 62 +++++++++++++++++++++++++++++ frontend/src/router/index.ts | 19 +++++++++ frontend/src/stores/main.ts | 1 + frontend/src/views/ExplorerView.vue | 44 +++++++++++++------- 4 files changed, 111 insertions(+), 15 deletions(-) diff --git a/frontend/src/assets/main.css b/frontend/src/assets/main.css index d527986..fbc1d1d 100644 --- a/frontend/src/assets/main.css +++ b/frontend/src/assets/main.css @@ -57,6 +57,66 @@ align-self: stretch; } } +/* Directory navigation slide transitions */ +.transition-wrapper { + display: grid; + grid-template-columns: 1fr; + grid-template-rows: 1fr; +} + +.explorer-content { + grid-area: 1 / 1; +} + +.slide-forward-enter-active, +.slide-backward-enter-active { + z-index: 2; +} + +.slide-forward-leave-active, +.slide-backward-leave-active { + z-index: 1; +} + +.slide-forward-enter-active, +.slide-forward-leave-active, +.slide-backward-enter-active, +.slide-backward-leave-active { + transition: transform 0.22s cubic-bezier(0.32, 0.72, 0, 1); +} + +.slide-forward-enter-from { + transform: translate3d(100%, 0, 0); +} + +.slide-forward-enter-to { + transform: translate3d(0, 0, 0); +} + +.slide-forward-leave-from { + transform: translate3d(0, 0, 0); +} + +.slide-forward-leave-to { + transform: translate3d(-100%, 0, 0); +} + +.slide-backward-enter-from { + transform: translate3d(-100%, 0, 0); +} + +.slide-backward-enter-to { + transform: translate3d(0, 0, 0); +} + +.slide-backward-leave-from { + transform: translate3d(0, 0, 0); +} + +.slide-backward-leave-to { + transform: translate3d(100%, 0, 0); +} + @media print { :root { --primary-color: black; @@ -206,6 +266,8 @@ main { min-height: 0; /* Allow flex child to shrink below content size */ padding-bottom: 3em; /* convenience space on the bottom */ overflow-y: scroll; + overflow-x: hidden; + position: relative; text-align: center; } diff --git a/frontend/src/router/index.ts b/frontend/src/router/index.ts index fdffbef..28d3c34 100644 --- a/frontend/src/router/index.ts +++ b/frontend/src/router/index.ts @@ -1,6 +1,12 @@ +import { useMainStore } from '@/stores/main' import ExplorerView from '@/views/ExplorerView.vue' import { createRouter, createWebHashHistory } from 'vue-router' +function getPathDepth(path: string): number { + const pathPart = decodeURIComponent(path).split('//')[0] ?? '' + return pathPart.split('/').filter(Boolean).length +} + const router = createRouter({ history: createWebHashHistory(import.meta.env.BASE_URL), routes: [ @@ -12,4 +18,17 @@ const router = createRouter({ ] }) +router.beforeEach((to, from) => { + const store = useMainStore() + const toDepth = getPathDepth(to.path) + const fromDepth = getPathDepth(from.path) + if (toDepth > fromDepth) { + store.transitionDirection = 'forward' + } else if (toDepth < fromDepth) { + store.transitionDirection = 'backward' + } else { + store.transitionDirection = 'none' + } +}) + export default router diff --git a/frontend/src/stores/main.ts b/frontend/src/stores/main.ts index c0ee168..91efd14 100644 --- a/frontend/src/stores/main.ts +++ b/frontend/src/stores/main.ts @@ -98,6 +98,7 @@ export const useMainStore = defineStore('main', { privileged: false as boolean, isLoggedIn: false as boolean }, + transitionDirection: 'none' as 'forward' | 'backward' | 'none', space: { disk: 0, free: 0, diff --git a/frontend/src/views/ExplorerView.vue b/frontend/src/views/ExplorerView.vue index c8e9dd7..f663b05 100644 --- a/frontend/src/views/ExplorerView.vue +++ b/frontend/src/views/ExplorerView.vue @@ -1,24 +1,32 @@