oblique-bit / oblique

An Angular front-end framework Tailored for your swiss branded business web application, Oblique provides a standardized corporate design look and feel as well as a collection of ready-to-use Angular components. Oblique, through its fully customizable master layout, takes care of the application's structure, letting you focus on the content.
https://oblique.bit.admin.ch
MIT License
56 stars 13 forks source link

Scroll top after navigation #146

Closed BenjaminHofstetter closed 2 weeks ago

BenjaminHofstetter commented 3 weeks ago

Description

I may be missing something, but I need help figuring out how to scroll to the top when changing routes.

I’m using a master layout, and some of my routes contain lengthy content. Currently, if I scroll down in one route and then navigate to another using the menu, I end up somewhere in the middle of the new content. However, I’d like each new route or view to start at the top after navigation.

Normally, I handle this using an Angular router feature, but it doesn’t seem to work with the Oblique master layout.

Before I implement my own workaround, is there a way to achieve this scrolling behavior directly with the master layout?

Use case

Basically every time when I change the route with long content and when the content was scrolled down to land at the top of the new content.

Relation to existing issue

No response

Proposed solution

No response

nina-egger commented 2 weeks ago

Hello @BenjaminHofstetter

I apologize for the late answer. We've had a support case about this before so I will post René's answer here. Can you try the code snippets below and see if this fixes your issue?:

Yes, Oblique is indeed blocking this behavior. This is because of the sticky header / footer which move the scrollbar from the body to an internal element of the ObMasterLayout. The Angular mechanism can only scroll on the body, but since there are no scrollbars there, nothing happens. If you configure the MasterLayout to not have sticky header and footer, then it will work.

This is not fixable at the moment, because it would mean a complete rewrite of the master layout, something that is scheduled for next year.

In the meantime, you can workaround this problem with the following code in app.component.ts:

private readonly destroyRef = inject(DestroyRef);
@ViewChild(ObMasterLayoutComponent, {static: true}) private readonly masterLayout: ObMasterLayoutComponent;
...
ngOnInit(): void {
    this.router.events
        .pipe(
            filter(event => event instanceof NavigationEnd),
            takeUntilDestroyed(this.destroyRef)
        )
        .subscribe(() => this.masterLayout.scrollTarget.scrollTo({top: 0, behavior: 'smooth'}));
}

This is a snippet for Oblique 11, It also works with Oblique 10, but need to be tweaked a little:

@ViewChild(ObMasterLayoutComponent) private readonly masterLayout: ObMasterLayoutComponent;
...
ngAfterViewInit(): void {
    this.router.events
        .pipe(filter(event => event instanceof NavigationEnd))            
        .subscribe(() => this.masterLayout.scrollTarget?.scrollTo({top: 0, behavior: 'smooth'}));
} 
BenjaminHofstetter commented 2 weeks ago

Thanks, I’ll try this.

BenjaminHofstetter commented 2 weeks ago

It works thank you @nina-egger . A small note .

scrollTo({top: 0, behavior: 'smooth'})

doesn't work on Safari on MacOS Version 18.1 (20619.2.8.11.10)

scrollTo({top: 0})

works. But this is a Safari issue and not an oblique problem.

nina-egger commented 2 weeks ago

@BenjaminHofstetter Thanks for the info. I will close this issue then.

ice-blaze commented 4 days ago

I'm wondering if we should really close the issue. Because currently there is only a workaround to simulate a standard angular behavior https://angular.dev/api/router/ExtraOptions#scrollPositionRestoration.

My biggest concern is that Oblique fix the issue but only mention it indirectly in a long list of change logs and then Projects have to live with not needed anymore workarounds. Would there be a solution to my concern? (maybe link at least this issue to the feature that will fix the issue and then having a task to ping again the discussion in this issue?)

nina-egger commented 4 days ago

@ice-blaze I'm thinking about adding those code snippets to the FAQs on our documentation, since this issue will not be solved very soon and require a rewrite of the master-layout.

But you have a point: Keeping this issue open with a "on-hold" label might also help other devs facing the same issue. I will talk about it with the other devs.