Skip to content

Migration Guide: v0.0.1-rc.1 to v0.0.1-rc.2

This guide details the new configuration options, behavioral improvements, and SSR enhancements when upgrading @devzwo/ngx-magic-scroll from v0.0.1-rc.1 to v0.0.1-rc.2.

Release v0.0.1-rc.2 introduces key improvements to scroll-spy precision, restoration lifecycle handling, and server-side rendering resilience:

  • Active Reading Area & Trigger Lines: Configurable bottomOffset and activationThreshold options to fine-tune section detection and exclusion zones.
  • User Interaction Cancellation: User input (wheel, touch, keyboard scroll keys) prior to data readiness gracefully cancels pending initial scroll restoration without breaking programmatic navigation.
  • Server-Side Rendering (SSR) Resilience: Improved guards for environments where ResizeObserver or defaultView is unavailable.

1. Configuring Active Reading Boundaries and Trigger Lines

Section titled “1. Configuring Active Reading Boundaries and Trigger Lines”

In v0.0.1-rc.1, scroll-spy calculations used a fixed top reference line (factoring in headerOffset and headerSelector). When scrolling through long pages with floating action bars, footers, or tall cards, active section detection could activate too late or trigger outside the reader’s primary viewing zone.

v0.0.1-rc.2 adds two options to MagicScrollOptions:

  • bottomOffset: Defines a bottom exclusion boundary in pixels (e.g. for sticky bottom bars or mobile navigation).
  • activationThreshold: A relative factor between 0.0 (top) and 1.0 (bottom) defining where within the effective reading area the active anchor trigger line sits.
import { Component } from '@angular/core';
import {
MagicScrollDirective,
ScrollAnchorDirective,
provideMagicScroll,
} from '@devzwo/ngx-magic-scroll';
@Component({
selector: 'app-migration-rc1-sample-before',
imports: [MagicScrollDirective, ScrollAnchorDirective],
providers: [
provideMagicScroll({
headerOffset: 64,
}),
],
template: `
<div magicScroll>
<section id="intro" scrollAnchor>
<h2>Introduction</h2>
</section>
<section id="specs" scrollAnchor>
<h2>Specifications</h2>
</section>
</div>
`,
})
export class MigrationRc1SampleBeforeComponent {}
import { Component } from '@angular/core';
import {
MagicScrollDirective,
ScrollAnchorDirective,
provideMagicScroll,
} from '@devzwo/ngx-magic-scroll';
@Component({
selector: 'app-migration-rc1-sample-after',
imports: [MagicScrollDirective, ScrollAnchorDirective],
providers: [
provideMagicScroll({
headerOffset: 64,
bottomOffset: 48,
activationThreshold: 0.25,
}),
],
template: `
<div
magicScroll
[scrollOptions]="{
headerOffset: 64,
bottomOffset: 48,
activationThreshold: 0.25,
}"
>
<section id="intro" scrollAnchor>
<h2>Introduction</h2>
</section>
<section id="specs" scrollAnchor>
<h2>Specifications</h2>
</section>
</div>
`,
})
export class MigrationRc1SampleAfterComponent {}

2. Interaction-Aware Scroll Restoration Lifecycle

Section titled “2. Interaction-Aware Scroll Restoration Lifecycle”

In v0.0.1-rc.1, when a page loaded with a pending URL fragment and asynchronous data source (scrollSource), initial position restoration waited for data readiness. If the user scrolled manually before data arrived, the subsequent delayed restoration could jump the page unexpectedly.

In v0.0.1-rc.2:

  • User interactions (mouse wheel, touch drag, keyboard navigation keys like PageDown, ArrowDown, Space) cancel pending initial restoration.
  • Focus or keystrokes inside editable fields (<input>, <textarea>, contenteditable) do not cancel restoration.
  • Programmatic calls to scrollTo() remain fully functional and are never blocked by prior user cancellation.
import { Component, signal } from '@angular/core';
import {
MagicScrollDirective,
ScrollAnchorDirective,
provideMagicScroll,
} from '@devzwo/ngx-magic-scroll';
interface Item {
readonly id: string;
readonly title: string;
}
@Component({
selector: 'app-migration-rc1-async-sample',
imports: [MagicScrollDirective, ScrollAnchorDirective],
providers: [provideMagicScroll()],
template: `
<div magicScroll [scrollSource]="items()">
@for (item of items(); track item.id) {
<article [id]="item.id" scrollAnchor>
<h3>{{ item.title }}</h3>
</article>
}
</div>
`,
})
export class MigrationRc1AsyncSampleComponent {
// undefined simulates loading; user scrolling during this phase cancels initial jump safely
readonly items = signal<Item[] | undefined>(undefined);
constructor() {
setTimeout(() => {
this.items.set([
{ id: 'item-1', title: 'First Item' },
{ id: 'item-2', title: 'Second Item' },
]);
}, 150);
}
}

v0.0.1-rc.2 enhances SSR compatibility by guarding observer instantiation (ResizeObserver, MutationObserver) and window references (defaultView). No code changes are required in your templates or providers; the directive safely skips DOM-only observers in SSR environments.


  • Breaking Changes: None. Default parameters preserve compatibility with v0.0.1-rc.1.
  • Deprecations: None.