Skip to content

Commit 46915d8

Browse files
authored
Merge branch '20.1.x' into mpopov/calendar/fix/issue-1858-20.1.x
2 parents 4a8c315 + 8ef93bd commit 46915d8

File tree

8 files changed

+79
-35
lines changed

8 files changed

+79
-35
lines changed

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
"@types/source-map": "0.5.2",
7676
"express": "^5.1.0",
7777
"fflate": "^0.8.1",
78-
"igniteui-theming": "^21.0.0",
78+
"igniteui-theming": "^21.0.2",
7979
"igniteui-trial-watermark": "^3.1.0",
8080
"lodash-es": "^4.17.21",
8181
"rxjs": "^7.8.2",

projects/igniteui-angular/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
"tslib": "^2.3.0",
7474
"igniteui-trial-watermark": "^3.1.0",
7575
"lodash-es": "^4.17.21",
76-
"igniteui-theming": "^21.0.0",
76+
"igniteui-theming": "^21.0.2",
7777
"@igniteui/material-icons-extended": "^3.1.0"
7878
},
7979
"peerDependencies": {

projects/igniteui-angular/src/lib/directives/input/input.directive.spec.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,22 @@ describe('IgxInput', () => {
908908

909909
expect(formControl.touched).toBe(true);
910910
}));
911+
912+
it('should update validity when control is marked as touched', fakeAsync(() => {
913+
const fixture = TestBed.createComponent(ReactiveFormComponent);
914+
fixture.detectChanges();
915+
916+
const component = fixture.componentInstance;
917+
const igxInput = component.strIgxInput;
918+
919+
expect(igxInput.valid).toBe(IgxInputState.INITIAL);
920+
921+
component.markAllAsTouched();
922+
tick();
923+
fixture.detectChanges();
924+
925+
expect(igxInput.valid).toBe(IgxInputState.INVALID);
926+
}));
911927
});
912928

