yew icon indicating copy to clipboard operation
yew copied to clipboard

window does not scroll on top when switching routes

Open squarfed opened this issue 5 years ago • 10 comments

I am not sure if it is on purpose, but right now when routes are switched the scrollbar is not reset to the (0,0) position. What is a suitable workaround?

squarfed avatar Mar 19 '20 11:03 squarfed

This isn't a concern with the router itself.

The probable solution would be to have a Scrollable component that you reset to the top when you detect a route change. I think that such a component would be a welcome addition to the router project should someone want to contribute one.

hgzimmerman avatar Apr 23 '20 14:04 hgzimmerman

@hamza1311 should we consider making this an option with the new ~~user~~ router? I'm thinking we could add a prop scroll_to_top: bool that does exactly this.

siku2 avatar May 18 '21 16:05 siku2

@hamza1311 should we consider making this an option with the new user? I'm thinking we could add a prop scroll_to_top: bool that does exactly this.

"new user"? I think we should make this the default with an option to opt out (for cases like Discord, where the URL defines which node should be in view). I wonder how other routers (angular/vue/react router) do this

ranile avatar May 18 '21 16:05 ranile

"new user"? I think we should make this the default with an option to opt out (for cases like Discord, where the URL defines which node should be in view). I wonder how other routers (angular/vue/react router) do this

Sorry, meant to write new router but got distracted and my fingers decided to type something on their own :D Anyway, I'm not particular over whether this is the default or not (though I'm tending toward yes as well). It seems like we both agree that this should be a feature though.

siku2 avatar May 18 '21 17:05 siku2

It seems like we both agree that this should be a feature though.

Yes. That's what causes the router example to stay in weird position when switching routes, requiring manual scroll-up

ranile avatar May 18 '21 17:05 ranile

I know it is been a while, but the issue is still there. React offers this sorta functionality with Scroll Restoration I briefly skimmed thru their code, and basically they save scroll y for each page in a stack and restore it with window.scrollTo, defaulting to window.scrollTo(0, 0); if a page wasn't visited before.

Prob for starters a simple reset with window.scrollTo(0, 0); on navigation change would suffice, but in the current yew-router implementation I only see one window reference. Maybe if you could point out where it would be the most suitable to be added I could implement it

Enigo avatar May 29 '23 15:05 Enigo

@hamza1311 @futursolo any feedback on it :point_up: ?

Enigo avatar Jun 04 '23 13:06 Enigo

I think you can replicate this behaviour with the following code.

let location = use_location();

use_effect_with_deps(|_| {
    window.scroll_to(ScrollToOptions::new().top(0));
}, location);

You can extend the above by storing the data in location.state() if you wish to restore the scroll location.

futursolo avatar Jun 04 '23 13:06 futursolo

I ended up with the following implementation:

Cargo.toml

web-sys = { version = "0.3.63", features = ["Window", "ScrollToOptions", "ScrollBehavior"] }

helper function

pub fn scroll_to_top() {
    let window = web_sys::window();
    if window.is_some() {
        window.unwrap().scroll_to_with_scroll_to_options(web_sys::ScrollToOptions::new().top(0.0).behavior(web_sys::ScrollBehavior::Instant));
    } else {
        warn!("Window is not found!")
    }
}

calling it like

use_effect_with_deps(
    |_| {
        navigation_utils::scroll_to_top();
}, ());

The question is - do you think this kind of functionality should reside in the the router code itself?

Enigo avatar Aug 06 '23 05:08 Enigo