Skip to content

Commit a4fdee8

Browse files
committed
feat(grid): use Angular injected document to allow Server Side Rendering
Closes #124
1 parent f446306 commit a4fdee8

File tree

3 files changed

+17
-13
lines changed

3 files changed

+17
-13
lines changed

projects/angular-grid-layout/src/lib/grid-item/grid-item.component.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { GRID_ITEM_GET_RENDER_DATA_TOKEN, KtdGridItemRenderDataTokenType } from
1313
import { KtdGridService } from '../grid.service';
1414
import { ktdOutsideZone } from '../utils/operators';
1515
import { ktdIsMouseEventOrMousePointerEvent, ktdPointerClient, ktdPointerDown, ktdPointerUp } from '../utils/pointer.utils';
16+
import { DOCUMENT } from '@angular/common';
1617

1718
@Component({
1819
standalone: true,
@@ -109,6 +110,7 @@ export class KtdGridItemComponent implements OnInit, OnDestroy, AfterContentInit
109110
private gridService: KtdGridService,
110111
private renderer: Renderer2,
111112
private ngZone: NgZone,
113+
@Inject(DOCUMENT) private document: Document,
112114
@Inject(GRID_ITEM_GET_RENDER_DATA_TOKEN) private getItemRenderData: KtdGridItemRenderDataTokenType) {
113115
this.dragStart$ = this.dragStartSubject.asObservable();
114116
this.resizeStart$ = this.resizeStartSubject.asObservable();
@@ -183,8 +185,8 @@ export class KtdGridItemComponent implements OnInit, OnDestroy, AfterContentInit
183185
}
184186

185187
const startPointer = ktdPointerClient(startEvent);
186-
return this.gridService.mouseOrTouchMove$(document).pipe(
187-
takeUntil(ktdPointerUp(document)),
188+
return this.gridService.mouseOrTouchMove$(this.document).pipe(
189+
takeUntil(ktdPointerUp(this.document)),
188190
ktdOutsideZone(this.ngZone),
189191
filter((moveEvent) => {
190192
moveEvent.preventDefault();

projects/angular-grid-layout/src/lib/grid.component.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import {
2-
AfterContentChecked, AfterContentInit, ChangeDetectionStrategy, Component, ContentChildren, ElementRef, EmbeddedViewRef, EventEmitter,
3-
HostBinding, Input,
2+
AfterContentChecked, AfterContentInit, ChangeDetectionStrategy, Component, ContentChildren, ElementRef, EmbeddedViewRef, EventEmitter, Inject, Input,
43
NgZone, OnChanges, OnDestroy, Output, QueryList, Renderer2, SimpleChanges, ViewContainerRef, ViewEncapsulation
54
} from '@angular/core';
65
import { coerceNumberProperty, NumberInput } from './coercion/number-property';
@@ -20,6 +19,7 @@ import { ktdGetScrollTotalRelativeDifference$, ktdScrollIfNearElementClientRect$
2019
import { BooleanInput, coerceBooleanProperty } from './coercion/boolean-property';
2120
import { KtdGridItemPlaceholder } from './directives/placeholder';
2221
import { getTransformTransitionDurationInMs } from './utils/transition-duration';
22+
import { DOCUMENT } from '@angular/common';
2323

2424
interface KtdDragResizeEvent {
2525
layout: KtdGridLayout;
@@ -315,7 +315,8 @@ export class KtdGridComponent implements OnChanges, AfterContentInit, AfterConte
315315
private elementRef: ElementRef,
316316
private viewContainerRef: ViewContainerRef,
317317
private renderer: Renderer2,
318-
private ngZone: NgZone) {
318+
private ngZone: NgZone,
319+
@Inject(DOCUMENT) private document: Document) {
319320

320321
}
321322

@@ -491,7 +492,7 @@ export class KtdGridComponent implements OnChanges, AfterContentInit, AfterConte
491492
const gridElemClientRect: KtdClientRect = getMutableClientRect(this.elementRef.nativeElement as HTMLElement);
492493
const dragElemClientRect: KtdClientRect = getMutableClientRect(gridItem.elementRef.nativeElement as HTMLElement);
493494

494-
const scrollableParent = typeof this.scrollableParent === 'string' ? document.getElementById(this.scrollableParent) : this.scrollableParent;
495+
const scrollableParent = typeof this.scrollableParent === 'string' ? this.document.getElementById(this.scrollableParent) : this.scrollableParent;
495496

496497
this.renderer.addClass(gridItem.elementRef.nativeElement, 'no-transitions');
497498
this.renderer.addClass(gridItem.elementRef.nativeElement, 'ktd-grid-item-dragging');
@@ -509,14 +510,14 @@ export class KtdGridComponent implements OnChanges, AfterContentInit, AfterConte
509510
// - Pros are that we would not repeat subscriptions and takeUntil would shut down observables at the same time.
510511
// - Cons are that moving this functionality as a side effect inside the main drag loop would be confusing.
511512
const scrollSubscription = this.ngZone.runOutsideAngular(() =>
512-
(!scrollableParent ? NEVER : this.gridService.mouseOrTouchMove$(document).pipe(
513+
(!scrollableParent ? NEVER : this.gridService.mouseOrTouchMove$(this.document).pipe(
513514
map((event) => ({
514515
pointerX: ktdPointerClientX(event),
515516
pointerY: ktdPointerClientY(event)
516517
})),
517518
ktdScrollIfNearElementClientRect$(scrollableParent, {scrollStep: this.scrollSpeed})
518519
)).pipe(
519-
takeUntil(ktdPointerUp(document))
520+
takeUntil(ktdPointerUp(this.document))
520521
).subscribe());
521522

522523
/**
@@ -525,15 +526,15 @@ export class KtdGridComponent implements OnChanges, AfterContentInit, AfterConte
525526
const subscription = this.ngZone.runOutsideAngular(() =>
526527
merge(
527528
combineLatest([
528-
this.gridService.mouseOrTouchMove$(document),
529+
this.gridService.mouseOrTouchMove$(this.document),
529530
...(!scrollableParent ? [of({top: 0, left: 0})] : [
530531
ktdGetScrollTotalRelativeDifference$(scrollableParent).pipe(
531532
startWith({top: 0, left: 0}) // Force first emission to allow CombineLatest to emit even no scroll event has occurred
532533
)
533534
])
534535
])
535536
).pipe(
536-
takeUntil(ktdPointerUp(document)),
537+
takeUntil(ktdPointerUp(this.document)),
537538
).subscribe(([pointerDragEvent, scrollDifference]: [MouseEvent | TouchEvent | PointerEvent, { top: number, left: number }]) => {
538539
pointerDragEvent.preventDefault();
539540

projects/angular-grid-layout/src/lib/grid.service.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import { Injectable, NgZone, OnDestroy } from '@angular/core';
1+
import { Inject, Injectable, NgZone, OnDestroy } from '@angular/core';
22
import { ktdNormalizePassiveListenerOptions } from './utils/passive-listeners';
33
import { fromEvent, iif, Observable, Subject, Subscription } from 'rxjs';
44
import { filter } from 'rxjs/operators';
55
import { ktdIsMobileOrTablet, ktdSupportsPointerEvents } from './utils/pointer.utils';
6+
import { DOCUMENT } from '@angular/common';
67

78
/** Event options that can be used to bind an active, capturing event. */
89
const activeCapturingEventOptions = ktdNormalizePassiveListenerOptions({
@@ -17,7 +18,7 @@ export class KtdGridService implements OnDestroy {
1718
private touchMoveSubject: Subject<TouchEvent> = new Subject<TouchEvent>();
1819
private touchMoveSubscription: Subscription;
1920

20-
constructor(private ngZone: NgZone) {
21+
constructor(private ngZone: NgZone, @Inject(DOCUMENT) private document: Document) {
2122
this.touchMove$ = this.touchMoveSubject.asObservable();
2223
this.registerTouchMoveSubscription();
2324
}
@@ -45,7 +46,7 @@ export class KtdGridService implements OnDestroy {
4546
this.touchMoveSubscription = this.ngZone.runOutsideAngular(() =>
4647
// The event handler has to be explicitly active,
4748
// because newer browsers make it passive by default.
48-
fromEvent(document, 'touchmove', activeCapturingEventOptions as AddEventListenerOptions) // TODO: Fix rxjs typings, boolean should be a good param too.
49+
fromEvent(this.document, 'touchmove', activeCapturingEventOptions as AddEventListenerOptions) // TODO: Fix rxjs typings, boolean should be a good param too.
4950
.pipe(filter((touchEvent: TouchEvent) => touchEvent.touches.length === 1))
5051
.subscribe((touchEvent: TouchEvent) => this.touchMoveSubject.next(touchEvent))
5152
);

0 commit comments

Comments
 (0)