feat(ui): mobile bottom nav com 4 fixos + menu MAIS para rotas secundárias
- HOME, TX, IMPORT, PERS. fixos na barra inferior - Botão '···' abre overlay com CONTAS, REC., CAT., CFG - Overlay fecha ao navegar ou ao tocar fora - Transição de fade no overlay
This commit is contained in:
@@ -1,10 +1,42 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const showMore = ref(false)
|
||||
const router = useRouter()
|
||||
|
||||
router.afterEach(() => { showMore.value = false })
|
||||
|
||||
const moreItems = [
|
||||
{ to: '/contas', label: 'CONTAS' },
|
||||
{ to: '/recorrencias', label: 'REC.' },
|
||||
{ to: '/categorias', label: 'CAT.' },
|
||||
{ to: '/configuracoes', label: 'CFG' },
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Transition name="fc-more">
|
||||
<div v-if="showMore" class="fc-more-overlay" @click.self="showMore = false">
|
||||
<nav class="fc-more-menu">
|
||||
<RouterLink
|
||||
v-for="item in moreItems"
|
||||
:key="item.to"
|
||||
:to="item.to"
|
||||
class="fc-more-menu__item fc-pixel"
|
||||
>{{ item.label }}</RouterLink>
|
||||
</nav>
|
||||
</div>
|
||||
</Transition>
|
||||
|
||||
<nav class="fc-bottom-nav">
|
||||
<RouterLink to="/" class="fc-bottom-nav__item fc-pixel">HOME</RouterLink>
|
||||
<RouterLink to="/transacoes" class="fc-bottom-nav__item fc-pixel">TX</RouterLink>
|
||||
<RouterLink to="/importar" class="fc-bottom-nav__item fc-pixel add">+</RouterLink>
|
||||
<RouterLink to="/importar" class="fc-bottom-nav__item fc-pixel">IMPORT</RouterLink>
|
||||
<RouterLink to="/personagem" class="fc-bottom-nav__item fc-pixel">PERS.</RouterLink>
|
||||
<RouterLink to="/contas" class="fc-bottom-nav__item fc-pixel">¤</RouterLink>
|
||||
<button class="fc-bottom-nav__item fc-bottom-nav__more fc-pixel" @click="showMore = !showMore">
|
||||
{{ showMore ? '✕' : '···' }}
|
||||
</button>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
@@ -25,11 +57,45 @@
|
||||
transition: color .12s;
|
||||
}
|
||||
.fc-bottom-nav__item.router-link-active { color: var(--fc-accent-2); }
|
||||
.fc-bottom-nav__item.add {
|
||||
font-size: 18px; color: var(--fc-accent);
|
||||
text-shadow: 0 0 8px var(--fc-accent);
|
||||
.fc-bottom-nav__more {
|
||||
background: none; border: none; cursor: pointer;
|
||||
font-size: 14px; letter-spacing: 1px;
|
||||
}
|
||||
.fc-bottom-nav__more.active { color: var(--fc-accent); }
|
||||
|
||||
/* overlay */
|
||||
.fc-more-overlay {
|
||||
display: none;
|
||||
position: fixed; inset: 0; bottom: 56px;
|
||||
z-index: 99;
|
||||
background: rgba(0,0,0,.5);
|
||||
align-items: flex-end;
|
||||
}
|
||||
.fc-more-menu {
|
||||
width: 100%;
|
||||
background: var(--fc-bg-panel);
|
||||
border-top: 2px solid var(--fc-panel-edge);
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
}
|
||||
.fc-more-menu__item {
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
padding: 16px 4px;
|
||||
font-size: 7px; color: var(--fc-text-dim);
|
||||
text-decoration: none;
|
||||
border-right: 1px solid var(--fc-panel-edge);
|
||||
transition: color .12s, background .12s;
|
||||
}
|
||||
.fc-more-menu__item:last-child { border-right: none; }
|
||||
.fc-more-menu__item.router-link-active,
|
||||
.fc-more-menu__item:active { color: var(--fc-accent-2); background: rgba(0,240,255,.05); }
|
||||
|
||||
/* transitions */
|
||||
.fc-more-enter-active, .fc-more-leave-active { transition: opacity .15s; }
|
||||
.fc-more-enter-from, .fc-more-leave-to { opacity: 0; }
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.fc-bottom-nav { display: flex; }
|
||||
.fc-more-overlay { display: flex; }
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user