+ Menu Hover no Layout Rail, Twilio, Sms, Email, Templates, LNovo Layout Configurações

This commit is contained in:
Leonardo
2026-03-25 08:39:45 -03:00
parent 53a4980396
commit 3f1786c9bf
59 changed files with 2553 additions and 1106 deletions
+45 -1
View File
@@ -28,13 +28,22 @@ function _loadVariant() {
return 'rail';
}
function _loadRailOpenMode() {
try {
const v = localStorage.getItem('rail_open_mode');
if (v === 'click' || v === 'hover') return v;
} catch {}
return 'hover';
}
const layoutConfig = reactive({
preset: 'Aura',
primary: 'emerald',
surface: null,
darkTheme: false,
menuMode: 'static',
variant: _loadVariant() // 'classic' | 'rail'
variant: _loadVariant(), // 'classic' | 'rail'
railOpenMode: _loadRailOpenMode() // 'click' | 'hover'
});
const layoutState = reactive({
@@ -84,6 +93,9 @@ if (typeof window !== 'undefined') {
window.addEventListener('resize', _onResize, { passive: true });
}
// ── Timer compartilhado para hover do rail ───────────────────
let _railHoverCloseTimer = null;
export function useLayout() {
// ✅ garante coerência sempre que alguém usar useLayout()
syncDarkFromDomOnce();
@@ -188,9 +200,37 @@ export function useLayout() {
if (fromUser) layoutState._variantDirty = true;
};
const setRailOpenMode = (mode) => {
if (mode !== 'click' && mode !== 'hover') return;
layoutConfig.railOpenMode = mode;
try {
localStorage.setItem('rail_open_mode', mode);
} catch {}
};
const clearRailHoverClose = () => {
if (_railHoverCloseTimer !== null) {
clearTimeout(_railHoverCloseTimer);
_railHoverCloseTimer = null;
}
};
const scheduleRailHoverClose = (delay = 200) => {
clearRailHoverClose();
_railHoverCloseTimer = setTimeout(() => {
layoutState.railPanelOpen = false;
_railHoverCloseTimer = null;
}, delay);
};
const isDarkTheme = computed(() => layoutConfig.darkTheme);
const hasOpenOverlay = computed(() => layoutState.overlayMenuActive);
// true apenas quando o painel está aberto E empurra o layout (não no modo hover)
const railPanelPushesLayout = computed(() =>
layoutState.railPanelOpen && layoutConfig.railOpenMode !== 'hover'
);
// ── Em mobile (≤ xl / 1280px) sempre usa o layout clássico, ───────
// independente de layoutConfig.variant
const isMobile = computed(() => _isMobileRef.value);
@@ -210,6 +250,10 @@ export function useLayout() {
closeMenuOnNavigate,
changeMenuMode,
setVariant,
setRailOpenMode,
railPanelPushesLayout,
clearRailHoverClose,
scheduleRailHoverClose,
isDesktop,
isRailMobile,
isMobile,