Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, ViewChild, ChangeDetectionStrategy } from '@angular/core';
import { Component, ViewChild, ChangeDetectionStrategy, provideZonelessChangeDetection, signal } from '@angular/core';
import { TestBed, fakeAsync, tick, waitForAsync } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
Expand Down Expand Up @@ -691,3 +691,59 @@ class PositionSettingsDialogComponent {
};

}

@Component({
template: `
<igx-dialog #dialog title="dialog" message="message" [isOpen]="open()"></igx-dialog>`,
changeDetection: ChangeDetectionStrategy.Eager,
imports: [IgxDialogComponent]
})
class ZonelessDialogHostComponent {
@ViewChild('dialog', { static: true }) public dialog: IgxDialogComponent;
public readonly open = signal(false);
}

describe('Dialog - zoneless change detection', () => {
const DIALOG_WINDOW = '.igx-dialog__window';

const nextFrame = () => new Promise<void>((resolve) => requestAnimationFrame(() => resolve()));

beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [NoopAnimationsModule, ZonelessDialogHostComponent],
providers: [provideZonelessChangeDetection()]
}).compileComponents();
}));

afterEach(() => {
UIInteractions.clearOverlay();
});

it('renders the dialog when isOpen is set from an asynchronous callback', async () => {
const fixture = TestBed.createComponent(ZonelessDialogHostComponent);
fixture.detectChanges();

const host = fixture.debugElement.query(By.css('igx-dialog')).nativeElement as HTMLElement;
const dialog = fixture.componentInstance.dialog;

await new Promise<void>(resolve => {
setTimeout(() => {
fixture.componentInstance.open.set(true);
resolve();
});
});
await fixture.whenStable();
await nextFrame();
await fixture.whenStable();

const dialogWindow = document.querySelector<HTMLElement>(DIALOG_WINDOW);
expect(dialog.isOpen).toBeTrue();
expect(dialog.isCollapsed).toBeFalse();
expect(dialogWindow).withContext('dialog window is in the DOM').not.toBeNull();
expect(dialogWindow?.getClientRects().length ?? 0)
.withContext('dialog window is actually rendered').toBeGreaterThan(0);
expect(host.classList.contains('igx-dialog--hidden'))
.withContext('host class mirrors isCollapsed')
.toBeFalse();
});
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, ElementRef, EventEmitter, HostBinding, Input, OnDestroy, OnInit, Output, ViewChild, AfterContentInit, booleanAttribute, inject, ChangeDetectionStrategy } from '@angular/core';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, HostBinding, Input, OnDestroy, OnInit, Output, ViewChild, AfterContentInit, booleanAttribute, inject } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { IgxNavigationService, IToggleView } from 'igniteui-angular/core';
Expand Down Expand Up @@ -46,6 +46,7 @@ let DIALOG_ID = 0;
imports: [IgxToggleDirective, IgxFocusTrapDirective, IgxFocusDirective, IgxButtonDirective, IgxRippleDirective]
})
export class IgxDialogComponent implements IToggleView, OnInit, OnDestroy, AfterContentInit {
private cdr = inject(ChangeDetectorRef);
private elementRef = inject(ElementRef);
private navService = inject(IgxNavigationService, { optional: true });

Expand Down Expand Up @@ -370,6 +371,7 @@ export class IgxDialogComponent implements IToggleView, OnInit, OnDestroy, After
if (value) {
requestAnimationFrame(() => {
this.open();
this.cdr.markForCheck();
});
} else {
this.close();
Expand Down
Loading