Skip to content

Commit c7e8788

Browse files
refactor(overlay): consecutevly close overlays on escape keypress
- set closeOnEsc to false by default
1 parent 9245798 commit c7e8788

File tree

7 files changed

+45
-44
lines changed

7 files changed

+45
-44
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ All notable changes for each version of this project will be documented in this
88
- `igxCombo`
99
- **Behavioral Change** - Change default positioning strategy from `ConnectedPositioningStrategy` to `AutoPositionStrategy`. The [`Auto`](https://www.infragistics.com/products/ignite-ui-angular/angular/components/overlay_position.html#auto) strategy will initially try to show the element like the Connected strategy does. If the element goes out of the viewport Auto will flip the starting point and the direction, i.e. if the direction is 'bottom', it will switch it to 'top' and so on. If after flipping direction the content goes out of the view, auto strategy will revert to initial start point and direction and will push the content into the view. Note after pushing the content it may hide the combo's input.
1010
- `IgxOverlay`
11-
- Added new property - `closeOnEsc` - in `OverlaySettings`. The overlay can now be prevented from closing, on escape keypress, by setting the property to `false`, by default it's `true`.
11+
- Added new property - `closeOnEsc` - in `OverlaySettings`. The overlay can now be prevented from closing, on escape keypress, by setting the property to `false`, it is `false` by default.
1212
- `igxDialog`
1313
- Added `closeOnEscapeKey` - with it, the dialog can be allowed or prevented from closing when `Esc` is pressed.
1414
- `IgxNavbar`:

projects/igniteui-angular/src/lib/date-picker/date-picker.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -783,8 +783,8 @@ export class IgxDatePickerComponent implements IDatePicker, ControlValueAccessor
783783

784784
this._modalOverlaySettings = {
785785
closeOnOutsideClick: true,
786-
closeOnEsc: true,
787786
modal: true,
787+
closeOnEsc: true,
788788
outlet: this.outlet
789789
};
790790

projects/igniteui-angular/src/lib/dialog/dialog.component.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ export class IgxDialogComponent implements IToggleView, OnInit, OnDestroy, After
8383
this._isModal = val;
8484
}
8585

