UNPKG

@ng-bootstrap/ng-bootstrap

Version:
48 lines 11.9 kB
import { fromEvent, race } from 'rxjs'; import { delay, filter, map, takeUntil, tap, withLatestFrom } from 'rxjs/operators'; import { Key } from './key'; import { closest } from './util'; const isContainedIn = (element, array) => array ? array.some((item) => item.contains(element)) : false; const matchesSelectorIfAny = (element, selector) => !selector || closest(element, selector) != null; // we have to add a more significant delay to avoid re-opening when handling (click) on a toggling element // TODO: use proper Angular platform detection when NgbAutoClose becomes a service and we can inject PLATFORM_ID const isMobile = (() => { const isIOS = () => /iPad|iPhone|iPod/.test(navigator.userAgent) || (/Macintosh/.test(navigator.userAgent) && navigator.maxTouchPoints && navigator.maxTouchPoints > 2); const isAndroid = () => /Android/.test(navigator.userAgent); return typeof navigator !== 'undefined' ? !!navigator.userAgent && (isIOS() || isAndroid()) : false; })(); // setting 'ngbAutoClose' synchronously on mobile results in immediate popup closing // when tapping on the triggering element const wrapAsyncForMobile = (fn) => (isMobile ? () => setTimeout(() => fn(), 100) : fn); export function ngbAutoClose(zone, document, type, close, closed$, insideElements, ignoreElements, insideSelector) { // closing on ESC and outside clicks if (type) { zone.runOutsideAngular(wrapAsyncForMobile(() => { const shouldCloseOnClick = (event) => { const element = event.target; if (event.button === 2 || isContainedIn(element, ignoreElements)) { return false; } if (type === 'inside') { return isContainedIn(element, insideElements) && matchesSelectorIfAny(element, insideSelector); } else if (type === 'outside') { return !isContainedIn(element, insideElements); } /* if (type === true) */ else { return matchesSelectorIfAny(element, insideSelector) || !isContainedIn(element, insideElements); } }; const escapes$ = fromEvent(document, 'keydown').pipe(takeUntil(closed$), /* eslint-disable-next-line deprecation/deprecation */ filter((e) => e.which === Key.Escape), tap((e) => e.preventDefault())); // we have to pre-calculate 'shouldCloseOnClick' on 'mousedown', // because on 'mouseup' DOM nodes might be detached const mouseDowns$ = fromEvent(document, 'mousedown').pipe(map(shouldCloseOnClick), takeUntil(closed$)); const closeableClicks$ = fromEvent(document, 'mouseup').pipe(withLatestFrom(mouseDowns$), filter(([_, shouldClose]) => shouldClose), delay(0), takeUntil(closed$)); race([escapes$.pipe(map((_) => 0 /* SOURCE.ESCAPE */)), closeableClicks$.pipe(map((_) => 1 /* SOURCE.CLICK */))]).subscribe((source) => zone.run(() => close(source))); })); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0b2Nsb3NlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3V0aWwvYXV0b2Nsb3NlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxTQUFTLEVBQWMsSUFBSSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLGNBQWMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3BGLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxPQUFPLENBQUM7QUFDNUIsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUVqQyxNQUFNLGFBQWEsR0FBRyxDQUFDLE9BQW9CLEVBQUUsS0FBcUIsRUFBRSxFQUFFLENBQ3JFLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7QUFFOUQsTUFBTSxvQkFBb0IsR0FBRyxDQUFDLE9BQW9CLEVBQUUsUUFBaUIsRUFBRSxFQUFFLENBQ3hFLENBQUMsUUFBUSxJQUFJLE9BQU8sQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLElBQUksSUFBSSxDQUFDO0FBRWpELDBHQUEwRztBQUMxRyxnSEFBZ0g7QUFDaEgsTUFBTSxRQUFRLEdBQUcsQ0FBQyxHQUFHLEVBQUU7SUFDdEIsTUFBTSxLQUFLLEdBQUcsR0FBRyxFQUFFLENBQ2xCLGtCQUFrQixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDO1FBQzVDLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLElBQUksU0FBUyxDQUFDLGNBQWMsSUFBSSxTQUFTLENBQUMsY0FBYyxHQUFHLENBQUMsQ0FBQyxD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QUU1QixJQUFJLENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLHNCQUFjLENBQUMsQ0FBQyxFQUFFLGdCQUFnQixDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxxQkFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUMxRyxDQUFDLE1BQWMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FDakQsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUNGLENBQUM7S0FDRjtBQUNGLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBOZ1pvbmUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGZyb21FdmVudCwgT2JzZXJ2YWJsZSwgcmFjZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGVsYXksIGZpbHRlciwgbWFwLCB0YWtlVW50aWwsIHRhcCwgd2l0aExhdGVzdEZyb20gfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBLZXkgfSBmcm9tICcuL2tleSc7XG5pbXBvcnQgeyBjbG9zZXN0IH0gZnJvbSAnLi91dGlsJztcblxuY29uc3QgaXNDb250YWluZWRJbiA9IChlbGVtZW50OiBIVE1MRWxlbWVudCwgYXJyYXk/OiBIVE1MRWxlbWVudFtdKSA9PlxuXHRhcnJheSA/IGFycmF5LnNvbWUoKGl0ZW0pID0+IGl0ZW0uY29udGFpbnMoZWxlbWVudCkpIDogZmFsc2U7XG5cbmNvbnN0IG1hdGNoZXNTZWxlY3RvcklmQW55ID0gKGVsZW1lbnQ6IEhUTUxFbGVtZW50LCBzZWxlY3Rvcj86IHN0cmluZykgPT5cblx0IXNlbGVjdG9yIHx8IGNsb3Nlc3QoZWxlbWVudCwgc2VsZWN0b3IpICE9IG51bGw7XG5cbi8vIHdlIGhhdmUgdG8gYWRkIGEgbW9yZSBzaWduaWZpY2FudCBkZWxheSB0byBhdm9pZCByZS1vcGVuaW5nIHdoZW4gaGFuZGxpbmcgKGNsaWNrKSBvbiBhIHRvZ2dsaW5nIGVsZW1lbnRcbi8vIFRPRE86IHVzZSBwcm9wZXIgQW5ndWxhciBwbGF0Zm9ybSBkZXRlY3Rpb24gd2hlbiBOZ2JBdXRvQ2xvc2UgYmVjb21lcyBhIHNlcnZpY2UgYW5kIHdlIGNhbiBpbmplY3QgUExBVEZPUk1fSURcbmNvbnN0IGlzTW9iaWxlID0gKCgpID0+IHtcblx0Y29uc3QgaXNJT1MgPSAoKSA9PlxuXHRcdC9pUGFkfGlQaG9uZXxpUG9kLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpIHx8XG5cdFx0KC9NYWNpbnRvc2gvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkgJiYgbmF2aWdhdG9yLm1heFRvdWNoUG9pbnRzICYmIG5hdmlnYXRvci5tYXhUb3VjaFBvaW50cyA+IDIpO1xuXHRjb25zdCBpc0FuZHJvaWQgPSAoKSA9PiAvQW5kcm9pZC8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcblxuXHRyZXR1cm4gdHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcgPyAhIW5hdmlnYXRvci51c2VyQWdlbnQgJiYgKGlzSU9TKCkgfHwgaXNBbmRyb2lkKCkpIDogZmFsc2U7XG59KSgpO1xuXG4vLyBzZXR0aW5nICduZ2JBdXRvQ2xvc2UnIHN5bmNocm9ub3VzbHkgb24gbW9iaWxlIHJlc3VsdHMgaW4gaW1tZWRpYXRlIHBvcHVwIGNsb3Npbmdcbi8vIHdoZW4gdGFwcGluZyBvbiB0aGUgdHJpZ2dlcmluZyBlbGVtZW50XG5jb25zdCB3cmFwQXN5bmNGb3JNb2JpbGUgPSAoZm4pID0+IChpc01vYmlsZSA/ICgpID0+IHNldFRpbWVvdXQoKCkgPT4gZm4oKSwgMTAwKSA6IGZuKTtcblxuZXhwb3J0IGNvbnN0IGVudW0gU09VUkNFIHtcblx0RVNDQVBFLFxuXHRDTElDSyxcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG5nYkF1dG9DbG9zZShcblx0em9uZTogTmdab25lLFxuXHRkb2N1bWVudDogYW55LFxuXHR0eXBlOiBib29sZWFuIHwgJ2luc2lkZScgfCAnb3V0c2lkZScsXG5cdGNsb3NlOiAoc291cmNlOiBTT1VSQ0UpID0+IHZvaWQsXG5cdGNsb3NlZCQ6IE9ic2VydmFibGU8YW55Pixcblx0aW5zaWRlRWxlbWVudHM6IEhUTUxFbGVtZW50W10sXG5cdGlnbm9yZUVsZW1lbnRzPzogSFRNTEVsZW1lbnRbXSxcblx0aW5zaWRlU2VsZWN0b3I/OiBzdHJpbmcsXG4pIHtcblx0Ly8gY2xvc2luZyBvbiBFU0MgYW5kIG91dHNpZGUgY2xpY2tzXG5cdGlmICh0eXBlKSB7XG5cdFx0em9uZS5ydW5PdXRzaWRlQW5ndWxhcihcblx0XHRcdHdyYXBBc3luY0Zvck1vYmlsZSgoKSA9PiB7XG5cdFx0XHRcdGNvbnN0IHNob3VsZENsb3NlT25DbGljayA9IChldmVudDogTW91c2VFdmVudCkgPT4ge1xuXHRcdFx0XHRcdGNvbnN0IGVsZW1lbnQgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7XG5cdFx0XHRcdFx0aWYgKGV2ZW50LmJ1dHRvbiA9PT0gMiB8fCBpc0NvbnRhaW5lZEluKGVsZW1lbnQsIGlnbm9yZUVsZW1lbnRzKSkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZiAodHlwZSA9PT0gJ2luc2lkZScpIHtcblx0XHRcdFx0XHRcdHJldHVybiBpc0NvbnRhaW5lZEluKGVsZW1lbnQsIGluc2lkZUVsZW1lbnRzKSAmJiBtYXRjaGVzU2VsZWN0b3JJZkFueShlbGVtZW50LCBpbnNpZGVTZWxlY3Rvcik7XG5cdFx0XHRcdFx0fSBlbHNlIGlmICh0eXBlID09PSAnb3V0c2lkZScpIHtcblx0XHRcdFx0XHRcdHJldHVybiAhaXNDb250YWluZWRJbihlbGVtZW50LCBpbnNpZGVFbGVtZW50cyk7XG5cdFx0XHRcdFx0fSAvKiBpZiAodHlwZSA9PT0gdHJ1ZSkgKi8gZWxzZSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gbWF0Y2hlc1NlbGVjdG9ySWZBbnkoZWxlbWVudCwgaW5zaWRlU2VsZWN0b3IpIHx8ICFpc0NvbnRhaW5lZEluKGVsZW1lbnQsIGluc2lkZUVsZW1lbnRzKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH07XG5cblx0XHRcdFx0Y29uc3QgZXNjYXBlcyQgPSBmcm9tRXZlbnQ8S2V5Ym9hcmRFdmVudD4oZG9jdW1lbnQsICdrZXlkb3duJykucGlwZShcblx0XHRcdFx0XHR0YWtlVW50aWwoY2xvc2VkJCksXG5cdFx0XHRcdFx0LyogZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRlcHJlY2F0aW9uL2RlcHJlY2F0aW9uICovXG5cdFx0XHRcdFx0ZmlsdGVyKChlKSA9PiBlLndoaWNoID09PSBLZXkuRXNjYXBlKSxcblx0XHRcdFx0XHR0YXAoKGUpID0+IGUucHJldmVudERlZmF1bHQoKSksXG5cdFx0XHRcdCk7XG5cblx0XHRcdFx0Ly8gd2UgaGF2ZSB0byBwcmUtY2FsY3VsYXRlICdzaG91bGRDbG9zZU9uQ2xpY2snIG9uICdtb3VzZWRvd24nLFxuXHRcdFx0XHQvLyBiZWNhdXNlIG9uICdtb3VzZXVwJyBET00gbm9kZXMgbWlnaHQgYmUgZGV0YWNoZWRcblx0XHRcdFx0Y29uc3QgbW91c2VEb3ducyQgPSBmcm9tRXZlbnQ8TW91c2VFdmVudD4oZG9jdW1lbnQsICdtb3VzZWRvd24nKS5waXBlKFxuXHRcdFx0XHRcdG1hcChzaG91bGRDbG9zZU9uQ2xpY2spLFxuXHRcdFx0XHRcdHRha2VVbnRpbChjbG9zZWQkKSxcblx0XHRcdFx0KTtcblxuXHRcdFx0XHRjb25zdCBjbG9zZWFibGVDbGlja3MkID0gZnJvbUV2ZW50PE1vdXNlRXZlbnQ+KGRvY3VtZW50LCAnbW91c2V1cCcpLnBpcGUoXG5cdFx0XHRcdFx0d2l0aExhdGVzdEZyb20obW91c2VEb3ducyQpLFxuXHRcdFx0XHRcdGZpbHRlcigoW18sIHNob3VsZENsb3NlXSkgPT4gc2hvdWxkQ2xvc2UpLFxuXHRcdFx0XHRcdGRlbGF5KDApLFxuXHRcdFx0XHRcdHRha2VVbnRpbChjbG9zZWQkKSxcblx0XHRcdFx0KSBhcyBPYnNlcnZhYmxlPE1vdXNlRXZlbnQ+O1xuXG5cdFx0XHRcdHJhY2UoW2VzY2FwZXMkLnBpcGUobWFwKChfKSA9PiBTT1VSQ0UuRVNDQVBFKSksIGNsb3NlYWJsZUNsaWNrcyQucGlwZShtYXAoKF8pID0+IFNPVVJDRS5DTElDSykpXSkuc3Vic2NyaWJlKFxuXHRcdFx0XHRcdChzb3VyY2U6IFNPVVJDRSkgPT4gem9uZS5ydW4oKCkgPT4gY2xvc2Uoc291cmNlKSksXG5cdFx0XHRcdCk7XG5cdFx0XHR9KSxcblx0XHQpO1xuXHR9XG59XG4iXX0=