|
1 | | -import { Component, ViewChild, ChangeDetectionStrategy } from '@angular/core'; |
| 1 | +import { Component, ViewChild, ChangeDetectionStrategy, provideZonelessChangeDetection, signal } from '@angular/core'; |
2 | 2 | import { TestBed, fakeAsync, tick, waitForAsync } from '@angular/core/testing'; |
3 | 3 | import { By } from '@angular/platform-browser'; |
4 | 4 | import { NoopAnimationsModule } from '@angular/platform-browser/animations'; |
@@ -691,3 +691,59 @@ class PositionSettingsDialogComponent { |
691 | 691 | }; |
692 | 692 |
|
693 | 693 | } |
| 694 | + |
| 695 | +@Component({ |
| 696 | + template: ` |
| 697 | + <igx-dialog #dialog title="dialog" message="message" [isOpen]="open()"></igx-dialog>`, |
| 698 | + changeDetection: ChangeDetectionStrategy.Eager, |
| 699 | + imports: [IgxDialogComponent] |
| 700 | +}) |
| 701 | +class ZonelessDialogHostComponent { |
| 702 | + @ViewChild('dialog', { static: true }) public dialog: IgxDialogComponent; |
| 703 | + public readonly open = signal(false); |
| 704 | +} |
| 705 | + |
| 706 | +describe('Dialog - zoneless change detection', () => { |
| 707 | + const DIALOG_WINDOW = '.igx-dialog__window'; |
| 708 | + |
| 709 | + const nextFrame = () => new Promise<void>((resolve) => requestAnimationFrame(() => resolve())); |
| 710 | + |
| 711 | + beforeEach(waitForAsync(() => { |
| 712 | + TestBed.configureTestingModule({ |
| 713 | + imports: [NoopAnimationsModule, ZonelessDialogHostComponent], |
| 714 | + providers: [provideZonelessChangeDetection()] |
| 715 | + }).compileComponents(); |
| 716 | + })); |
| 717 | + |
| 718 | + afterEach(() => { |
| 719 | + UIInteractions.clearOverlay(); |
| 720 | + }); |
| 721 | + |
| 722 | + it('renders the dialog when isOpen is set from an asynchronous callback', async () => { |
| 723 | + const fixture = TestBed.createComponent(ZonelessDialogHostComponent); |
| 724 | + fixture.detectChanges(); |
| 725 | + |
| 726 | + const host = fixture.debugElement.query(By.css('igx-dialog')).nativeElement as HTMLElement; |
| 727 | + const dialog = fixture.componentInstance.dialog; |
| 728 | + |
| 729 | + await new Promise<void>(resolve => { |
| 730 | + setTimeout(() => { |
| 731 | + fixture.componentInstance.open.set(true); |
| 732 | + resolve(); |
| 733 | + }); |
| 734 | + }); |
| 735 | + await fixture.whenStable(); |
| 736 | + await nextFrame(); |
| 737 | + await fixture.whenStable(); |
| 738 | + |
| 739 | + const dialogWindow = document.querySelector<HTMLElement>(DIALOG_WINDOW); |
| 740 | + expect(dialog.isOpen).toBeTrue(); |
| 741 | + expect(dialog.isCollapsed).toBeFalse(); |
| 742 | + expect(dialogWindow).withContext('dialog window is in the DOM').not.toBeNull(); |
| 743 | + expect(dialogWindow?.getClientRects().length ?? 0) |
| 744 | + .withContext('dialog window is actually rendered').toBeGreaterThan(0); |
| 745 | + expect(host.classList.contains('igx-dialog--hidden')) |
| 746 | + .withContext('host class mirrors isCollapsed') |
| 747 | + .toBeFalse(); |
| 748 | + }); |
| 749 | +}); |
0 commit comments