Refine: Make persistent navbar viewport-aware
This commit enhances the behavior of the persistent desktop navbar. Previously, if `desktopNavbarPersistent` was true, the main content would always shift to accommodate the sidebar on medium screens and up. Now, the content shifting is also conditional on available viewport width: - The main content wrapper in `App.vue` now tracks `window.innerWidth`. - A `SHIFT_THRESHOLD` is defined (currently 880px), calculated from NAVBAR_WIDTH (240px) + MIN_CONTENT_WIDTH (640px). - If `ui.sidebarOpen` and `ui.desktopNavbarPersistent` are both true, the `md:pl-60` class (to shift content) is only applied if `viewportWidth.value >= SHIFT_THRESHOLD`. - If the viewport width is below this threshold (but still potentially above the 'md' breakpoint), the persistent sidebar will overlay the content, similar to a non-persistent or mobile sidebar, preventing the main content area from becoming too cramped. This provides a more refined and responsive user experience for you if you enable the persistent navbar feature on varying screen sizes.
This commit is contained in:
@@ -1,10 +1,32 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { watchEffect, computed } from 'vue' // Added computed
|
import { watchEffect, computed, ref, onMounted, onUnmounted } from 'vue' // ensure all are imported
|
||||||
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'
|
||||||
|
|
||||||
const ui = useUi()
|
const ui = useUi()
|
||||||
|
const viewportWidth = ref(0) // New reactive variable
|
||||||
|
|
||||||
|
const updateViewportWidth = () => { // New function
|
||||||
|
viewportWidth.value = window.innerWidth
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => { // New lifecycle hook
|
||||||
|
updateViewportWidth()
|
||||||
|
window.addEventListener('resize', updateViewportWidth)
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => { // New lifecycle hook
|
||||||
|
window.removeEventListener('resize', updateViewportWidth)
|
||||||
|
})
|
||||||
|
|
||||||
|
const NAVBAR_WIDTH = 240 // Defined constant
|
||||||
|
const MIN_CONTENT_WIDTH = 640 // Defined constant
|
||||||
|
const SHIFT_THRESHOLD = NAVBAR_WIDTH + MIN_CONTENT_WIDTH // Calculated threshold
|
||||||
|
|
||||||
|
const shouldShiftContent = computed(() => { // New computed property
|
||||||
|
return ui.sidebarOpen && ui.desktopNavbarPersistent && viewportWidth.value >= SHIFT_THRESHOLD
|
||||||
|
})
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
const root = document.documentElement
|
const root = document.documentElement
|
||||||
@@ -63,8 +85,8 @@ const transitionDurationStyle = computed(() => {
|
|||||||
|
|
||||||
<!-- wrapper: deja espacio para TopBar (pt-14 = 56px) y, en desktop, para NavBar (pl-60) -->
|
<!-- wrapper: deja espacio para TopBar (pt-14 = 56px) y, en desktop, para NavBar (pl-60) -->
|
||||||
<div :class="[
|
<div :class="[
|
||||||
'pt-14 min-h-screen transition-[padding-left] duration-200',
|
'pt-14 min-h-screen transition-[padding-left] duration-200', // Keep existing transition
|
||||||
(ui.sidebarOpen && ui.desktopNavbarPersistent) ? 'md:pl-60' : '',
|
shouldShiftContent.value ? 'md:pl-60' : '', // Use the computed property
|
||||||
// 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'
|
||||||
|
|||||||
Reference in New Issue
Block a user