From a7bf98b219d7f547367cb3c2983d6294b8784a6c Mon Sep 17 00:00:00 2001 From: Murhaf Sousli Date: Sat, 30 Nov 2024 01:45:14 +0100 Subject: [PATCH] Update --- CHANGELOG.md | 6 ++ .../overview-content.component.ts | 35 ------------ .../scroll-content.directive.ts | 57 +------------------ projects/ngx-scrollbar/package.json | 2 +- .../lib/button/scrollbar-button.component.ts | 2 +- .../src/lib/scrollbar/scrollbar.ts | 7 +-- projects/ngx-scrollbar/src/lib/sync-spacer.ts | 2 +- .../src/lib/track/track-adapter.ts | 14 ++++- projects/ngx-scrollbar/src/lib/track/track.ts | 7 +-- .../src/lib/utils/pointer-events-adapter.ts | 6 +- 10 files changed, 31 insertions(+), 107 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9cc668e9..cfd60213 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 16.1.1 + +- fix: Bug with `visibility="visible"` closes [#674](https://github.com/MurhafSousli/ngx-scrollbar/issues/674). +- refactor: In effects, move `onCleanup` function inside `untracked` function in the `PointerEventsAdapter` class. +- refactor: Use `from` instead of `fromPromise` to convert a promise to observable. + ## 16.1.0 - feat: Disable / Suppress the scroll bar during runtime, in [#658](https://github.com/MurhafSousli/ngx-scrollbar/issues/658). diff --git a/projects/ngx-scrollbar-demo/src/app/example-scrollto-element/overview-content/overview-content.component.ts b/projects/ngx-scrollbar-demo/src/app/example-scrollto-element/overview-content/overview-content.component.ts index cd588361..f9768623 100644 --- a/projects/ngx-scrollbar-demo/src/app/example-scrollto-element/overview-content/overview-content.component.ts +++ b/projects/ngx-scrollbar-demo/src/app/example-scrollto-element/overview-content/overview-content.component.ts @@ -2,21 +2,16 @@ import { Component, inject, signal, - effect, - PLATFORM_ID, AfterViewInit, OnDestroy, - NgZone, WritableSignal, ChangeDetectionStrategy } from '@angular/core'; -import { isPlatformBrowser } from '@angular/common'; import { ActivatedRoute } from '@angular/router'; import { Subscription, tap } from 'rxjs'; import { NgScrollbar } from 'ngx-scrollbar'; import { AnchorLinkComponent } from '../anchor-link/anchor-link.component'; import { ScrollContent } from '../scroll-content.directive'; -import { ScrollAnchor } from '../scroll-anchor.directive'; @Component({ standalone: true, @@ -32,44 +27,14 @@ export class OverviewContentComponent implements AfterViewInit, OnDestroy { private fragmentSub$: Subscription; - // readonly isBrowser: boolean = isPlatformBrowser(inject(PLATFORM_ID)); - private activatedRoute: ActivatedRoute = inject(ActivatedRoute); - // private zone: NgZone = inject(NgZone); - private scrollbar: NgScrollbar = inject(NgScrollbar, { skipSelf: true }); scrollContent: ScrollContent = inject(ScrollContent, { skipSelf: true }); activeLinkId: WritableSignal = signal(''); - constructor() { - // if (this.isBrowser) { - // this.zone.runOutsideAngular(() => { - // const intersectionObserver: IntersectionObserver = new IntersectionObserver((entries: IntersectionObserverEntry[]) => { - // entries.forEach((entry: IntersectionObserverEntry) => { - // if (entry.intersectionRatio > 0) { - // this.zone.run(() => { - // this.activeLinkId.set(entry.target.id); - // }); - // } - // }); - // }, { - // root: this.scrollbar.viewport.nativeElement, - // rootMargin: '0px 0px 0px -10%', - // threshold: 1.0 - // }); - // - // effect(() => { - // this.scrollContent.anchors().forEach((group: ScrollAnchor) => { - // intersectionObserver.observe(group.nativeElement); - // }); - // }); - // }); - // } - } - private goToAnchor(id: string): void { this.scrollbar.scrollToElement(`#${ id }`, { top: -75, duration: 700 }); } diff --git a/projects/ngx-scrollbar-demo/src/app/example-scrollto-element/scroll-content.directive.ts b/projects/ngx-scrollbar-demo/src/app/example-scrollto-element/scroll-content.directive.ts index f6c8e865..e1d8dff1 100644 --- a/projects/ngx-scrollbar-demo/src/app/example-scrollto-element/scroll-content.directive.ts +++ b/projects/ngx-scrollbar-demo/src/app/example-scrollto-element/scroll-content.directive.ts @@ -1,18 +1,4 @@ -import { - computed, contentChildren, ContentChildren, Directive, - effect, - ElementRef, - inject, - NgZone, - PLATFORM_ID, - QueryList, - signal, - Signal, - WritableSignal -} from '@angular/core'; -import { isPlatformBrowser } from '@angular/common'; -import { ActivatedRoute } from '@angular/router'; -import { Subscription } from 'rxjs'; +import { Directive, computed, contentChildren, Signal } from '@angular/core'; import { ScrollAnchor } from './scroll-anchor.directive'; @Directive({ @@ -21,51 +7,10 @@ import { ScrollAnchor } from './scroll-anchor.directive'; }) export class ScrollContent { - // readonly isBrowser: boolean = isPlatformBrowser(inject(PLATFORM_ID)); - - readonly nativeElement: HTMLElement = inject(ElementRef).nativeElement; - - // private activatedRoute: ActivatedRoute = inject(ActivatedRoute); - - // private zone: NgZone = inject(NgZone); - - // private fragmentSub$: Subscription; - - // activeId: WritableSignal = signal(''); - anchors: Signal = contentChildren(ScrollAnchor, { descendants: true }); anchorsTree: Signal = computed(() => { return this.anchors().filter((anchor: ScrollAnchor) => anchor.children.length); }); - // constructor() { - // if (this.isBrowser) { - // this.zone.runOutsideAngular(() => { - // const intersectionObserver: IntersectionObserver = new IntersectionObserver((entries: IntersectionObserverEntry[]) => { - // console.log(entries) - // entries.forEach((entry: IntersectionObserverEntry) => { - // if (entry.intersectionRatio > 0) { - // this.zone.run(() => { - // this.activeId.set(entry.target.id); - // }) - // } - // }); - // }, { - // root: this.nativeElement, - // rootMargin: '-10% 0px -50% 0px', - // }); - - // effect(() => { - // this.anchors().forEach((group: Group) => { - // console.log(group) - // intersectionObserver.observe(group.element); - // group.sections.forEach((section: Element) => { - // intersectionObserver.observe(section); - // }); - // }); - // }); - // }); - // } - // } } diff --git a/projects/ngx-scrollbar/package.json b/projects/ngx-scrollbar/package.json index 9dd49a91..7ae27ec3 100644 --- a/projects/ngx-scrollbar/package.json +++ b/projects/ngx-scrollbar/package.json @@ -1,6 +1,6 @@ { "name": "ngx-scrollbar", - "version": "16.1.0", + "version": "16.1.1", "license": "MIT", "homepage": "https://ngx-scrollbar.netlify.app/", "author": { diff --git a/projects/ngx-scrollbar/src/lib/button/scrollbar-button.component.ts b/projects/ngx-scrollbar/src/lib/button/scrollbar-button.component.ts index 4c83c189..96fe0744 100644 --- a/projects/ngx-scrollbar/src/lib/button/scrollbar-button.component.ts +++ b/projects/ngx-scrollbar/src/lib/button/scrollbar-button.component.ts @@ -1,4 +1,4 @@ -import { Component, effect, untracked, input, InputSignal, ChangeDetectionStrategy, } from '@angular/core'; +import { Component, effect, untracked, input, InputSignal, ChangeDetectionStrategy } from '@angular/core'; import { Direction } from '@angular/cdk/bidi'; import { Observable, diff --git a/projects/ngx-scrollbar/src/lib/scrollbar/scrollbar.ts b/projects/ngx-scrollbar/src/lib/scrollbar/scrollbar.ts index 1ccb3bae..c789849a 100644 --- a/projects/ngx-scrollbar/src/lib/scrollbar/scrollbar.ts +++ b/projects/ngx-scrollbar/src/lib/scrollbar/scrollbar.ts @@ -1,6 +1,5 @@ import { Component, effect, inject, ChangeDetectionStrategy } from '@angular/core'; -import { Observable } from 'rxjs'; -import { fromPromise } from 'rxjs/internal/observable/innerFrom'; +import { from, Observable } from 'rxjs'; import { TrackXDirective, TrackYDirective } from '../track/track'; import { ThumbXDirective, ThumbYDirective } from '../thumb/thumb'; import { SCROLLBAR_CONTROL, ScrollbarAdapter } from './scrollbar-adapter'; @@ -62,7 +61,7 @@ export class ScrollbarY extends ScrollbarAdapter { } scrollTo(top: number, duration: number): Observable { - return fromPromise(this.cmp.scrollTo({ top, duration })); + return from(this.cmp.scrollTo({ top, duration })); } instantScrollTo(value: number): void { @@ -143,7 +142,7 @@ export class ScrollbarX extends ScrollbarAdapter { } scrollTo(left: number, duration: number): Observable { - return fromPromise(this.cmp.scrollTo({ left, duration })); + return from(this.cmp.scrollTo({ left, duration })); } instantScrollTo(value: number, scrollMax?: number): void { diff --git a/projects/ngx-scrollbar/src/lib/sync-spacer.ts b/projects/ngx-scrollbar/src/lib/sync-spacer.ts index a6e93aa2..6aba4695 100644 --- a/projects/ngx-scrollbar/src/lib/sync-spacer.ts +++ b/projects/ngx-scrollbar/src/lib/sync-spacer.ts @@ -63,7 +63,7 @@ export class SyncSpacer { }); }); } - onCleanup(() => sub$?.unsubscribe()) + onCleanup(() => sub$?.unsubscribe()); }); }); } diff --git a/projects/ngx-scrollbar/src/lib/track/track-adapter.ts b/projects/ngx-scrollbar/src/lib/track/track-adapter.ts index 87598202..10f5c551 100644 --- a/projects/ngx-scrollbar/src/lib/track/track-adapter.ts +++ b/projects/ngx-scrollbar/src/lib/track/track-adapter.ts @@ -1,4 +1,5 @@ -import { Directive, effect, untracked } from '@angular/core'; +import { Directive, effect, inject, PLATFORM_ID, untracked } from '@angular/core'; +import { isPlatformBrowser } from '@angular/common'; import { Observable, delay, @@ -18,6 +19,8 @@ import { PointerEventsAdapter } from '../utils/pointer-events-adapter'; @Directive() export abstract class TrackAdapter extends PointerEventsAdapter { + private readonly isBrowser: boolean = isPlatformBrowser(inject(PLATFORM_ID)); + // The current position of the mouse during track dragging private currMousePosition: number; @@ -116,7 +119,14 @@ export abstract class TrackAdapter extends PointerEventsAdapter { effect(() => { this.cmp.viewportDimension(); this.cmp.contentDimension(); - untracked(() => this.control.trackSize.set(this.size)); + + // Avoid SSR error because we're using `requestAnimationFrame` + if (!this.isBrowser) return; + + untracked(() => { + // Use animation frame to give the track element time to render (avoid size 0) + requestAnimationFrame(() => this.control.trackSize.set(this.size)); + }); }); super(); } diff --git a/projects/ngx-scrollbar/src/lib/track/track.ts b/projects/ngx-scrollbar/src/lib/track/track.ts index 8a7317cb..aa2f5553 100644 --- a/projects/ngx-scrollbar/src/lib/track/track.ts +++ b/projects/ngx-scrollbar/src/lib/track/track.ts @@ -1,6 +1,5 @@ import { Directive, effect } from '@angular/core'; -import { Observable } from 'rxjs'; -import { fromPromise } from 'rxjs/internal/observable/innerFrom'; +import { from, Observable } from 'rxjs'; import { TrackAdapter } from './track-adapter'; @Directive({ @@ -41,7 +40,7 @@ export class TrackXDirective extends TrackAdapter { } protected scrollTo(start: number): Observable { - return fromPromise(this.cmp.scrollTo({ start, duration: this.cmp.trackScrollDuration() })); + return from(this.cmp.scrollTo({ start, duration: this.cmp.trackScrollDuration() })); } protected getScrollForwardStep(): number { @@ -73,7 +72,7 @@ export class TrackYDirective extends TrackAdapter { } protected scrollTo(top: number): Observable { - return fromPromise(this.cmp.scrollTo({ top, duration: this.cmp.trackScrollDuration() })); + return from(this.cmp.scrollTo({ top, duration: this.cmp.trackScrollDuration() })); } protected getScrollForwardStep(): number { diff --git a/projects/ngx-scrollbar/src/lib/utils/pointer-events-adapter.ts b/projects/ngx-scrollbar/src/lib/utils/pointer-events-adapter.ts index 9155a8f9..073b3b89 100644 --- a/projects/ngx-scrollbar/src/lib/utils/pointer-events-adapter.ts +++ b/projects/ngx-scrollbar/src/lib/utils/pointer-events-adapter.ts @@ -27,7 +27,7 @@ export abstract class PointerEventsAdapter { abstract get pointerEvents(): Observable; - constructor() { + protected constructor() { effect((onCleanup: EffectCleanupRegisterFn) => { const disableInteraction: boolean = this.cmp.disableInteraction(); @@ -37,9 +37,9 @@ export abstract class PointerEventsAdapter { this._pointerEventsSub = this.pointerEvents.subscribe(); }); } - }); - onCleanup(() => this._pointerEventsSub?.unsubscribe()); + onCleanup(() => this._pointerEventsSub?.unsubscribe()); + }); }); } }