sycamore-rs / sycamore

A library for creating reactive web apps in Rust and WebAssembly
https://sycamore-rs.netlify.app
MIT License
2.79k stars 148 forks source link

Make scrolling to top in `HistoryIntegration` optional #564

Open Dav1dde opened 1 year ago

Dav1dde commented 1 year ago

Currently the HistoryIntegration click handler includes window.scroll_to_with_x_and_y(0.0, 0.0);, this immediately scrolls to top when the user clicks a navigation link.

This is not always desired, e.g. in the following flow click -> (load resources for new page) -> update view. The router immediately updates but the view is only changed once the resources for the new page are fully fetched. Github has this e.g. while the new page is loading it displays a global loading indicator at the top of the page, the scroll will only be reset after the new page is actually displayed.

Since the router is not aware of futures, the reset would need to happen manually. Alternatively the routers view function could be made async and only once the function completes the router would reset the scroll.

Dav1dde commented 1 year ago

Actually a full scroll restoration would be better. I was messing around with attaching the scroll value to the browser history state. Unfortunately this breaks on multiple history navigations (forward, backward), because you can't intercept the popstate event, update the state for that route, then switch to the old route.

Two solutions: 1) Update the state with a debounced onscroll listener 2) Have an internal store for routes + scroll values

arctic-hen7 commented 1 year ago

@Dav1dde there's an issue I opened a while ago on scroll state restoration, but to be honest I wonder now if that should be in Sycamore or not. It would seem more natural to put it in something like Perseus (which already has the infrastructure of the page state store), or perhaps a separate library that provides a custom router integration or the like.

Dav1dde commented 1 year ago

but to be honest I wonder now if that should be in Sycamore or not

I personally think it fits in sycamore-router, which already is a separate library from sycamore.

lukechu10 commented 1 year ago

Yeah this should probably go in sycamore-router. Also we could potentially integrate this with Suspense. Basically, only change URL / reset scroll state when suspense resolves.

Also there should definitely be a way to turn this off completely because there are cases where you don't want to scroll back to the top.