- Agregar z-index: 100 al app-header - Aumentar z-index del dropdown a 10001 (mayor que AuthIndicator) - Asegurar que el dropdown se dibuje por encima de todos los elementos
198 lines
3.8 KiB
Vue
198 lines
3.8 KiB
Vue
<template>
|
|
<div class="settings-menu" ref="menuContainer">
|
|
<IconButton
|
|
:icon="MoreVertical"
|
|
title="Configuración"
|
|
size="small"
|
|
@click="toggleMenu"
|
|
class="menu-trigger"
|
|
:active="isOpen"
|
|
/>
|
|
|
|
<transition name="dropdown">
|
|
<div v-if="isOpen" class="dropdown-menu glass">
|
|
<div class="menu-section">
|
|
<div class="menu-label">Autenticación</div>
|
|
<AuthIndicator class="menu-item-auth" />
|
|
</div>
|
|
|
|
<div class="menu-divider"></div>
|
|
|
|
<div class="menu-section">
|
|
<div class="menu-label">Tema</div>
|
|
<div class="menu-item">
|
|
<ThemeToggle />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</transition>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, onMounted, onUnmounted } from 'vue'
|
|
import { MoreVertical } from 'lucide-vue-next'
|
|
import IconButton from './IconButton.client.vue'
|
|
import AuthIndicator from './AuthIndicator.client.vue'
|
|
import ThemeToggle from './ThemeToggle.client.vue'
|
|
|
|
const isOpen = ref(false)
|
|
const menuContainer = ref(null)
|
|
|
|
const toggleMenu = () => {
|
|
isOpen.value = !isOpen.value
|
|
}
|
|
|
|
const closeMenu = () => {
|
|
isOpen.value = false
|
|
}
|
|
|
|
// Cerrar el menú al hacer clic fuera
|
|
const handleClickOutside = (event) => {
|
|
if (menuContainer.value && !menuContainer.value.contains(event.target)) {
|
|
closeMenu()
|
|
}
|
|
}
|
|
|
|
// Cerrar el menú al presionar Escape
|
|
const handleEscape = (event) => {
|
|
if (event.key === 'Escape' && isOpen.value) {
|
|
closeMenu()
|
|
}
|
|
}
|
|
|
|
onMounted(() => {
|
|
document.addEventListener('click', handleClickOutside)
|
|
document.addEventListener('keydown', handleEscape)
|
|
})
|
|
|
|
onUnmounted(() => {
|
|
document.removeEventListener('click', handleClickOutside)
|
|
document.removeEventListener('keydown', handleEscape)
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
.settings-menu {
|
|
position: relative;
|
|
display: inline-block;
|
|
}
|
|
|
|
.menu-trigger:hover {
|
|
animation: pulse-menu 0.6s ease-in-out;
|
|
}
|
|
|
|
.dropdown-menu {
|
|
position: absolute;
|
|
top: calc(100% + 8px);
|
|
right: 0;
|
|
min-width: 220px;
|
|
background: rgba(255, 255, 255, 0.12);
|
|
backdrop-filter: blur(20px);
|
|
-webkit-backdrop-filter: blur(20px);
|
|
border: 1px solid rgba(255, 255, 255, 0.15);
|
|
border-radius: 16px;
|
|
padding: 12px;
|
|
box-shadow: var(--shadow-glass), 0 8px 32px rgba(0, 0, 0, 0.2);
|
|
z-index: 10001;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
}
|
|
|
|
.menu-section {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
}
|
|
|
|
.menu-label {
|
|
font-size: 0.75rem;
|
|
font-weight: 600;
|
|
color: var(--text-secondary);
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.5px;
|
|
padding: 0 8px;
|
|
opacity: 0.8;
|
|
}
|
|
|
|
.menu-item {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 8px;
|
|
border-radius: 12px;
|
|
transition: all 0.2s ease;
|
|
}
|
|
|
|
.menu-item:hover {
|
|
background: rgba(255, 255, 255, 0.08);
|
|
}
|
|
|
|
.menu-item-auth {
|
|
width: 100%;
|
|
}
|
|
|
|
/* Ajustar el AuthIndicator para que se vea bien en el menú */
|
|
.menu-item-auth :deep(.auth-indicator) {
|
|
width: 100%;
|
|
justify-content: flex-start;
|
|
}
|
|
|
|
.menu-divider {
|
|
height: 1px;
|
|
background: linear-gradient(
|
|
90deg,
|
|
transparent,
|
|
rgba(255, 255, 255, 0.2),
|
|
transparent
|
|
);
|
|
margin: 4px 0;
|
|
}
|
|
|
|
/* Animations */
|
|
.dropdown-enter-active,
|
|
.dropdown-leave-active {
|
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
transform-origin: top right;
|
|
}
|
|
|
|
.dropdown-enter-from {
|
|
opacity: 0;
|
|
transform: scale(0.95) translateY(-10px);
|
|
}
|
|
|
|
.dropdown-leave-to {
|
|
opacity: 0;
|
|
transform: scale(0.95) translateY(-10px);
|
|
}
|
|
|
|
@keyframes pulse-menu {
|
|
0%, 100% { transform: scale(1); }
|
|
50% { transform: scale(1.1); }
|
|
}
|
|
|
|
/* Responsive design */
|
|
@media (max-width: 768px) {
|
|
.dropdown-menu {
|
|
min-width: 200px;
|
|
padding: 10px;
|
|
}
|
|
|
|
.menu-label {
|
|
font-size: 0.7rem;
|
|
}
|
|
|
|
.menu-item {
|
|
padding: 6px;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 480px) {
|
|
.dropdown-menu {
|
|
/* En móvil, centrar mejor el menú */
|
|
right: -10px;
|
|
}
|
|
}
|
|
</style>
|