diff --git a/src/core/components/split-view/split-view.html b/src/core/components/split-view/split-view.html
index a585f4b0a..569af4224 100644
--- a/src/core/components/split-view/split-view.html
+++ b/src/core/components/split-view/split-view.html
@@ -1,5 +1,7 @@
-
-
+
+
+
diff --git a/src/core/components/split-view/split-view.scss b/src/core/components/split-view/split-view.scss
index d94a6efcc..13f0c2db4 100644
--- a/src/core/components/split-view/split-view.scss
+++ b/src/core/components/split-view/split-view.scss
@@ -1,11 +1,13 @@
-// @todo RTL layout
-
:host {
--menu-min-width: 270px;
--menu-max-width: 28%;
+ --menu-box-shadow: var(--core-menu-box-shadow-end);
+ --menu-z: 2;
+ --menu-border-width: 1;
--menu-display: flex;
--content-display: block;
- --border-width: 1;
+ --content-outlet-display: none;
+ --content-placeholder-display: var(--content-display);
top: 0;
right: 0;
@@ -17,58 +19,74 @@
flex-direction: row;
flex-wrap: nowrap;
contain: strict;
+
+ .menu,
+ .content-outlet {
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ position: relative;
+ box-shadow: none;
+ z-index: 0;
+ }
+
+ .menu {
+ box-shadow: var(--menu-box-shadow);
+ z-index: var(--menu-z);
+ display: var(--menu-display);
+ flex-shrink: 0;
+ order: -1;
+ width: 100%;
+ border-inline-start: 0;
+ border-inline-end: var(--border);
+ min-width: var(--menu-min-width);
+ max-width: var(--menu-max-width);
+ }
+
+ .content-outlet {
+ display: var(--content-outlet-display);
+ flex: 1;
+
+ ::ng-deep ion-header {
+ display: none;
+ }
+
+ }
+
+ .content-placeholder {
+ display: var(--content-placeholder-display);
+ flex: 1;
+ position: relative;
+ background-color: var(--ion-background);
+ }
+
}
:host(.menu-only) {
--menu-min-width: 0;
--menu-max-width: 100%;
--content-display: none;
- --border-width: 0;
+ --menu-border-width: 0;
+ --menu-box-shadow: none;
+ --menu-z: 0;
+ --selected-item-border-width: 0;
}
:host(.content-only) {
--menu-display: none;
- --border-width: 0;
+ --menu-border-width: 0;
+}
+
+:host(.outlet-activated) {
+ --content-placeholder-display: none;
+ --content-outlet-display: var(--content-display);
}
:host-context(ion-app.md) {
- --border: calc(var(--border-width) * 1px) solid var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-150, rgba(0, 0, 0, .13))));
+ --border: calc(var(--menu-border-width) * 1px) solid var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-150, rgba(0, 0, 0, .13))));
}
:host-context(ion-app.ios) {
- --border: calc(var(--border-width) * .55px) solid var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-250, #c8c7cc)));
-}
-
-.menu,
-.content {
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- position: relative;
- box-shadow: none !important;
- z-index: 0;
-}
-
-.menu {
- display: var(--menu-display);
- flex-shrink: 0;
- order: -1;
- border-left: unset;
- border-right: unset;
- border-inline-start: 0;
- border-inline-end: var(--border);
- min-width: var(--menu-min-width);
- max-width: var(--menu-max-width);
- width: 100%;
-}
-
-.content {
- display: var(--content-display);
- flex: 1;
-
- ::ng-deep ion-header {
- display: none;
- }
-
+ --border: calc(var(--menu-border-width) * .55px) solid var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-250, #c8c7cc)));
}
diff --git a/src/core/components/split-view/split-view.ts b/src/core/components/split-view/split-view.ts
index 22d8b1e98..c9ab27d97 100644
--- a/src/core/components/split-view/split-view.ts
+++ b/src/core/components/split-view/split-view.ts
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import { AfterViewInit, Component, ElementRef, HostBinding, OnDestroy, ViewChild } from '@angular/core';
+import { AfterViewInit, Component, ElementRef, HostBinding, Input, OnDestroy, ViewChild } from '@angular/core';
import { IonRouterOutlet } from '@ionic/angular';
import { CoreScreen } from '@services/screen';
import { Subscription } from 'rxjs';
@@ -32,6 +32,7 @@ export class CoreSplitViewComponent implements AfterViewInit, OnDestroy {
@ViewChild(IonRouterOutlet) outlet!: IonRouterOutlet;
@HostBinding('class') classes = '';
+ @Input() placeholderText = 'core.emptysplit';
isNested = false;
private subscriptions?: Subscription[];
@@ -65,6 +66,10 @@ export class CoreSplitViewComponent implements AfterViewInit, OnDestroy {
private updateClasses(): void {
const classes: string[] = [this.getCurrentMode()];
+ if (this.outlet.isActivated) {
+ classes.push('outlet-activated');
+ }
+
if (this.isNested) {
classes.push('nested');
}
@@ -92,4 +97,13 @@ export class CoreSplitViewComponent implements AfterViewInit, OnDestroy {
return CoreSplitViewMode.MenuAndContent;
}
+ /**
+ * Check if both panels are shown. It depends on screen width.
+ *
+ * @return If split view is enabled.
+ */
+ isOn(): boolean {
+ return this.outlet.isActivated;
+ }
+
}
diff --git a/src/core/features/block/components/course-blocks/course-blocks.scss b/src/core/features/block/components/course-blocks/course-blocks.scss
index 04f290e4f..314fa25ff 100644
--- a/src/core/features/block/components/course-blocks/course-blocks.scss
+++ b/src/core/features/block/components/course-blocks/course-blocks.scss
@@ -1,4 +1,6 @@
:host {
+ --side-blocks-box-shadow: var(--core-menu-box-shadow-start);
+
&.core-no-blocks .core-course-blocks-content {
height: auto;
}
@@ -20,7 +22,7 @@
div.core-course-blocks-side {
max-width: var(--side-blocks-max-width);
min-width: var(--side-blocks-min-width);
- box-shadow: -4px 0px 16px rgba(0, 0, 0, 0.18);
+ box-shadow: var(--side-blocks-box-shadow);
z-index: 2;
// @todo @include core-split-area-end();
}
@@ -53,7 +55,7 @@
:host-context([dir="rtl"]).core-has-blocks {
@media (min-width: 768px) {
div.core-course-blocks-side {
- box-shadow: 4px 0px 16px rgba(0, 0, 0, 0.18);
+ box-shadow: var(--side-blocks-box-shadow);
}
}
}
diff --git a/src/core/services/navigator.ts b/src/core/services/navigator.ts
index f14ab895b..431ec6132 100644
--- a/src/core/services/navigator.ts
+++ b/src/core/services/navigator.ts
@@ -91,6 +91,21 @@ export class CoreNavigatorService {
return matches?.[1] ?? null;
}
+ /**
+ * Returns if a section is loaded on the split view (tablet mode).
+ *
+ * @param path Path, can be a glob pattern.
+ * @return Whether the active route is using the given path.
+ */
+ isCurrentPathInTablet(path: string): boolean {
+ if (CoreScreen.instance.isMobile) {
+ // Split view is off.
+ return false;
+ }
+
+ return this.isCurrent(path);
+ }
+
/**
* Navigate to a new path.
*
@@ -213,9 +228,11 @@ export class CoreNavigatorService {
* @return Previous path.
*/
getPreviousPath(): string {
+ // @todo: Remove this method and the used attributes.
+ // This is a quick workarround to avoid loops. Ie, in messages we can navigate to user profile and there to messages.
return CoreUrlUtils.instance.removeUrlParams(this.previousPath || '');
}
-
+
/**
* Get a parameter for the current route.
* Please notice that objects can only be retrieved once. You must call this function only once per page and parameter,
diff --git a/src/theme/app.scss b/src/theme/app.scss
index d2f65a5d1..96a30cb11 100644
--- a/src/theme/app.scss
+++ b/src/theme/app.scss
@@ -69,6 +69,10 @@ ion-icon {
}
}
+[dir=rtl] ion-icon.icon-flip-rtl {
+ transform: scaleX(-1);
+}
+
// Ionic alert.
ion-alert.core-alert-network-error .alert-head {
position: relative;
diff --git a/src/theme/variables.scss b/src/theme/variables.scss
index 49093e206..30ab4fcc5 100644
--- a/src/theme/variables.scss
+++ b/src/theme/variables.scss
@@ -106,6 +106,7 @@
--color: var(--custom-bottom-tabs-color, var(--white));
}
+ --core-toolbar-button-image-width: var(--custom-toolbar-button-image-width, 32px);
--ion-statusbar-background: var(--custom-toolbar-background, var(--ion-color-primary));
ion-toolbar {
--color: var(--custom-toolbar-color, var(--ion-color-primary-contrast));
@@ -170,8 +171,6 @@
--selected-item-color: var(--custom-selected-item-color, var(--core-color));
--selected-item-border-width: var(--custom-selected-item-border-width, 5px);
- --drop-shadow: var(--custom-drop-shadow, 0, 0, 0, 0.2);
-
--core-login-background: var(--custom-login-background, var(--white));
--core-login-text-color: var(--custom-login-text-color, var(--black));
@@ -188,11 +187,8 @@
--core-star-color: var(--custom-star-color, var(--core-color));
--core-large-avatar-size: var(--custom-large-avatar-size, 90px);
-
--core-avatar-size: var(--custom-avatar-size, 40px);
- --core-toolbar-button-image-width: var(--custom-toolbar-button-image-width, 32px);
-
--core-send-message-input-background: var(--custom-send-message-input-background, var(--gray));
--core-send-message-input-color: var(--custom-send-message-input-color, var(--black));
@@ -214,6 +210,11 @@
--addon-messages-avatar-size: var(--custom-messages-avatar-size, 30px);
--addon-messages-discussion-badge: var(--custom-messages-discussion-badge, var(--core-color));
--addon-messages-discussion-badge-text: var(--custom-messages-discussion-badge-text, var(--white));
+
+ --drop-shadow: var(--custom-drop-shadow, 0, 0, 0, 0.2);
+
+ --core-menu-box-shadow-end: var(--custom-menu-box-shadow-end, -4px 0px 16px rgba(0, 0, 0, 0.18));
+ --core-menu-box-shadow-start: var(--custom-menu-box-shadow-start, 4px 0px 16px rgba(0, 0, 0, 0.18));
}
/*