fix(web): force scroll-to-top on tab switch (iOS Safari quirk)
Next.js App Router *should* reset scroll on route change, but iOS
Safari (and occasionally Chrome on Android) preserves the document
scroll position when navigating between routes that share a layout —
the user lands on the new tab halfway down the page and has to scroll
manually.
Adds a useEffect([]) in both AccountsTable and UsersTable that calls
window.scrollTo({top:0, left:0, behavior:'instant'}) on mount. Route
transitions remount the table component (different page module), so
the empty deps array fires exactly once per visit.
'instant' behavior avoids a smooth-scroll animation that would compete
with the loading-skeleton swap.
This commit is contained in:
parent
9b222eec56
commit
850fb71ddd
@ -75,6 +75,14 @@ export default function AccountsTable({
|
|||||||
const [createOpen, setCreateOpen] = useState(false);
|
const [createOpen, setCreateOpen] = useState(false);
|
||||||
const [toast, setToast] = useState<ToastMessage | null>(null);
|
const [toast, setToast] = useState<ToastMessage | null>(null);
|
||||||
|
|
||||||
|
// iOS Safari (and sometimes Chrome on Android) keeps the document
|
||||||
|
// scroll position across SPA route changes, so tab-switching from
|
||||||
|
// /users back to / leaves the user halfway down the page. Force
|
||||||
|
// scroll-to-top on mount; route transitions remount the table.
|
||||||
|
useEffect(() => {
|
||||||
|
window.scrollTo({ top: 0, left: 0, behavior: "instant" });
|
||||||
|
}, []);
|
||||||
|
|
||||||
// Accumulated rows from initial server-side fetch + every loadMore.
|
// Accumulated rows from initial server-side fetch + every loadMore.
|
||||||
const [rows, setRows] = useState<Acc[]>(initial);
|
const [rows, setRows] = useState<Acc[]>(initial);
|
||||||
const [hasMore, setHasMore] = useState<boolean>(initialHasMore);
|
const [hasMore, setHasMore] = useState<boolean>(initialHasMore);
|
||||||
|
|||||||
@ -77,6 +77,13 @@ export default function UsersTable({
|
|||||||
const [createOpen, setCreateOpen] = useState(false);
|
const [createOpen, setCreateOpen] = useState(false);
|
||||||
const [toast, setToast] = useState<ToastMessage | null>(null);
|
const [toast, setToast] = useState<ToastMessage | null>(null);
|
||||||
|
|
||||||
|
// Force scroll-to-top on mount — iOS Safari preserves document scroll
|
||||||
|
// across SPA route changes, so tab-switching leaves the new page
|
||||||
|
// halfway down. Route transitions remount the table, so [] deps fire.
|
||||||
|
useEffect(() => {
|
||||||
|
window.scrollTo({ top: 0, left: 0, behavior: "instant" });
|
||||||
|
}, []);
|
||||||
|
|
||||||
const [rows, setRows] = useState<User[]>(initial);
|
const [rows, setRows] = useState<User[]>(initial);
|
||||||
const [hasMore, setHasMore] = useState<boolean>(initialHasMore);
|
const [hasMore, setHasMore] = useState<boolean>(initialHasMore);
|
||||||
const [total, setTotal] = useState<number>(initialTotal);
|
const [total, setTotal] = useState<number>(initialTotal);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user