86+
@Input()
8687
get closeOnEscapeKey() {
8788
return this._closeOnEscapeKey;
8889
}

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,6 @@ describe('IgxToggle', () => {
475475
positionStrategy: jasmine.any(ConnectedPositioningStrategy) as any,
476476
closeOnOutsideClick: true,
477477
modal: false,
478-
closeOnEsc: true,
479478
scrollStrategy: jasmine.any(AbsoluteScrollStrategy) as any,
480479
excludePositionTarget: true
481480
};
@@ -499,7 +498,6 @@ describe('IgxToggle', () => {
499498
positionStrategy: jasmine.any(ConnectedPositioningStrategy) as any,
500499
closeOnOutsideClick: true,
501500
modal: false,
502-
closeOnEsc: true,
503501
scrollStrategy: jasmine.any(AbsoluteScrollStrategy) as any,
504502
excludePositionTarget: true
505503
};
@@ -535,7 +533,6 @@ describe('IgxToggle', () => {
535533
positionStrategy: jasmine.any(ConnectedPositioningStrategy) as any,
536534
closeOnOutsideClick: true,
537535
modal: false,
538-
closeOnEsc: true,
539536
scrollStrategy: jasmine.any(AbsoluteScrollStrategy) as any,
540537
excludePositionTarget: true
541538
};
@@ -594,7 +591,6 @@ describe('IgxToggle', () => {
594591
positionStrategy: jasmine.any(ConnectedPositioningStrategy) as any,
595592
closeOnOutsideClick: true,
596593
modal: false,
597-
closeOnEsc: true,
598594
scrollStrategy: jasmine.any(AbsoluteScrollStrategy) as any,
599595
outlet: jasmine.any(IgxOverlayOutletDirective) as any,
600596
excludePositionTarget: true

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,6 @@ export class IgxToggleActionDirective implements OnInit {
429429
scrollStrategy: new AbsoluteScrollStrategy(),
430430
closeOnOutsideClick: true,
431431
modal: false,
432-
closeOnEsc: true,
433432
excludePositionTarget: true
434433
};
435434
}

projects/igniteui-angular/src/lib/services/overlay/overlay.spec.ts

Lines changed: 27 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -216,16 +216,15 @@ describe('igxOverlay', () => {
216216

217217
overlay.show(overlay.attach(SimpleDynamicComponent), {
218218
outlet: button,
219-
modal: false,
220-
closeOnEsc: false
219+
modal: false
221220
});
222221
tick();
223222
let wrapper = document.getElementsByClassName(CLASS_OVERLAY_WRAPPER)[0];
224223
expect(wrapper).toBeDefined();
225224
expect(wrapper.parentNode).toBe(button.nativeElement);
226225
overlay.hideAll();
227226

228-
overlay.show(overlay.attach(SimpleDynamicComponent), { modal: false, closeOnEsc: false });
227+
overlay.show(overlay.attach(SimpleDynamicComponent), { modal: false });
229228
tick();
230229
wrapper = document.getElementsByClassName(CLASS_OVERLAY_WRAPPER)[0];
231230
expect(wrapper).toBeDefined();
@@ -237,7 +236,6 @@ describe('igxOverlay', () => {
237236
fixture.debugElement.nativeElement.appendChild(outlet);
238237
overlay.show(overlay.attach(SimpleDynamicComponent), {
239238
modal: false,
240-
closeOnEsc: false,
241239
outlet: new IgxOverlayOutletDirective(new ElementRef(outlet))
242240
});
243241
tick();
@@ -688,7 +686,6 @@ describe('igxOverlay', () => {
688686
tick();
689687

690688
fix.componentInstance.overlaySettings.outlet = fix.componentInstance.elementRef;
691-
fix.componentInstance.overlaySettings.closeOnEsc = false;
692689

693690
const buttonElement: HTMLElement = fix.componentInstance.buttonElement.nativeElement;
694691
buttonElement.click();
@@ -1078,7 +1075,6 @@ describe('igxOverlay', () => {
10781075
positionStrategy: new GlobalPositionStrategy(),
10791076
scrollStrategy: new NoOpScrollStrategy(),
10801077
modal: false,
1081-
closeOnEsc: false,
10821078
closeOnOutsideClick: false
10831079
};
10841080
const positionSettings: PositionSettings = {
@@ -1305,7 +1301,6 @@ describe('igxOverlay', () => {
13051301
positionStrategy: new GlobalPositionStrategy(),
13061302
scrollStrategy: new NoOpScrollStrategy(),
13071303
modal: false,
1308-
closeOnEsc: false,
13091304
closeOnOutsideClick: false
13101305
};
13111306
const positionSettings: PositionSettings = {
@@ -1332,7 +1327,6 @@ describe('igxOverlay', () => {
13321327
positionStrategy: new GlobalPositionStrategy(),
13331328
scrollStrategy: new NoOpScrollStrategy(),
13341329
modal: false,
1335-
closeOnEsc: false,
13361330
closeOnOutsideClick: false
13371331
};
13381332
overlaySettings.positionStrategy = new ConnectedPositioningStrategy();
@@ -1460,7 +1454,6 @@ describe('igxOverlay', () => {
14601454
positionStrategy: new GlobalPositionStrategy(),
14611455
scrollStrategy: scrollStrat,
14621456
modal: false,
1463-
closeOnEsc: false,
14641457
closeOnOutsideClick: false
14651458
};
14661459
const overlay = fixture.componentInstance.overlay;
@@ -1490,7 +1483,6 @@ describe('igxOverlay', () => {
14901483
positionStrategy: new ConnectedPositioningStrategy(),
14911484
scrollStrategy: scrollStrat,
14921485
modal: false,
1493-
closeOnEsc: false,
14941486
closeOnOutsideClick: false
14951487
};
14961488
const buttonElement = fixture.componentInstance.buttonElement.nativeElement;
@@ -1668,7 +1660,6 @@ describe('igxOverlay', () => {
16681660
positionStrategy: new AutoPositionStrategy(),
16691661
scrollStrategy: new NoOpScrollStrategy(),
16701662
modal: false,
1671-
closeOnEsc: false,
16721663
closeOnOutsideClick: false
16731664
};
16741665

@@ -1697,7 +1688,6 @@ describe('igxOverlay', () => {
16971688
positionStrategy: new GlobalPositionStrategy(),
16981689
scrollStrategy: new NoOpScrollStrategy(),
16991690
modal: false,
1700-
closeOnEsc: false,
17011691
closeOnOutsideClick: false
17021692
};
17031693
const positionSettings: PositionSettings = {
@@ -1943,7 +1933,6 @@ describe('igxOverlay', () => {
19431933
positionStrategy: new AutoPositionStrategy(positionSettings),
19441934
scrollStrategy: new NoOpScrollStrategy(),
19451935
modal: false,
1946-
closeOnEsc: false,
19471936
closeOnOutsideClick: false
19481937
};
19491938
const hAlignmentArray = Object.keys(HorizontalAlignment).filter(key => !isNaN(Number(HorizontalAlignment[key])));
@@ -2000,7 +1989,6 @@ describe('igxOverlay', () => {
20001989
positionStrategy: new AutoPositionStrategy(positionSettings),
20011990
scrollStrategy: new NoOpScrollStrategy(),
20021991
modal: false,
2003-
closeOnEsc: false,
20041992
closeOnOutsideClick: false
20051993
};
20061994
overlay.show(overlay.attach(SimpleDynamicComponent), overlaySettings);
@@ -2043,7 +2031,6 @@ describe('igxOverlay', () => {
20432031
positionStrategy: new AutoPositionStrategy(positionSettings),
20442032
scrollStrategy: new NoOpScrollStrategy(),
20452033
modal: false,
2046-
closeOnEsc: false,
20472034
closeOnOutsideClick: false
20482035
};
20492036
overlay.show(overlay.attach(SimpleDynamicComponent), overlaySettings);
@@ -2145,7 +2132,6 @@ describe('igxOverlay', () => {
21452132
positionStrategy: new ElasticPositionStrategy(),
21462133
scrollStrategy: new NoOpScrollStrategy(),
21472134
modal: false,
2148-
closeOnEsc: false,
21492135
closeOnOutsideClick: false
21502136
};
21512137

@@ -2174,7 +2160,6 @@ describe('igxOverlay', () => {
21742160
positionStrategy: new GlobalPositionStrategy(),
21752161
scrollStrategy: new NoOpScrollStrategy(),
21762162
modal: false,
2177-
closeOnEsc: false,
21782163
closeOnOutsideClick: false
21792164
};
21802165
const positionSettings: PositionSettings = {
@@ -2438,7 +2423,6 @@ describe('igxOverlay', () => {
24382423
positionStrategy: new ElasticPositionStrategy(positionSettings),
24392424
scrollStrategy: new NoOpScrollStrategy(),
24402425
modal: false,
2441-
closeOnEsc: false,
24422426
closeOnOutsideClick: false
24432427
};
24442428
const hAlignmentArray = Object.keys(HorizontalAlignment).filter(key => !isNaN(Number(HorizontalAlignment[key])));
@@ -2495,7 +2479,6 @@ describe('igxOverlay', () => {
24952479
positionStrategy: new ElasticPositionStrategy(positionSettings),
24962480
scrollStrategy: new NoOpScrollStrategy(),
24972481
modal: false,
2498-
closeOnEsc: false,
24992482
closeOnOutsideClick: false
25002483
};
25012484
overlay.show(overlay.attach(SimpleDynamicComponent), overlaySettings);
@@ -2539,7 +2522,6 @@ describe('igxOverlay', () => {
25392522
positionStrategy: new ElasticPositionStrategy(positionSettings),
25402523
scrollStrategy: new NoOpScrollStrategy(),
25412524
modal: false,
2542-
closeOnEsc: false,
25432525
closeOnOutsideClick: false
25442526
};
25452527
overlay.show(overlay.attach(SimpleDynamicComponent), overlaySettings);
@@ -2766,7 +2748,6 @@ describe('igxOverlay', () => {
27662748
const overlay = fixture.componentInstance.overlay;
27672749
const overlaySettings: OverlaySettings = {
27682750
modal: true,
2769-
closeOnEsc: false,
27702751
positionStrategy: new GlobalPositionStrategy()
27712752
};
27722753
const targetButton = 'Escape';
@@ -2790,6 +2771,27 @@ describe('igxOverlay', () => {
27902771
expect(overlayWrapper).toBeTruthy();
27912772
}));
27922773

2774+
it('Should close the opened overlays consecutively on escape keypress', fakeAsync(() => {
2775+
const fixture = TestBed.createComponent(EmptyPageComponent);
2776+
const overlay = fixture.componentInstance.overlay;
2777+
overlay.show(overlay.attach(SimpleDynamicComponent), { modal: false, closeOnEsc: true });
2778+
tick();
2779+
overlay.show(overlay.attach(SimpleDynamicComponent), { modal: true, closeOnEsc: true });
2780+
tick();
2781+
2782+
const overlayWrapper = document.getElementsByClassName(CLASS_OVERLAY_WRAPPER_MODAL)[0];
2783+
const escEvent = new KeyboardEvent('keydown', {
2784+
key: 'Escape'
2785+
});
2786+
overlayWrapper.dispatchEvent(escEvent);
2787+
tick();
2788+
expect(document.getElementsByClassName(CLASS_OVERLAY_WRAPPER_MODAL)[0]).toBeFalsy();
2789+
2790+
document.dispatchEvent(escEvent);
2791+
tick();
2792+
expect(document.getElementsByClassName(CLASS_OVERLAY_WRAPPER)[0]).toBeFalsy();
2793+
}));
2794+
27932795
// Test #1883 #1820
27942796
it('It should close the component when esc key is pressed and there were other keys pressed prior to esc.', fakeAsync(() => {
27952797
const fixture = TestBed.createComponent(EmptyPageComponent);
@@ -2837,8 +2839,7 @@ describe('igxOverlay', () => {
28372839
const fixture = TestBed.createComponent(EmptyPageComponent);
28382840
const overlay = fixture.componentInstance.overlay;
28392841
const overlaySettings: OverlaySettings = {
2840-
modal: false,
2841-
closeOnEsc: false
2842+
modal: false
28422843
};
28432844

28442845
overlay.show(overlay.attach(SimpleDynamicComponent), overlaySettings);
@@ -2867,7 +2868,6 @@ describe('igxOverlay', () => {
28672868
const overlay = fixture.componentInstance.overlay;
28682869
const overlaySettings: OverlaySettings = {
28692870
modal: false,
2870-
closeOnEsc: false,
28712871
positionStrategy: new GlobalPositionStrategy()
28722872
};
28732873
const targetEvent = 'keydown';
@@ -2986,7 +2986,6 @@ describe('igxOverlay', () => {
29862986
positionStrategy: new ConnectedPositioningStrategy(),
29872987
scrollStrategy: scrollStrat,
29882988
modal: false,
2989-
closeOnEsc: false,
29902989
closeOnOutsideClick: false
29912990
};
29922991
const overlay = fixture.componentInstance.overlay;
@@ -3405,7 +3404,6 @@ describe('igxOverlay', () => {
34053404

34063405
const overlaySettings: OverlaySettings = {
34073406
modal: false,
3408-
closeOnEsc: false
34093407
};
34103408
const overlay = fixture.componentInstance.overlay;
34113409

@@ -3448,7 +3446,6 @@ describe('igxOverlay', () => {
34483446
positionStrategy: new GlobalPositionStrategy(),
34493447
scrollStrategy: scrollStrategy,
34503448
modal: false,
3451-
closeOnEsc: false
34523449
};
34533450

34543451
overlay.show(overlay.attach(SimpleDynamicComponent), overlaySettings);
@@ -3489,7 +3486,6 @@ describe('igxOverlay', () => {
34893486
scrollStrategy: scrollStrategy,
34903487
closeOnOutsideClick: false,
34913488
modal: false,
3492-
closeOnEsc: false
34933489
};
34943490

34953491
overlay.show(overlay.attach(SimpleDynamicComponent), overlaySettings);
@@ -3524,7 +3520,6 @@ describe('igxOverlay', () => {
35243520
positionStrategy: new GlobalPositionStrategy(),
35253521
scrollStrategy: scrollStrategy,
35263522
modal: false,
3527-
closeOnEsc: false
35283523
};
35293524

35303525
overlay.show(overlay.attach(SimpleDynamicComponent), overlaySettings);
@@ -3562,7 +3557,6 @@ describe('igxOverlay', () => {
35623557
const overlay = fixture.componentInstance.overlay;
35633558
const overlaySettings: OverlaySettings = {
35643559
modal: false,
3565-
closeOnEsc: false,
35663560
scrollStrategy: scrollStrategy,
35673561
positionStrategy: new GlobalPositionStrategy()
35683562
};
@@ -3604,7 +3598,6 @@ describe('igxOverlay', () => {
36043598
const overlaySettings: OverlaySettings = {
36053599
closeOnOutsideClick: false,
36063600
modal: false,
3607-
closeOnEsc: false,
36083601
positionStrategy: new ConnectedPositioningStrategy(),
36093602
scrollStrategy: scrollStrategy
36103603
};
@@ -3879,16 +3872,16 @@ export class TopLeftOffsetComponent {
38793872
</div>`
38803873
})
38813874
export class TwoButtonsComponent {
3882-
private _setting: OverlaySettings = { modal: false, closeOnEsc: false };
3875+
public settings: OverlaySettings = { modal: false };
38833876

38843877
constructor(@Inject(IgxOverlayService) public overlay: IgxOverlayService) { }
38853878

38863879
clickOne() {
3887-
this.overlay.show(this.overlay.attach(SimpleDynamicComponent), this._setting);
3880+
this.overlay.show(this.overlay.attach(SimpleDynamicComponent), this.settings);
38883881
}
38893882

38903883
clickTwo() {
3891-
this.overlay.show(this.overlay.attach(SimpleDynamicComponent), this._setting);
3884+
this.overlay.show(this.overlay.attach(SimpleDynamicComponent), this.settings);
38923885
}
38933886

38943887
divClick(ev: Event) {

projects/igniteui-angular/src/lib/services/overlay/overlay.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import { fromEvent, Subject } from 'rxjs';
3030
import { filter, takeUntil } from 'rxjs/operators';
3131
import { IAnimationParams } from '../../animations/main';
3232
import { showMessage } from '../../core/deprecateDecorators';
33+
import { FromEventTarget } from 'rxjs/internal/observable/fromEvent';
3334

3435
let warningShown = false;
3536

@@ -50,7 +51,7 @@ export class IgxOverlayService implements OnDestroy {
5051
scrollStrategy: new NoOpScrollStrategy(),
5152
modal: true,
5253
closeOnOutsideClick: true,
53-
closeOnEsc: true
54+
closeOnEsc: false
5455
};
5556

5657
/**
@@ -476,11 +477,22 @@ export class IgxOverlayService implements OnDestroy {
476477
}
477478

478479
private setUpCloseOnEscape(info: OverlayInfo) {
480+
if (!info.settings.modal) {
481+
this.subscribeOnEscape(this._document);
482+
return;
483+
}
479484
const wrapperElement = info.elementRef.nativeElement.parentElement.parentElement;
480-
fromEvent(wrapperElement, 'keydown').pipe(
485+
this.subscribeOnEscape(wrapperElement);
486+
}
487+
488+
private subscribeOnEscape(target: FromEventTarget<unknown>) {
489+
fromEvent(target, 'keydown').pipe(
481490
filter((ev: KeyboardEvent) => ev.key === 'Escape' || ev.key === 'Esc'),
482491
takeUntil(this.destroy$)
483-
).subscribe(() => this.hide(info.id));
492+
).subscribe(() => {
493+
const targetOverlay = this._overlayInfos[this._overlayInfos.length - 1];
494+
this.hide(targetOverlay.id);
495+
});
484496
}
485497

486498
private onCloseDone(info: OverlayInfo) {

0 commit comments

Comments
 (0)