Files
tehran_taj/apps/user-app/src/layout/MasterLayout.vue
T
s.esmaeiliandClaude Sonnet 5 c05352d6fd refactor(ui): replace modal dialogs with toast/sheet components
Remove DialogVant/NotifyVant and add Toast and Sheet components with
useToast, useReveal, and usePageTransition composables. Rework
Navigation, RegisterView, and styles across both apps; rebuild dist assets.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-04 13:57:25 +03:30

88 lines
2.9 KiB
Vue

<!--
Ported from legacy henza_pwa/src/layout/master.vue.
NOTE (existing issue, ported as-is — not fixed here): this layout renders
its own <router-view/> rather than a <slot/>, so the keep-alive/suspense
wrapper App.vue builds around its own <router-view> is never actually used
by this layout — the route component here is resolved fresh, independently.
Preserved exactly; flagged separately.
-->
<template>
<section ref="content">
<router-view v-slot="{ Component, route }">
<transition
name="page"
mode="out-in"
@before-leave="pageLeaveStarted"
@after-leave="pageLeaveEnded"
@leave-cancelled="pageLeaveEnded"
>
<component :is="Component" :key="route.name" />
</transition>
</router-view>
<Navigation />
<div class="bg-primary top-[-2rem] fixed h-[2rem] w-full z-10" />
</section>
</template>
<script setup lang="ts">
import { onBeforeMount, ref } from 'vue'
import { useResizeObserver } from '@vueuse/core'
import Navigation from '../components/ui/Navigation.vue'
import { useWindowDataStore } from '../stores/windowDataStore'
import { pageLeaveStarted, pageLeaveEnded } from '../composables/usePageTransition'
const windowData = useWindowDataStore()
const content = ref<HTMLElement | null>(null)
// Route changes here are tab switches, not a hierarchy, so there is no "back"
// or "forward" direction to honour. The outgoing page fades out quickly and
// the new one fades in; the sense of the page settling into place comes from
// each screen's own section reveal (composables/useReveal.ts).
onBeforeMount(() => {
windowData.setWidth(window.innerWidth)
})
useResizeObserver(content, (entries) => {
const entry = entries[0]
const { width } = entry.contentRect
if (windowData.width !== width) {
windowData.setWidth(width)
}
})
</script>
<!--
Not scoped: these classes land on the routed page component, which carries
its own scope id, not this layout's.
Opacity only, deliberately. A transform (or filter) on the page root makes it
the containing block for every position: fixed element inside the page — the
top bars, PageBar, the cart's checkout bar — so for the length of the
transition they would ride along with the page, then snap back to the screen
edge when it ends. Opacity has no such effect, so nothing jumps.
-->
<style lang="less">
// Leave is deliberately shorter than enter. With mode="out-in" the two run
// back to back, so a slow exit is dead time the user feels as lag; a quick
// fade out and an unhurried fade in reads as responsive but smooth.
.page-leave-active {
transition: opacity 0.16s cubic-bezier(0.4, 0, 1, 1);
}
.page-enter-active {
transition: opacity 0.42s cubic-bezier(0.32, 0.72, 0, 1);
}
.page-enter-from,
.page-leave-to {
opacity: 0;
}
@media (prefers-reduced-motion: reduce) {
.page-enter-active,
.page-leave-active {
transition: opacity 0.12s linear;
}
}
</style>