Skip to content

Commit ee164f6

Browse files
authored
Merge branch '10.1.x' into ibarakov/fix-8162-10.1.x
2 parents 0869982 + ca2d891 commit ee164f6

File tree

3 files changed

+138
-4
lines changed

3 files changed

+138
-4
lines changed

projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_grid.scss

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ $_bootstrap-grid: extend(
604604
/// @prop {Color} header-text-color [igx-color: 'primary'] - The table header text color.
605605
/// @prop {Map} header-selected-background [igx-color: ('primary', 50)] - The table header background color when selected (ex. column selection).
606606
/// @prop {Map} header-selected-text-color [igx-color: 'primary'] - The table header text color when selected (ex. column selection).
607-
/// @prop {Map} header-border-color [igx-color: ('primary', 100)] - The color used for header borders.
607+
/// @prop {Map} header-border-color [igx-color: ('primary', 500), rgba: .24] - The color used for header borders.
608608
///
609609
/// @prop {Map} filtering-header-text-color [igx-color: ('primary', 900)] - The text color color of the filtered column header.
610610
/// @prop {Map} filtering-background-or [igx-color: 'warn'] - The background color of advanced filtering "OR" condition.
@@ -673,7 +673,8 @@ $_indigo-grid: extend(
673673
),
674674

675675
header-border-color: (
676-
igx-color: ('primary', 100)
676+
igx-color: ('primary', 500),
677+
rgba: .24
677678
),
678679

679680
filtering-header-text-color: (

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

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,92 @@ describe('igxOverlay', () => {
188188
UIInteractions.clearOverlay();
189189
});
190190

191+
describe('Pure Unit Test', () => {
192+
configureTestSuite();
193+
let mockElement: any;
194+
let mockElementRef: any;
195+
let mockFactoryResolver: any;
196+
let mockApplicationRef: any;
197+
let mockInjector: any;
198+
let mockAnimationBuilder: any;
199+
let mockDocument: any;
200+
let mockNgZone: any;
201+
let mockPlatformUtil: any;
202+
let overlay: IgxOverlayService;
203+
beforeEach(() => {
204+
mockElement = {
205+
style: { visibility: '', cursor: '', transitionDuration: '' },
206+
classList: { add: () => { }, remove: () => { } },
207+
appendChild: () => { },
208+
removeChild: () => { },
209+
addEventListener: (type: string, listener: (this: HTMLElement, ev: MouseEvent) => any) => { },
210+
removeEventListener: (type: string, listener: (this: HTMLElement, ev: MouseEvent) => any) => { },
211+
getBoundingClientRect: () => ({ width: 10, height: 10 }),
212+
insertBefore: (newChild: HTMLDivElement, refChild: Node) => { },
213+
contains: () => { }
214+
};
215+
mockElement.parent = mockElement;
216+
mockElement.parentElement = mockElement;
217+
mockElementRef = { nativeElement: mockElement };
218+
mockFactoryResolver = {
219+
resolveComponentFactory: (c: any) => {
220+
return {
221+
create: (i: any) => {
222+
return {
223+
hostView: '',
224+
location: mockElementRef,
225+
changeDetectorRef: { detectChanges: () => { } },
226+
destroy: () => { }
227+
};
228+
}
229+
};
230+
}
231+
};
232+
mockApplicationRef = { attachView: (h: any) => { }, detachView: (h: any) => { } };
233+
mockInjector = {};
234+
mockAnimationBuilder = {};
235+
mockDocument = {
236+
body: mockElement,
237+
defaultView: mockElement,
238+
createElement: () => mockElement,
239+
appendChild: () => { },
240+
addEventListener: (type: string, listener: (this: HTMLElement, ev: MouseEvent) => any) => { },
241+
removeEventListener: (type: string, listener: (this: HTMLElement, ev: MouseEvent) => any) => { }
242+
};
243+
mockNgZone = {};
244+
mockPlatformUtil = { isIOS: false };
245+
246+
overlay = new IgxOverlayService(
247+
mockFactoryResolver, mockApplicationRef, mockInjector, mockAnimationBuilder, mockDocument, mockNgZone, mockPlatformUtil);
248+
});
249+
250+
it('Should set cursor to pointer on iOS', () => {
251+
mockPlatformUtil.isIOS = true;
252+
mockDocument.body.style.cursor = 'initialCursorValue';
253+
254+
const mockOverlaySettings: OverlaySettings = {
255+
modal: false,
256+
positionStrategy: new GlobalPositionStrategy({ openAnimation: null, closeAnimation: null })
257+
};
258+
let id = overlay.attach(mockElementRef, mockOverlaySettings);
259+
260+
overlay.show(id);
261+
expect(mockDocument.body.style.cursor).toEqual('pointer');
262+
263+
overlay.hide(id);
264+
expect(mockDocument.body.style.cursor).toEqual('initialCursorValue');
265+
266+
mockPlatformUtil.isIOS = false;
267+
id = overlay.attach(mockElementRef, mockOverlaySettings);
268+
269+
overlay.show(id);
270+
expect(mockDocument.body.style.cursor).toEqual('initialCursorValue');
271+
272+
overlay.hide(id);
273+
expect(mockDocument.body.style.cursor).toEqual('initialCursorValue');
274+
});
275+
});
276+
191277
describe('Unit Tests: ', () => {
192278
configureTestSuite();
193279
beforeEach(async(() => {
@@ -887,6 +973,35 @@ describe('igxOverlay', () => {
887973
expect(element.style.width).toBe('200px');
888974
expect(element.style.height).toBe('100px');
889975
});
976+
977+
it('should close overlay on outside click when target is point, #8297', fakeAsync(() => {
978+
const fix = TestBed.createComponent(EmptyPageComponent);
979+
const button = fix.componentInstance.buttonElement;
980+
const overlay = fix.componentInstance.overlay;
981+
fix.detectChanges();
982+
983+
const overlaySettings: OverlaySettings = {
984+
modal: false,
985+
closeOnOutsideClick: true,
986+
positionStrategy: new ConnectedPositioningStrategy()
987+
};
988+
989+
overlaySettings.positionStrategy.settings.target = new Point(10, 10);
990+
991+
overlay.show(overlay.attach(SimpleDynamicComponent), overlaySettings);
992+
tick();
993+
fix.detectChanges();
994+
995+
let overlayDiv: Element = document.getElementsByClassName(CLASS_OVERLAY_MAIN)[0];
996+
expect(overlayDiv).toBeDefined();
997+
998+
document.body.click();
999+
tick();
1000+
fix.detectChanges();
1001+
1002+
overlayDiv = document.getElementsByClassName(CLASS_OVERLAY_MAIN)[0];
1003+
expect(overlayDiv).toBeUndefined();
1004+
}));
8901005
});
8911006

8921007
describe('Unit Tests - Scroll Strategies: ', () => {

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

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { fromEvent, Subject, Subscription } from 'rxjs';
1717
import { filter, takeUntil } from 'rxjs/operators';
1818
import { IAnimationParams } from '../../animations/main';
1919
import { showMessage } from '../../core/deprecateDecorators';
20+
import { PlatformUtil } from '../../core/utils';
2021
import { GlobalPositionStrategy } from './position/global-position-strategy';
2122
import { NoOpScrollStrategy } from './scroll/NoOpScrollStrategy';
2223
import {
@@ -41,6 +42,8 @@ export class IgxOverlayService implements OnDestroy {
4142
private _document: Document;
4243
private _keyPressEventListener: Subscription;
4344
private destroy$ = new Subject<boolean>();
45+
private _cursorStyleIsSet = false;
46+
private _cursorOriginalValue: string;
4447

4548
private _defaultSettings: OverlaySettings = {
4649
positionStrategy: new GlobalPositionStrategy(),
@@ -116,7 +119,8 @@ export class IgxOverlayService implements OnDestroy {
116119
private _injector: Injector,
117120
private builder: AnimationBuilder,
118121
@Inject(DOCUMENT) private document: any,
119-
private _zone: NgZone) {
122+
private _zone: NgZone,
123+
protected platformUtil: PlatformUtil) {
120124
this._document = <Document>this.document;
121125
}
122126

@@ -653,7 +657,7 @@ export class IgxOverlayService implements OnDestroy {
653657
// if we should exclude position target check if the click is over it. If so do not close overlay
654658
const positionTarget = info.settings.positionStrategy.settings.target as HTMLElement;
655659
let clickOnPositionTarget = false;
656-
if (positionTarget) {
660+
if (positionTarget && positionTarget.contains) {
657661
clickOnPositionTarget = positionTarget.contains(target);
658662
}
659663

@@ -683,6 +687,15 @@ export class IgxOverlayService implements OnDestroy {
683687
this._overlayInfos.filter(x => x.settings.closeOnOutsideClick && !x.settings.modal &&
684688
x.closeAnimationPlayer &&
685689
x.closeAnimationPlayer.hasStarted()).length === 1) {
690+
691+
// click event is not fired on iOS. To make element "clickable" we are
692+
// setting the cursor to pointer
693+
if (this.platformUtil.isIOS && !this._cursorStyleIsSet) {
694+
this._cursorOriginalValue = this._document.body.style.cursor;
695+
this._document.body.style.cursor = 'pointer';
696+
this._cursorStyleIsSet = true;
697+
}
698+
686699
this._document.addEventListener('click', this.documentClicked, true);
687700
}
688701
}
@@ -698,6 +711,11 @@ export class IgxOverlayService implements OnDestroy {
698711
});
699712

700713
if (shouldRemoveClickEventListener) {
714+
if (this._cursorStyleIsSet) {
715+
this._document.body.style.cursor = this._cursorOriginalValue;
716+
this._cursorOriginalValue = '';
717+
this._cursorStyleIsSet = false;
718+
}
701719
this._document.removeEventListener('click', this.documentClicked, true);
702720
}
703721
}

0 commit comments

Comments
 (0)