913929
@Component({
@@ -1201,6 +1217,12 @@ class ReactiveFormComponent {
12011217
this.textareaControl.markAsTouched();
12021218
this.textareaControl.updateValueAndValidity();
12031219
}
1220+
1221+
public markAllAsTouched() {
1222+
if (!this.form.valid) {
1223+
this.form.markAllAsTouched();
1224+
}
1225+
}
12041226
}
12051227

12061228
@Component({

projects/igniteui-angular/src/lib/directives/input/input.directive.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ import {
1616
import {
1717
AbstractControl,
1818
NgControl,
19-
NgModel
19+
NgModel,
20+
TouchedChangeEvent
2021
} from '@angular/forms';
21-
import { Subscription } from 'rxjs';
22+
import { filter, Subscription } from 'rxjs';
2223
import { IgxInputGroupBase } from '../../input-group/input-group.common';
2324

2425
const nativeValidationAttributes = [
@@ -100,6 +101,7 @@ export class IgxInputDirective implements AfterViewInit, OnDestroy {
100101
private _valid = IgxInputState.INITIAL;
101102
private _statusChanges$: Subscription;
102103
private _valueChanges$: Subscription;
104+
private _touchedChanges$: Subscription;
103105
private _fileNames: string;
104106
private _disabled = false;
105107

@@ -313,6 +315,14 @@ export class IgxInputDirective implements AfterViewInit, OnDestroy {
313315
this._valueChanges$ = this.ngControl.valueChanges.subscribe(
314316
this.onValueChanged.bind(this)
315317
);
318+
319+
if (this.ngControl.control) {
320+
this._touchedChanges$ = this.ngControl.control.events
321+
.pipe(filter(e => e instanceof TouchedChangeEvent))
322+
.subscribe(
323+
this.updateValidityState.bind(this)
324+
);
325+
}
316326
}
317327

318328
this.cdr.detectChanges();
@@ -326,6 +336,10 @@ export class IgxInputDirective implements AfterViewInit, OnDestroy {
326336
if (this._valueChanges$) {
327337
this._valueChanges$.unsubscribe();
328338
}
339+
340+
if (this._touchedChanges$) {
341+
this._touchedChanges$.unsubscribe();
342+
}
329343
}
330344
/**
331345
* Sets a focus on the igxInput.

projects/igniteui-angular/src/lib/expansion-panel/expansion-panel.spec.ts

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
import { Component, ViewChild } from '@angular/core';
2+
import { Component, DebugElement, ViewChild } from '@angular/core';
33
import { TestBed, ComponentFixture, tick, fakeAsync, waitForAsync } from '@angular/core/testing';
44
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
55
import { IgxExpansionPanelComponent } from './expansion-panel.component';
@@ -296,13 +296,17 @@ describe('igxExpansionPanel', () => {
296296
panel: IgxExpansionPanelComponent,
297297
panelContainer: any,
298298
panelHeader: HTMLElement,
299-
button: HTMLElement,
299+
button: DebugElement,
300300
timesCollapsed = 0,
301301
timesExpanded = 0) => {
302302
expect(panel.collapsed).toEqual(collapsed);
303303
const ariaExpanded = collapsed ? 'false' : 'true';
304304
expect(panelHeader.querySelector('div [role = \'button\']').getAttribute('aria-expanded')).toMatch(ariaExpanded);
305305
expect(panelHeader.classList.contains(CSS_CLASS_HEADER_EXPANDED)).toEqual(!collapsed);
306+
if (button.children.length > 1) {
307+
const iconName = collapsed ? 'expand_more' : 'expand_less';
308+
expect(button.componentInstance.iconName).toMatch(iconName);
309+
}
306310
if (collapsed) {
307311
expect(panelContainer.lastElementChild.nodeName).toEqual('IGX-EXPANSION-PANEL-HEADER');
308312
} else {
@@ -322,7 +326,7 @@ describe('igxExpansionPanel', () => {
322326
const header = fixture.componentInstance.header;
323327
const panelContainer = fixture.nativeElement.querySelector('.' + CSS_CLASS_EXPANSION_PANEL);
324328
const panelHeader = fixture.nativeElement.querySelector('.' + CSS_CLASS_PANEL_HEADER) as HTMLElement;
325-
const button = fixture.nativeElement.querySelector('.' + CSS_CLASS_PANEL_ICON) as HTMLElement;
329+
const button = fixture.debugElement.query(By.css('.' + CSS_CLASS_PANEL_ICON)) as DebugElement;
326330

327331
let timesCollapsed = 0;
328332
let timesExpanded = 0;
@@ -383,7 +387,7 @@ describe('igxExpansionPanel', () => {
383387
const header = fixture.componentInstance.header;
384388
const panelContainer = fixture.nativeElement.querySelector('.' + CSS_CLASS_EXPANSION_PANEL);
385389
const panelHeader = fixture.nativeElement.querySelector('.' + CSS_CLASS_PANEL_HEADER) as HTMLElement;
386-
let button = fixture.nativeElement.querySelector('.' + CSS_CLASS_PANEL_ICON) as HTMLElement;
390+
let button = fixture.debugElement.query(By.css('.' + CSS_CLASS_PANEL_ICON)) as DebugElement;
387391

388392
let timesCollapsed = 0;
389393
let timesExpanded = 0;
@@ -392,23 +396,23 @@ describe('igxExpansionPanel', () => {
392396
spyOn(header.interaction, 'emit');
393397
verifyPanelExpansionState(true, panel, panelContainer, panelHeader, button, timesCollapsed, timesExpanded);
394398

395-
button.click();
399+
button.nativeElement.click()
396400
tick();
397401
fixture.detectChanges();
398402
tick();
399403
timesExpanded++;
400404
verifyPanelExpansionState(false, panel, panelContainer, panelHeader, button, timesCollapsed, timesExpanded);
401405
expect(header.interaction.emit).toHaveBeenCalledTimes(1);
402406

403-
button.click();
407+
button.nativeElement.click()
404408
tick();
405409
fixture.detectChanges();
406410
tick();
407411
timesCollapsed++;
408412
verifyPanelExpansionState(true, panel, panelContainer, panelHeader, button, timesCollapsed, timesExpanded);
409413
expect(header.interaction.emit).toHaveBeenCalledTimes(2);
410414

411-
button.click();
415+
button.nativeElement.click()
412416
tick();
413417
fixture.detectChanges();
414418
tick();
@@ -422,24 +426,24 @@ describe('igxExpansionPanel', () => {
422426
fixture.detectChanges();
423427
tick();
424428

425-
button = fixture.nativeElement.querySelector('.' + CSS_CLASS_PANEL_ICON) as HTMLElement;
426-
button.click();
429+
button = fixture.debugElement.query(By.css('.' + CSS_CLASS_PANEL_ICON)) as DebugElement;
430+
button.nativeElement.click()
427431
tick();
428432
fixture.detectChanges();
429433
tick();
430434
timesCollapsed++;
431435
verifyPanelExpansionState(true, panel, panelContainer, panelHeader, button, timesCollapsed, timesExpanded);
432436
expect(header.interaction.emit).toHaveBeenCalledTimes(4);
433437

434-
button.click();
438+
button.nativeElement.click()
435439
tick();
436440
fixture.detectChanges();
437441
tick();
438442
timesExpanded++;
439443
verifyPanelExpansionState(false, panel, panelContainer, panelHeader, button, timesCollapsed, timesExpanded);
440444
expect(header.interaction.emit).toHaveBeenCalledTimes(5);
441445

442-
button.click();
446+
button.nativeElement.click()
443447
tick();
444448
fixture.detectChanges();
445449
tick();
@@ -453,7 +457,7 @@ describe('igxExpansionPanel', () => {
453457
const panel = fixture.componentInstance.expansionPanel;
454458
const panelContainer = fixture.nativeElement.querySelector('.' + CSS_CLASS_EXPANSION_PANEL);
455459
const panelHeader = fixture.nativeElement.querySelector('.' + CSS_CLASS_PANEL_HEADER) as HTMLElement;
456-
const button = fixture.nativeElement.querySelector('.' + CSS_CLASS_PANEL_ICON) as HTMLElement;
460+
const button = fixture.debugElement.query(By.css('.' + CSS_CLASS_PANEL_ICON)) as DebugElement;
457461
spyOn(panel.contentCollapsed, 'emit').and.callThrough();
458462
spyOn(panel.contentExpanded, 'emit').and.callThrough();
459463
verifyPanelExpansionState(true, panel, panelContainer, panelHeader, button);
@@ -482,7 +486,7 @@ describe('igxExpansionPanel', () => {
482486
const panel = fixture.componentInstance.expansionPanel;
483487
const panelContainer = fixture.nativeElement.querySelector('.' + CSS_CLASS_EXPANSION_PANEL);
484488
const panelHeader = fixture.nativeElement.querySelector('.' + CSS_CLASS_PANEL_HEADER) as HTMLElement;
485-
const button = fixture.nativeElement.querySelector('.' + CSS_CLASS_PANEL_ICON) as HTMLElement;
489+
const button = fixture.debugElement.query(By.css('.' + CSS_CLASS_PANEL_ICON)) as DebugElement;
486490

487491
let timesCollapsed = 0;
488492
let timesExpanded = 0;
@@ -524,7 +528,7 @@ describe('igxExpansionPanel', () => {
524528
const panel = fixture.componentInstance.expansionPanel;
525529
const panelContainer = fixture.nativeElement.querySelector('.' + CSS_CLASS_EXPANSION_PANEL);
526530
const panelHeader = fixture.nativeElement.querySelector('.' + CSS_CLASS_PANEL_HEADER) as HTMLElement;
527-
const button = fixture.nativeElement.querySelector('.' + CSS_CLASS_PANEL_ICON) as HTMLElement;
531+
const button = fixture.debugElement.query(By.css('.' + CSS_CLASS_PANEL_ICON)) as DebugElement;
528532

529533
let timesCollapsed = 0;
530534
let timesExpanded = 0;
@@ -571,7 +575,7 @@ describe('igxExpansionPanel', () => {
571575
const header = fixture.componentInstance.header;
572576
const panelContainer = fixture.nativeElement.querySelector('.' + CSS_CLASS_EXPANSION_PANEL);
573577
const panelHeader = fixture.nativeElement.querySelector('.' + CSS_CLASS_PANEL_HEADER) as HTMLElement;
574-
const button = fixture.nativeElement.querySelector('.' + CSS_CLASS_PANEL_ICON) as HTMLElement;
578+
const button = fixture.debugElement.query(By.css('.' + CSS_CLASS_PANEL_ICON)) as DebugElement;
575579

576580
let timesCollapsed = 0;
577581
let timesExpanded = 0;
@@ -684,7 +688,7 @@ describe('igxExpansionPanel', () => {
684688
const header = fixture.componentInstance.header;
685689
const panelContainer = fixture.nativeElement.querySelector('.' + CSS_CLASS_EXPANSION_PANEL);
686690
const panelHeader = fixture.nativeElement.querySelector('.' + CSS_CLASS_PANEL_HEADER) as HTMLElement;
687-
const button = fixture.nativeElement.querySelector('.' + CSS_CLASS_PANEL_ICON) as HTMLElement;
691+
const button = fixture.debugElement.query(By.css('.' + CSS_CLASS_PANEL_ICON)) as DebugElement;
688692

689693
let timesCollapsed = 0;
690694
let timesExpanded = 0;
@@ -708,7 +712,7 @@ describe('igxExpansionPanel', () => {
708712
verifyPanelExpansionState(true, panel, panelContainer, panelHeader, button, timesCollapsed, timesExpanded);
709713
expect(header.interaction.emit).toHaveBeenCalledTimes(1);
710714

711-
button.click();
715+
button.nativeElement.click()
712716
tick();
713717
fixture.detectChanges();
714718
tick();
@@ -759,7 +763,7 @@ describe('igxExpansionPanel', () => {
759763
const header = fixture.componentInstance.header;
760764
const panelContainer = fixture.nativeElement.querySelector('.' + CSS_CLASS_EXPANSION_PANEL);
761765
const panelHeader = fixture.nativeElement.querySelector('.' + CSS_CLASS_PANEL_HEADER) as HTMLElement;
762-
const button = fixture.nativeElement.querySelector('.' + CSS_CLASS_PANEL_ICON) as HTMLElement;
766+
const button = fixture.debugElement.query(By.css('.' + CSS_CLASS_PANEL_ICON)) as DebugElement;
763767
const headerButton = panelHeader.querySelector('div [role = \'button\']');
764768

765769
let timesCollapsed = 0;
@@ -788,7 +792,7 @@ describe('igxExpansionPanel', () => {
788792
verifyPanelExpansionState(false, panel, panelContainer, panelHeader, button, timesCollapsed, timesExpanded);
789793
expect(header.interaction.emit).toHaveBeenCalledTimes(0);
790794

791-
button.click();
795+
button.nativeElement.click()
792796
tick();
793797
fixture.detectChanges();
794798
tick();
@@ -817,7 +821,7 @@ describe('igxExpansionPanel', () => {
817821
verifyPanelExpansionState(true, panel, panelContainer, panelHeader, button, timesCollapsed, timesExpanded);
818822
expect(header.interaction.emit).toHaveBeenCalledTimes(0);
819823

820-
button.click();
824+
button.nativeElement.click()
821825
tick();
822826
fixture.detectChanges();
823827
tick();

projects/igniteui-angular/src/lib/grids/grid/cell.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ describe('IgxGrid - Cell component #grid', () => {
151151
});
152152
});
153153

154-
xdescribe('Cells in virtualized grid ', () => {
154+
describe('Cells in virtualized grid ', () => {
155155
let fix;
156156
let grid: IgxGridComponent;
157157

@@ -260,8 +260,8 @@ describe('IgxGrid - Cell component #grid', () => {
260260

261261
const gridContent = GridFunctions.getGridContent(fix);
262262
UIInteractions.triggerEventHandlerKeyDown('arrowup', gridContent);
263+
await wait(16);
263264
fix.detectChanges();
264-
await wait(30);
265265

266266
expect(grid.getCellByColumn(2, 'value').selected).toBeTruthy();
267267
}));

projects/igniteui-angular/src/lib/query-builder/query-builder.component.spec.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { waitForAsync, TestBed, ComponentFixture, fakeAsync, tick, flush } from '@angular/core/testing';
2-
import { FilteringExpressionsTree, FilteringLogic, IExpressionTree, IgxChipComponent, IgxComboComponent, IgxDateFilteringOperand, IgxNumberFilteringOperand, IgxQueryBuilderComponent, IgxQueryBuilderHeaderComponent, IgxQueryBuilderSearchValueTemplateDirective } from 'igniteui-angular';
2+
import { FilteringExpressionsTree, FilteringLogic, IExpressionTree, IgxChipComponent, IgxComboComponent, IgxDateFilteringOperand, IgxIconComponent, IgxInputGroupComponent, IgxNumberFilteringOperand, IgxQueryBuilderComponent, IgxQueryBuilderHeaderComponent, IgxQueryBuilderSearchValueTemplateDirective, IgxSelectComponent } from 'igniteui-angular';
33
import { Component, OnInit, ViewChild } from '@angular/core';
44
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
55
import { By } from '@angular/platform-browser';
@@ -837,8 +837,10 @@ describe('IgxQueryBuilder', () => {
837837
QueryBuilderFunctions.selectOperatorInEditModeExpression(fix, 10); // Select 'In' operator.
838838

839839
// Verify operator icon
840-
// const operatorInputGroup = QueryBuilderFunctions.getQueryBuilderOperatorSelect(fix).querySelector('igx-input-group') as HTMLElement;
841-
// expect(operatorInputGroup.querySelector('igx-icon').attributes.getNamedItem('ng-reflect-name').nodeValue).toEqual('in');
840+
const operatorSelectDebugElement = fix.debugElement.queryAll(By.directive(IgxSelectComponent))[2];
841+
const inputDebugElement = operatorSelectDebugElement.query(By.directive(IgxInputGroupComponent));
842+
const iconDebugElem = inputDebugElement.query(By.directive(IgxIconComponent));
843+
expect(iconDebugElem.componentInstance.name).toEqual('in');
842844

843845
const input = QueryBuilderFunctions.getQueryBuilderValueInput(fix).querySelector('input');
844846
// Verify value input placeholder
@@ -914,8 +916,10 @@ describe('IgxQueryBuilder', () => {
914916
QueryBuilderFunctions.selectOperatorInEditModeExpression(fix, 11); // Select 'Not-In' operator.
915917

916918
// Verify operator icon
917-
// const operatorInputGroup = QueryBuilderFunctions.getQueryBuilderOperatorSelect(fix).querySelector('igx-input-group') as HTMLElement;
918-
// expect(operatorInputGroup.querySelector('igx-icon').attributes.getNamedItem('ng-reflect-name').nodeValue).toEqual('not-in');
919+
const operatorSelectDebugElement = fix.debugElement.queryAll(By.directive(IgxSelectComponent))[2];
920+
const inputDebugElement = operatorSelectDebugElement.query(By.directive(IgxInputGroupComponent));
921+
const iconDebugElem = inputDebugElement.query(By.directive(IgxIconComponent));
922+
expect(iconDebugElem.componentInstance.name).toEqual('not-in');
919923

920924
const input = QueryBuilderFunctions.getQueryBuilderValueInput(fix).querySelector('input');
921925
// Verify value input placeholder

0 commit comments

Comments
 (0)