Merge pull request #20 from josedario87/route-transitions
Route transitions
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { watchEffect } from 'vue'
|
import { watchEffect, computed } from 'vue' // Added computed
|
||||||
import TopBar from '@/components/ui/TopBar.vue'
|
import TopBar from '@/components/ui/TopBar.vue'
|
||||||
import NavBar from '@/components/ui/NavBar.vue'
|
import NavBar from '@/components/ui/NavBar.vue'
|
||||||
import { useUi } from '@/stores/useUi'
|
import { useUi } from '@/stores/useUi'
|
||||||
@@ -46,6 +46,15 @@ watchEffect(() => {
|
|||||||
root.classList.add('animations-disabled')
|
root.classList.add('animations-disabled')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const transitionDurationStyle = computed(() => {
|
||||||
|
// Assuming base duration of 0.3s for normal speed (transitionSpeed = 1)
|
||||||
|
const baseDuration = 0.3
|
||||||
|
const effectiveDuration = baseDuration * ui.transitionSpeed
|
||||||
|
return {
|
||||||
|
'--current-transition-duration': `${effectiveDuration}s`
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -59,13 +68,17 @@ watchEffect(() => {
|
|||||||
// The global style.css will handle base background and text color via body styling
|
// The global style.css will handle base background and text color via body styling
|
||||||
// but we can keep specific overrides here if needed or theme classes.
|
// but we can keep specific overrides here if needed or theme classes.
|
||||||
// ui.theme === 'dark' ? 'bg-gray-800 text-gray-100' : 'bg-gray-100 text-gray-900'
|
// ui.theme === 'dark' ? 'bg-gray-800 text-gray-100' : 'bg-gray-100 text-gray-900'
|
||||||
]">
|
]" :style="transitionDurationStyle">
|
||||||
<!-- NavBar fija -->
|
<!-- NavBar fija -->
|
||||||
<NavBar />
|
<NavBar />
|
||||||
|
|
||||||
<!-- contenido principal -->
|
<!-- contenido principal -->
|
||||||
<main class="min-h-[calc(100vh-56px)] flex flex-col overflow-hidden">
|
<main class="min-h-[calc(100vh-56px)] flex flex-col overflow-hidden">
|
||||||
<RouterView class="flex-1 overflow-auto" />
|
<router-view v-slot="{ Component }">
|
||||||
|
<transition name="slide-fade" mode="out-in">
|
||||||
|
<component :is="Component" class="flex-1 overflow-auto" />
|
||||||
|
</transition>
|
||||||
|
</router-view>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -73,4 +86,26 @@ watchEffect(() => {
|
|||||||
<style scoped>
|
<style scoped>
|
||||||
/* Scoped styles remain, global styles are in style.css */
|
/* Scoped styles remain, global styles are in style.css */
|
||||||
/* We can add specific App.vue styling here if needed, that doesn't rely on theme variables directly */
|
/* We can add specific App.vue styling here if needed, that doesn't rely on theme variables directly */
|
||||||
|
|
||||||
|
.slide-fade-enter-active,
|
||||||
|
.slide-fade-leave-active {
|
||||||
|
transition: all var(--current-transition-duration) ease-out; /* Use the CSS variable */
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-fade-enter-from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(-20px); /* Slide in from the left */
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-fade-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(20px); /* Slide out to the right */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure content is fully opaque and in place when active/not transitioning */
|
||||||
|
.slide-fade-enter-to,
|
||||||
|
.slide-fade-leave-from {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ const appearanceSettingKeys = [
|
|||||||
'defaultViewPlanillas',
|
'defaultViewPlanillas',
|
||||||
'defaultViewAsistencias',
|
'defaultViewAsistencias',
|
||||||
'defaultViewConfiguracion',
|
'defaultViewConfiguracion',
|
||||||
|
'transitionSpeed',
|
||||||
]
|
]
|
||||||
|
|
||||||
const loadSettingsFromLocalStorage = () => {
|
const loadSettingsFromLocalStorage = () => {
|
||||||
@@ -104,6 +105,7 @@ export const useUi = defineStore('ui', {
|
|||||||
'defaultViewPlanillas': 'table',
|
'defaultViewPlanillas': 'table',
|
||||||
'defaultViewAsistencias': 'table',
|
'defaultViewAsistencias': 'table',
|
||||||
'defaultViewConfiguracion': 'table',
|
'defaultViewConfiguracion': 'table',
|
||||||
|
transitionSpeed: 1, // Default to normal speed
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadedSettings = loadSettingsFromLocalStorage()
|
const loadedSettings = loadSettingsFromLocalStorage()
|
||||||
@@ -237,7 +239,13 @@ export const useUi = defineStore('ui', {
|
|||||||
setDefaultViewConfiguracion(view) {
|
setDefaultViewConfiguracion(view) {
|
||||||
this.defaultViewConfiguracion = view
|
this.defaultViewConfiguracion = view
|
||||||
_saveAppearanceState(this)
|
_saveAppearanceState(this)
|
||||||
}
|
},
|
||||||
|
|
||||||
|
// Action for transition speed
|
||||||
|
setTransitionSpeed(newSpeed) {
|
||||||
|
this.transitionSpeed = Number(newSpeed) // Ensure it's a number
|
||||||
|
_saveAppearanceState(this)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,26 @@
|
|||||||
<input type="checkbox" id="desktopNavbarPersistent" v-model="ui.desktopNavbarPersistent" @change="ui.setDesktopNavbarPersistent($event.target.checked)"
|
<input type="checkbox" id="desktopNavbarPersistent" v-model="ui.desktopNavbarPersistent" @change="ui.setDesktopNavbarPersistent($event.target.checked)"
|
||||||
class="custom-checkbox relative w-10 h-5 appearance-none bg-gray-300 dark:bg-gray-600 rounded-full cursor-pointer transition-colors duration-300 ease-in-out checked:bg-[var(--primary-color)] focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-[var(--primary-color)] focus:ring-offset-[var(--background-color)]">
|
class="custom-checkbox relative w-10 h-5 appearance-none bg-gray-300 dark:bg-gray-600 rounded-full cursor-pointer transition-colors duration-300 ease-in-out checked:bg-[var(--primary-color)] focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-[var(--primary-color)] focus:ring-offset-[var(--background-color)]">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Animation Speed Setting -->
|
||||||
|
<div class="setting-item mt-6 md:col-span-2"> <!-- md:col-span-2 to make it take full width on medium screens if the grid has 2 columns -->
|
||||||
|
<label class="block text-sm font-medium mb-1 text-[var(--text-color)]">Animation Speed</label>
|
||||||
|
<p class="text-xs text-gray-500 dark:text-gray-400 mb-2">
|
||||||
|
Adjust the speed of screen transitions (applied if animations are enabled).
|
||||||
|
</p>
|
||||||
|
<div class="flex flex-col space-y-1 sm:flex-row sm:space-y-0 sm:space-x-4">
|
||||||
|
<label v-for="option in speedOptions" :key="option.value"
|
||||||
|
class="flex items-center p-2 rounded-md hover:bg-gray-200/50 dark:hover:bg-gray-700/50 cursor-pointer transition-colors duration-150 ease-in-out border border-gray-300 dark:border-gray-600 hover:border-[var(--primary-color)]">
|
||||||
|
<input type="radio"
|
||||||
|
name="transitionSpeed"
|
||||||
|
:value="option.value"
|
||||||
|
:checked="ui.transitionSpeed === option.value"
|
||||||
|
@change="ui.setTransitionSpeed(option.value)"
|
||||||
|
class="form-radio h-4 w-4 text-[var(--primary-color)] focus:ring-1 focus:ring-[var(--primary-color)] border-gray-300 dark:border-gray-500 bg-white dark:bg-gray-800 focus:ring-offset-white dark:focus:ring-offset-gray-900">
|
||||||
|
<span class="ml-2 text-sm text-[var(--text-color)]">{{ option.label }} <span class="text-xs text-gray-500 dark:text-gray-400">({{ option.value }}x)</span></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@@ -211,6 +231,12 @@ onMounted(() => {
|
|||||||
isMounted.value = true
|
isMounted.value = true
|
||||||
}, 50)
|
}, 50)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const speedOptions = [
|
||||||
|
{ label: 'Slow', value: 2 },
|
||||||
|
{ label: 'Normal', value: 1 },
|
||||||
|
{ label: 'Fast', value: 0.5 },
|
||||||
|
]
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
Reference in New Issue
Block a user