diff --git a/demo/src/app/components/dropdown/demos/navbar/dropdown-navbar.html b/demo/src/app/components/dropdown/demos/navbar/dropdown-navbar.html
index 8fb36619d5..b833125680 100644
--- a/demo/src/app/components/dropdown/demos/navbar/dropdown-navbar.html
+++ b/demo/src/app/components/dropdown/demos/navbar/dropdown-navbar.html
@@ -37,9 +37,9 @@
Static
@@ -48,9 +48,9 @@
Static right
@@ -59,9 +59,9 @@
Dynamic
diff --git a/src/util/autoclose.ts b/src/util/autoclose.ts
index 8020fee1cb..cccc1b60f9 100644
--- a/src/util/autoclose.ts
+++ b/src/util/autoclose.ts
@@ -18,16 +18,20 @@ if (typeof navigator !== 'undefined') {
iOS = !!navigator.userAgent && /iPad|iPhone|iPod/.test(navigator.userAgent);
}
+// setting 'ngbAutoClose' synchronously on iOS results in immediate popup closing
+// when tapping on the triggering element
+const wrapAsyncForiOS = fn => iOS ? () => setTimeout(() => fn(), 100) : fn;
+
export function ngbAutoClose(
zone: NgZone, document: any, type: boolean | 'inside' | 'outside', close: () => void, closed$: Observable,
insideElements: HTMLElement[], ignoreElements?: HTMLElement[], insideSelector?: string) {
// closing on ESC and outside clicks
if (type) {
- zone.runOutsideAngular(() => {
+ zone.runOutsideAngular(wrapAsyncForiOS(() => {
- const shouldCloseOnClick = (event: MouseEvent | TouchEvent) => {
+ const shouldCloseOnClick = (event: MouseEvent) => {
const element = event.target as HTMLElement;
- if ((event instanceof MouseEvent && event.button === 2) || isContainedIn(element, ignoreElements)) {
+ if (event.button === 2 || isContainedIn(element, ignoreElements)) {
return false;
}
if (type === 'inside') {
@@ -48,16 +52,16 @@ export function ngbAutoClose(
// we have to pre-calculate 'shouldCloseOnClick' on 'mousedown/touchstart',
// because on 'mouseup/touchend' DOM nodes might be detached
- const mouseDowns$ = fromEvent(document, iOS ? 'touchstart' : 'mousedown')
- .pipe(map(shouldCloseOnClick), takeUntil(closed$));
+ const mouseDowns$ =
+ fromEvent(document, 'mousedown').pipe(map(shouldCloseOnClick), takeUntil(closed$));
- const closeableClicks$ = fromEvent(document, iOS ? 'touchend' : 'mouseup')
+ const closeableClicks$ = fromEvent(document, 'mouseup')
.pipe(
- withLatestFrom(mouseDowns$), filter(([_, shouldClose]) => shouldClose),
- delay(iOS ? 16 : 0), takeUntil(closed$)) as Observable;
+ withLatestFrom(mouseDowns$), filter(([_, shouldClose]) => shouldClose), delay(0),
+ takeUntil(closed$)) as Observable;
race([escapes$, closeableClicks$]).subscribe(() => zone.run(close));
- });
+ }));
}
}