diff --git a/.github/workflows/pr-build.yml b/.github/workflows/pr-build.yml index 6dcef4ff78..6c1c65eec9 100644 --- a/.github/workflows/pr-build.yml +++ b/.github/workflows/pr-build.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - angular: ['Angular v15', 'Angular v16', 'Angular v17', 'Angular v18'] + angular: ['Angular v15', 'Angular v16', 'Angular v17', 'Angular v18', 'Angular v19'] steps: - name: Checkout uses: actions/checkout@v3 @@ -22,17 +22,21 @@ jobs: - name: Install Dependencies run: npm ci - name: Update to Angular v16 - if: ${{matrix.angular == 'Angular v16' || matrix.angular == 'Angular v17' || matrix.angular == 'Angular v18'}} + if: ${{matrix.angular == 'Angular v16' || matrix.angular == 'Angular v17' || matrix.angular == 'Angular v18' || matrix.angular == 'Angular v19'}} run: | npx ng update @angular/core@16 @angular/common@16 @angular/cli@16 @angular/cdk@16 --force - name: Update to Angular v17 - if: ${{matrix.angular == 'Angular v17' || matrix.angular == 'Angular v18'}} + if: ${{matrix.angular == 'Angular v17' || matrix.angular == 'Angular v18' || matrix.angular == 'Angular v19'}} run: | npx ng update @angular/core@17 @angular/common@17 @angular/cli@17 @angular/cdk@17 --allow-dirty --force - name: Update to Angular v18 - if: ${{matrix.angular == 'Angular v18'}} + if: ${{matrix.angular == 'Angular v18' || matrix.angular == 'Angular v19'}} run: | npx ng update @angular/core@18 @angular/common@18 @angular/cli@18 @angular/cdk@18 --allow-dirty --force + - name: Update to Angular v19 + if: ${{matrix.angular == 'Angular v19'}} + run: | + npx ng update @angular/core@19 @angular/common@19 @angular/cli@19 @angular/cdk@19 --allow-dirty --force - name: Disable Storybook Build if: ${{matrix.angular != 'Angular v15'}} run: node ./scripts/clear-npm-script.js _build:storybook diff --git a/projects/angular/package.json b/projects/angular/package.json index 8cbde6d127..5851a087f1 100644 --- a/projects/angular/package.json +++ b/projects/angular/package.json @@ -18,9 +18,9 @@ "url": "https://github.com/vmware-clarity/ng-clarity/issues" }, "peerDependencies": { - "@angular/cdk": "15 || 16 || 17 || 18", - "@angular/common": "15 || 16 || 17 || 18", - "@angular/core": "15 || 16 || 17 || 18", + "@angular/cdk": "15 || 16 || 17 || 18 || 19", + "@angular/common": "15 || 16 || 17 || 18 || 19", + "@angular/core": "15 || 16 || 17 || 18 || 19", "@cds/core": ">= 6.9.2" } } diff --git a/projects/angular/src/data/datagrid/datagrid-virtual-scroll.directive.ts b/projects/angular/src/data/datagrid/datagrid-virtual-scroll.directive.ts index 16d36ff99d..a1e5da6fc8 100644 --- a/projects/angular/src/data/datagrid/datagrid-virtual-scroll.directive.ts +++ b/projects/angular/src/data/datagrid/datagrid-virtual-scroll.directive.ts @@ -7,19 +7,23 @@ import { Directionality } from '@angular/cdk/bidi'; import { coerceNumberProperty } from '@angular/cdk/coercion'; -import { _RecycleViewRepeaterStrategy, ListRange } from '@angular/cdk/collections'; +import { _RecycleViewRepeaterStrategy, _VIEW_REPEATER_STRATEGY, ListRange } from '@angular/cdk/collections'; import { CdkFixedSizeVirtualScroll, CdkVirtualForOf, CdkVirtualForOfContext, + CdkVirtualScrollable, CdkVirtualScrollableElement, CdkVirtualScrollViewport, FixedSizeVirtualScrollStrategy, ScrollDispatcher, ViewportRuler, + VIRTUAL_SCROLL_STRATEGY, + VirtualScrollStrategy, } from '@angular/cdk/scrolling'; import { AfterViewInit, + VERSION as ANGULAR_VERSION, ChangeDetectorRef, Directive, DoCheck, @@ -27,6 +31,8 @@ import { EmbeddedViewRef, EnvironmentInjector, EventEmitter, + inject, + Injector, Input, IterableDiffers, NgZone, @@ -199,7 +205,7 @@ export class ClrDatagridVirtualScrollDirective implements AfterViewInit, DoCh this.virtualScrollStrategy ); - this.cdkVirtualFor = new CdkVirtualForOf( + this.cdkVirtualFor = createCdkVirtualForOfDirective( this.viewContainerRef, this.templateRef, this.iterableDiffers, @@ -309,7 +315,7 @@ export class ClrDatagridVirtualScrollDirective implements AfterViewInit, DoCh datagridRowsElement.style.height = `${totalContentSize - topOffset}px`; } - const virtualScrollViewport = new CdkVirtualScrollViewport( + const virtualScrollViewport = createCdkVirtualScrollViewport( datagridDivElementRef, changeDetectorRef, ngZone, @@ -340,3 +346,83 @@ export class ClrDatagridVirtualScrollDirective implements AfterViewInit, DoCh return virtualScrollViewport; } } + +function createCdkVirtualScrollViewport( + datagridDivElementRef: ElementRef, + changeDetectorRef: ChangeDetectorRef, + ngZone: NgZone, + virtualScrollStrategy: VirtualScrollStrategy, + directionality: Directionality, + scrollDispatcher: ScrollDispatcher, + viewportRuler: ViewportRuler, + scrollable: CdkVirtualScrollable +) { + if (+ANGULAR_VERSION.major < 19) { + return new CdkVirtualScrollViewport( + datagridDivElementRef, + changeDetectorRef, + ngZone, + virtualScrollStrategy, + directionality, + scrollDispatcher, + viewportRuler, + scrollable + ); + } else { + const virtualScrollViewportInjector = Injector.create({ + parent: inject(EnvironmentInjector), + providers: [ + { provide: ElementRef, useValue: datagridDivElementRef }, + { provide: ChangeDetectorRef, useValue: changeDetectorRef }, + { provide: NgZone, useValue: ngZone }, + { provide: VIRTUAL_SCROLL_STRATEGY, useValue: virtualScrollStrategy }, + { provide: Directionality, useValue: directionality }, + { provide: ScrollDispatcher, useValue: scrollDispatcher }, + { provide: ViewportRuler, useValue: viewportRuler }, + { provide: CdkVirtualScrollable, useValue: scrollable }, + { provide: CdkVirtualScrollViewport, useClass: CdkVirtualScrollViewport }, + ], + }); + + return virtualScrollViewportInjector.get(CdkVirtualScrollViewport); + } +} + +function createCdkVirtualForOfDirective( + viewContainerRef: ViewContainerRef, + templateRef: TemplateRef>, + iterableDiffers: IterableDiffers, + viewRepeater: _RecycleViewRepeaterStrategy>, + virtualScrollViewport: CdkVirtualScrollViewport, + ngZone: NgZone +) { + if (+ANGULAR_VERSION.major < 19) { + return new CdkVirtualForOf( + viewContainerRef, + templateRef, + iterableDiffers, + viewRepeater, + virtualScrollViewport, + ngZone + ); + } else { + const virtualScrollViewportInjector = Injector.create({ + parent: inject(EnvironmentInjector), + providers: [{ provide: CdkVirtualScrollViewport, useValue: virtualScrollViewport }], + }); + + const cdkVirtualForInjector = Injector.create({ + parent: virtualScrollViewportInjector, + providers: [ + { provide: ViewContainerRef, useValue: viewContainerRef }, + { provide: TemplateRef, useValue: templateRef }, + { provide: IterableDiffers, useValue: iterableDiffers }, + { provide: _VIEW_REPEATER_STRATEGY, useValue: viewRepeater }, + { provide: NgZone, useValue: ngZone }, + { provide: CdkVirtualForOf, useClass: CdkVirtualForOf }, + ], + }); + + return cdkVirtualForInjector.get(CdkVirtualForOf); + } +}