restore savedPosition + force smooth scroll on hash via HomePage watcher
Two fixes: - Bring back savedPosition handling in scrollBehavior so /shop ⇄ /shop/<slug> back-nav restores the previous scroll y. - Add a route.hash watcher in HomePage that calls scrollIntoView with smooth behaviour. Vue Router's scrollBehavior alone wasn't reliably firing for same-route hash navigations, so this catches them explicitly. Also handles direct /#bundles deep-links via immediate. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1
dist/assets/HomePage-DmySDKLA.js
vendored
1
dist/assets/HomePage-DmySDKLA.js
vendored
File diff suppressed because one or more lines are too long
1
dist/assets/HomePage-Dy33s4dG.js
vendored
Normal file
1
dist/assets/HomePage-Dy33s4dG.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
dist/index.html
vendored
2
dist/index.html
vendored
@@ -12,7 +12,7 @@
|
||||
href="https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,200;0,9..144,400;0,9..144,600;0,9..144,700;1,9..144,200;1,9..144,400;1,9..144,600&family=DM+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script type="module" crossorigin src="/assets/index-B0R6Jy4g.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-B3cVgQOI.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/assets/_plugin-vue_export-helper-BOai-rQB.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/preload-helper-DzyYoeor.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/runtime-core.esm-bundler-DTXUv7Wx.js">
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
@import '../design-system/motion.css';
|
||||
|
||||
html {
|
||||
/* No `scroll-behavior: smooth` — instant jumps requested for accessibility
|
||||
(smooth animation between scroll positions can trigger motion sickness). */
|
||||
/* No global `scroll-behavior: smooth` — only same-route hash
|
||||
anchors (handled in `router.scrollBehavior`) smooth-scroll.
|
||||
Cross-route navigations and back/forward jumps are instant. */
|
||||
font-size: 17px;
|
||||
/* Runtime-measured navbar height. Default matches the standard
|
||||
Navbar variant at lg (py-5 + logo + border) so the home-page
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup>
|
||||
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import Navbar from '@/design-system/components/Navbar.vue'
|
||||
import Hero from '@/design-system/components/Hero.vue'
|
||||
import Bundles from '@/design-system/components/Bundles.vue'
|
||||
@@ -21,8 +21,25 @@ import { useI18n } from '@/i18n/index.js'
|
||||
const { t } = useI18n()
|
||||
const cart = useCartStore()
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const cartOpen = ref(false)
|
||||
|
||||
// Smooth-scroll to the target section when the URL hash changes.
|
||||
// Belt-and-suspenders for Vue Router's scrollBehavior — same-route
|
||||
// hash navigations sometimes don't trigger it (or run before the
|
||||
// section is mounted), so we re-fire scrollIntoView here. `immediate`
|
||||
// covers the case where the user lands on /#bundles directly.
|
||||
watch(
|
||||
() => route.hash,
|
||||
async (hash) => {
|
||||
if (!hash) return
|
||||
await nextTick()
|
||||
const el = document.querySelector(hash)
|
||||
if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
|
||||
// Cart drawer's "checkout" event closes the drawer and navigates to
|
||||
// the checkout page. Kept centralised here (and on ShopPage) so the
|
||||
// drawer stays purely presentational — it emits intent, the page
|
||||
|
||||
@@ -158,14 +158,16 @@ const routes = [
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes,
|
||||
// Anchor-aware scroll: navigating to `/#bundles` or `/shop#care`
|
||||
// scrolls to that section rather than resetting to top. Each
|
||||
// section's `scroll-mt-[calc(var(--nav-h)+1rem)]` offset handles
|
||||
// the sticky-nav clearance. Back/forward navigation always returns
|
||||
// to the top of the destination — `savedPosition` is intentionally
|
||||
// not honoured so users land at a predictable position rather than
|
||||
// wherever they last scrolled to.
|
||||
scrollBehavior(to) {
|
||||
// Scroll rules:
|
||||
// • Browser back/forward → restore the previous scroll y so
|
||||
// /shop ⇄ /shop/<slug> round-trips land where the user left off.
|
||||
// • Hash nav (e.g. /#bundles) → smooth-scroll to the target.
|
||||
// Belt-and-suspenders: HomePage also runs a route.hash watcher
|
||||
// so that hash-only changes within the same route are caught
|
||||
// even when Vue Router's scrollBehavior is short-circuited.
|
||||
// • Everything else (forward route nav) → top of the page.
|
||||
scrollBehavior(to, _from, savedPosition) {
|
||||
if (savedPosition) return savedPosition
|
||||
if (to.hash) return { el: to.hash, behavior: 'smooth' }
|
||||
return { top: 0 }
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user