This commit is contained in:
Leonardo
2026-03-06 06:37:13 -03:00
parent d58dc21297
commit f733db8436
146 changed files with 43436 additions and 12779 deletions
+80 -13
View File
@@ -1,38 +1,76 @@
import { computed, reactive } from 'vue'
// ── resolve variant salvo no localStorage ───────────────────
function _loadVariant () {
try {
const v = localStorage.getItem('layout_variant')
if (v === 'rail' || v === 'classic') return v
} catch {}
return 'classic'
}
const layoutConfig = reactive({
preset: 'Aura',
primary: 'emerald',
surface: null,
darkTheme: false,
menuMode: 'static'
menuMode: 'static',
variant: _loadVariant() // 'classic' | 'rail'
})
const layoutState = reactive({
staticMenuInactive: false,
overlayMenuActive: false,
mobileMenuActive: false, // ✅ ADICIONA (estava faltando)
mobileMenuActive: false,
profileSidebarVisible: false,
configSidebarVisible: false,
sidebarExpanded: false,
menuHoverActive: false,
anchored: false,
activeMenuItem: null,
activePath: null
activePath: null,
// ── Layout 2 (rail) ─────────────────────────────────────
railSectionKey: null, // qual seção está ativa no rail
railPanelOpen: false // painel lateral expandido
})
/**
* ✅ Fonte da verdade do dark:
* - DOM class: .app-dark (usado pelo PrimeUI/PrimeVue)
* - layoutConfig.darkTheme: refletir o DOM (pra UI reagir)
*
* Motivo: você aplica tema cedo (main.js / user_settings) e depois
* usa o composable em páginas/Topbar/Configurator. Se não sincronizar,
* isDarkTheme pode ficar “mentindo”.
*/
let _syncedDarkFromDomOnce = false
function syncDarkFromDomOnce () {
if (_syncedDarkFromDomOnce) return
_syncedDarkFromDomOnce = true
try {
layoutConfig.darkTheme = document.documentElement.classList.contains('app-dark')
} catch {}
}
export function useLayout () {
// ✅ garante coerência sempre que alguém usar useLayout()
syncDarkFromDomOnce()
const executeDarkModeToggle = () => {
layoutConfig.darkTheme = !layoutConfig.darkTheme
// ✅ garante consistência (não depende do estado anterior do DOM)
document.documentElement.classList.toggle('app-dark', layoutConfig.darkTheme)
}
const toggleDarkMode = () => {
if (!document.startViewTransition) {
executeDarkModeToggle()
return
}
document.startViewTransition(() => executeDarkModeToggle(event))
}
const executeDarkModeToggle = () => {
layoutConfig.darkTheme = !layoutConfig.darkTheme
document.documentElement.classList.toggle('app-dark')
// ✅ não usa "event" (undefined) e mantém transição suave quando suportado
document.startViewTransition(() => executeDarkModeToggle())
}
const isDesktop = () => window.innerWidth > 991
@@ -57,6 +95,8 @@ export function useLayout () {
const hideMobileMenu = () => {
layoutState.mobileMenuActive = false
layoutState.overlayMenuActive = false
layoutState.menuHoverActive = false
}
// ✅ use isso ao navegar: mantém menu aberto no desktop, fecha só no mobile
@@ -68,15 +108,41 @@ export function useLayout () {
}
}
const changeMenuMode = (event) => {
layoutConfig.menuMode = event.value
/**
* ✅ aceita:
* - changeMenuMode({ value: 'static' })
* - changeMenuMode('static')
*
* Motivo: você chama isso de lugares diferentes (Topbar, Configurator, Profile).
*/
const changeMenuMode = (eventOrValue) => {
const nextMode = typeof eventOrValue === 'string'
? eventOrValue
: eventOrValue?.value
// ✅ não deixa setar undefined / vazio
if (!nextMode) return
layoutConfig.menuMode = nextMode
// ✅ reset consistente (evita drift quando alterna overlay/static)
layoutState.staticMenuInactive = false
layoutState.overlayMenuActive = false
layoutState.mobileMenuActive = false
layoutState.sidebarExpanded = false
layoutState.menuHoverActive = false
layoutState.anchored = false
}
const setVariant = (v) => {
if (v !== 'classic' && v !== 'rail') return
layoutConfig.variant = v
try { localStorage.setItem('layout_variant', v) } catch {}
// reset rail state ao trocar
layoutState.railSectionKey = null
layoutState.railPanelOpen = false
}
const isDarkTheme = computed(() => layoutConfig.darkTheme)
const hasOpenOverlay = computed(() => layoutState.overlayMenuActive)
@@ -88,9 +154,10 @@ export function useLayout () {
toggleConfigSidebar,
toggleMenu,
hideMobileMenu,
closeMenuOnNavigate, // ✅ exporta
closeMenuOnNavigate,
changeMenuMode,
setVariant,
isDesktop,
hasOpenOverlay
}
}
}