Restore feed scroll position on Back; enlarge the detail back button
- The dex feed remembers scrollY on teardown (ui.feedScroll) and restores it on re-mount, so viewing a Pokémon and going back lands where you were. Reset to top when the filter, sort, direction or game changes. - Router no longer force-scrolls after mount; it scrolls to top on the loading placeholder and each view manages its own position (detail pages land at top, feed and search restore). - .phero__back is now a rounded pill with a real 40px tap target. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
0d95f9c93a
commit
b0e3655dbf
@ -45,6 +45,9 @@ export function initRouter(host) {
|
||||
|
||||
const pending = el('div', { class: 'view view--loading' }, 'Loading…');
|
||||
host.replaceChildren(pending);
|
||||
// Views manage their own scroll: detail pages jump to the top, the feed
|
||||
// and search restore where the user left off.
|
||||
window.scrollTo(0, 0);
|
||||
|
||||
try {
|
||||
const node = await route.view(match);
|
||||
@ -64,7 +67,6 @@ export function initRouter(host) {
|
||||
),
|
||||
);
|
||||
}
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
|
||||
rerenderCurrent = render;
|
||||
|
||||
@ -9,6 +9,7 @@ export const ui = createStore('pdx.ui', {
|
||||
searchQuery: '',
|
||||
searchScroll: 0,
|
||||
searchTab: 'pokemon',
|
||||
feedScroll: 0,
|
||||
sort: 'dex',
|
||||
sortDesc: false,
|
||||
filter: 'all',
|
||||
|
||||
@ -761,6 +761,21 @@
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.phero__back {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
flex: none;
|
||||
padding: 8px 14px 8px 11px;
|
||||
border-radius: 999px;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
font-size: 1rem;
|
||||
font-weight: 700;
|
||||
text-shadow: none;
|
||||
}
|
||||
.phero__back:hover {
|
||||
background: rgba(255, 255, 255, 0.32);
|
||||
}
|
||||
.phero__num {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
|
||||
@ -108,6 +108,7 @@ export async function DexGrid() {
|
||||
ui.set({ filter: f.key });
|
||||
chipEls.forEach((c, i) => c.btn.classList.toggle('is-active', FILTERS[i].key === f.key));
|
||||
paintGrid();
|
||||
resetScroll();
|
||||
},
|
||||
},
|
||||
el('span', {}, f.label),
|
||||
@ -127,6 +128,7 @@ export async function DexGrid() {
|
||||
ui.set({ sort: sortKey, sortDesc });
|
||||
syncDirBtn();
|
||||
paintGrid();
|
||||
resetScroll();
|
||||
},
|
||||
},
|
||||
...SORTS.map((s) => el('option', { value: s.key, selected: s.key === sortKey }, s.label)),
|
||||
@ -140,6 +142,7 @@ export async function DexGrid() {
|
||||
ui.set({ sortDesc });
|
||||
syncDirBtn();
|
||||
paintGrid();
|
||||
resetScroll();
|
||||
},
|
||||
});
|
||||
function syncDirBtn() {
|
||||
@ -148,6 +151,12 @@ export async function DexGrid() {
|
||||
}
|
||||
syncDirBtn();
|
||||
|
||||
// Changing the list order/contents makes the old scroll offset meaningless.
|
||||
function resetScroll() {
|
||||
ui.set({ feedScroll: 0 });
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
|
||||
view.append(
|
||||
el(
|
||||
'header',
|
||||
@ -262,15 +271,25 @@ export async function DexGrid() {
|
||||
paintGrid();
|
||||
}
|
||||
|
||||
let mountedVG = settings.get().versionGroup;
|
||||
rebuild();
|
||||
// Return to where the user last scrolled (e.g. after viewing a Pokémon).
|
||||
requestAnimationFrame(() => window.scrollTo(0, ui.get().feedScroll || 0));
|
||||
|
||||
const offSettings = settings.subscribe(rebuild);
|
||||
const offSettings = settings.subscribe((s) => {
|
||||
if (s.versionGroup !== mountedVG) {
|
||||
mountedVG = s.versionGroup;
|
||||
ui.set({ feedScroll: 0 });
|
||||
}
|
||||
rebuild();
|
||||
});
|
||||
const offSelection = selection.subscribe(() => {
|
||||
refreshMeta();
|
||||
if (filterKey !== 'all' && filterKey !== 'legendary') paintGrid();
|
||||
else if (sortKey === 'caught') paintGrid();
|
||||
});
|
||||
onTeardown(view, () => {
|
||||
ui.set({ feedScroll: window.scrollY });
|
||||
offSettings();
|
||||
offSelection();
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user