From 0db4971ae60149f618041377d5934792d5e21772 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Thu, 20 May 2021 15:30:58 +0200 Subject: [PATCH] MOBILE-3320 ios: Fix ion-content outside split view scroll --- src/core/components/split-view/split-view.ts | 34 ++++++++++++++++++++ src/theme/theme.base.scss | 9 ++++++ 2 files changed, 43 insertions(+) diff --git a/src/core/components/split-view/split-view.ts b/src/core/components/split-view/split-view.ts index f5b15ab49..b08eea849 100644 --- a/src/core/components/split-view/split-view.ts +++ b/src/core/components/split-view/split-view.ts @@ -24,6 +24,8 @@ export enum CoreSplitViewMode { MenuAndContent = 'menu-and-content', // Shows both menu and content. } +const disabledScrollClass = 'disable-scroll-y'; + @Component({ selector: 'core-split-view', templateUrl: 'split-view.html', @@ -36,6 +38,7 @@ export class CoreSplitViewComponent implements AfterViewInit, OnDestroy { @Input() placeholderText = 'core.emptysplit'; @Input() mode?: CoreSplitViewMode; isNested = false; + disabledScrollOuterContents: HTMLIonContentElement[] = []; private outletRouteSubject: BehaviorSubject = new BehaviorSubject(null); private subscriptions?: Subscription[]; @@ -59,6 +62,9 @@ export class CoreSplitViewComponent implements AfterViewInit, OnDestroy { */ ngAfterViewInit(): void { this.isNested = !!this.element.nativeElement.parentElement?.closest('core-split-view'); + + this.disableScrollOnParent(); + this.subscriptions = [ this.contentOutlet.activateEvents.subscribe(() => { this.updateClasses(); @@ -79,6 +85,8 @@ export class CoreSplitViewComponent implements AfterViewInit, OnDestroy { */ ngOnDestroy(): void { this.subscriptions?.forEach(subscription => subscription.unsubscribe()); + + this.enableScrollOnParent(); } /** @@ -122,4 +130,30 @@ export class CoreSplitViewComponent implements AfterViewInit, OnDestroy { return CoreSplitViewMode.MenuAndContent; } + /** + * Will disable scroll on parent ion contents to enabled PTR on the ones inside the splitview. + * This error only happens on iOS. + * Another manual solution is to add scroll-y=false on the ion-contents outside the split view. + */ + protected disableScrollOnParent(): void { + let outerContent = this.element.nativeElement.parentElement?.closest('ion-content'); + while (outerContent) { + if (outerContent?.getAttribute('scroll-y') != 'false' && !outerContent?.classList.contains(disabledScrollClass)) { + outerContent.classList.add(disabledScrollClass); + this.disabledScrollOuterContents.push(outerContent); + } + + outerContent = outerContent.parentElement?.closest('ion-content'); + } + } + + /** + * Will enable scroll on parent ion contents previouly disabled. + */ + protected enableScrollOnParent(): void { + this.disabledScrollOuterContents.forEach((outerContent) => { + outerContent.classList.remove(disabledScrollClass); + }); + } + } diff --git a/src/theme/theme.base.scss b/src/theme/theme.base.scss index a1c7ac7fd..967e2b05e 100644 --- a/src/theme/theme.base.scss +++ b/src/theme/theme.base.scss @@ -628,3 +628,12 @@ ion-input .native-input { ion-checkbox { --border-radius: 2px; } + +// Disable scroll on parent ion contents to enabled PTR on the ones inside the splitview. See split-view component for more info. +ion-content.disable-scroll-y::part(scroll) { + touch-action: auto; + overflow-y: hidden; + overscroll-behavior-y: auto; + z-index: auto; + will-change: auto; +}