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>
88 lines
2.9 KiB
Vue
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>
|