mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
docs(docs-infra): fix app-scroller offset. (#64144)
Guide heading need different scroll offsets depending on the width of the screen. (The menu position varies). PR Close #64144
This commit is contained in:
parent
ced186fafb
commit
3db8ef004f
3 changed files with 53 additions and 13 deletions
|
|
@ -5,6 +5,18 @@ $screen-lg: 1200px;
|
|||
$screen-xl: 1430px;
|
||||
$screen-xxl: 1800px;
|
||||
|
||||
@mixin breakpoints-vars {
|
||||
// The app-scroller also relies on these values to determine the scroll offset.
|
||||
:root {
|
||||
--screen-xs: #{$screen-xs};
|
||||
--screen-sm: #{$screen-sm};
|
||||
--screen-md: #{$screen-md};
|
||||
--screen-lg: #{$screen-lg};
|
||||
--screen-xl: #{$screen-xl};
|
||||
--screen-xxl: #{$screen-xxl};
|
||||
}
|
||||
}
|
||||
|
||||
@mixin for-phone-only {
|
||||
@media (max-width: $screen-xs) {
|
||||
@content;
|
||||
|
|
@ -12,43 +24,43 @@ $screen-xxl: 1800px;
|
|||
}
|
||||
|
||||
@mixin for-tablet-portrait-up {
|
||||
@media (min-width: calc($screen-xs + .01px)) {
|
||||
@media (min-width: calc($screen-xs + 0.01px)) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin for-tablet {
|
||||
@media (min-width: calc($screen-xs + .01px)) and (max-width: $screen-md) {
|
||||
@media (min-width: calc($screen-xs + 0.01px)) and (max-width: $screen-md) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin for-tablet-up {
|
||||
@media (min-width: calc($screen-sm + .01px)) {
|
||||
@media (min-width: calc($screen-sm + 0.01px)) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin for-tablet-landscape-up {
|
||||
@media (min-width: calc($screen-md + .01px)) {
|
||||
@media (min-width: calc($screen-md + 0.01px)) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin for-desktop-up {
|
||||
@media (min-width: calc($screen-lg + .01px)) {
|
||||
@media (min-width: calc($screen-lg + 0.01px)) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin for-large-desktop-up {
|
||||
@media (min-width: calc($screen-xl + .01px)) {
|
||||
@media (min-width: calc($screen-xl + 0.01px)) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin for-extra-large-desktop-up {
|
||||
@media (min-width: calc($screen-xxl + .01px)) {
|
||||
@media (min-width: calc($screen-xxl + 0.01px)) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
|
@ -75,4 +87,4 @@ $screen-xxl: 1800px;
|
|||
@media (max-width: $screen-sm) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
@include api-item-label.api-item-label();
|
||||
@include faceted-list.faceted-list();
|
||||
|
||||
@include mq.breakpoints-vars();
|
||||
@include mq.for-phone-only();
|
||||
@include mq.for-tablet-portrait-up();
|
||||
@include mq.for-tablet-landscape-up();
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
import {ViewportScroller} from '@angular/common';
|
||||
import {isPlatformBrowser, ViewportScroller} from '@angular/common';
|
||||
import {
|
||||
Injectable,
|
||||
inject,
|
||||
|
|
@ -13,6 +13,8 @@ import {
|
|||
afterNextRender,
|
||||
EnvironmentInjector,
|
||||
Injector,
|
||||
DestroyRef,
|
||||
PLATFORM_ID,
|
||||
} from '@angular/core';
|
||||
import {Scroll, Router} from '@angular/router';
|
||||
import {filter, firstValueFrom, map, switchMap, tap} from 'rxjs';
|
||||
|
|
@ -23,6 +25,7 @@ export class AppScroller {
|
|||
private readonly viewportScroller = inject(ViewportScroller);
|
||||
private readonly appRef = inject(ApplicationRef);
|
||||
private readonly injector = inject(EnvironmentInjector);
|
||||
private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
|
||||
|
||||
private _lastScrollEvent?: Scroll;
|
||||
private canScroll = false;
|
||||
|
|
@ -33,6 +36,26 @@ export class AppScroller {
|
|||
}
|
||||
|
||||
constructor() {
|
||||
if (this.isBrowser) {
|
||||
this.setupScrollRestoration();
|
||||
}
|
||||
}
|
||||
|
||||
private setupScrollRestoration(): void {
|
||||
let windowWidth = window.innerWidth;
|
||||
// Setting up a ResizeObserver to update the width on resize. (without triggering a reflow)
|
||||
const windowSizeObserver = new ResizeObserver((entries) => {
|
||||
windowWidth = entries[0].contentRect.width;
|
||||
});
|
||||
windowSizeObserver.observe(document.documentElement);
|
||||
inject(DestroyRef).onDestroy(() => windowSizeObserver.disconnect());
|
||||
|
||||
const root = document.documentElement; // or any element with the variable
|
||||
const styles = getComputedStyle(root);
|
||||
// slice to drop the 'px'
|
||||
const xsBreakpoint = +styles.getPropertyValue('--screen-xs').slice(0, -2);
|
||||
const mdBreakpoint = +styles.getPropertyValue('--screen-md').slice(0, -2);
|
||||
|
||||
this.viewportScroller.setHistoryScrollRestoration('manual');
|
||||
this.router.events
|
||||
.pipe(
|
||||
|
|
@ -62,12 +85,16 @@ export class AppScroller {
|
|||
this.scroll();
|
||||
});
|
||||
|
||||
// This value is primarily intended to offset the scroll position on mobile when the menu is on the top.
|
||||
// But on desktop, it doesn't hurt to have a small offset either.
|
||||
this.viewportScroller.setOffset([0, 64]);
|
||||
if (windowWidth < xsBreakpoint) {
|
||||
this.viewportScroller.setOffset([0, 64]);
|
||||
} else if (windowWidth <= mdBreakpoint) {
|
||||
this.viewportScroller.setOffset([0, 140]);
|
||||
} else {
|
||||
this.viewportScroller.setOffset([0, 24]);
|
||||
}
|
||||
}
|
||||
|
||||
scroll(injector?: Injector) {
|
||||
private scroll(injector?: Injector) {
|
||||
if (!this._lastScrollEvent || !this.canScroll) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue