MOBILE-3661 split-view: Support nested split views
parent
ae76e3da02
commit
6d148229f1
|
@ -1,5 +1,5 @@
|
|||
<ion-content>
|
||||
<ion-content class="menu">
|
||||
<ng-content></ng-content>
|
||||
</ion-content>
|
||||
<ion-router-outlet></ion-router-outlet>
|
||||
<ion-router-outlet class="content"></ion-router-outlet>
|
||||
<!-- @todo placeholder -->
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
@import "~theme/breakpoints";
|
||||
|
||||
// @todo RTL layout
|
||||
|
||||
:host {
|
||||
--side-width: 100%;
|
||||
--side-min-width: 270px;
|
||||
--side-max-width: 28%;
|
||||
--menu-min-width: 270px;
|
||||
--menu-max-width: 28%;
|
||||
--menu-display: flex;
|
||||
--content-display: block;
|
||||
--border-width: 1;
|
||||
|
||||
top: 0;
|
||||
right: 0;
|
||||
|
@ -19,16 +19,28 @@
|
|||
contain: strict;
|
||||
}
|
||||
|
||||
:host(.menu-only) {
|
||||
--menu-min-width: 0;
|
||||
--menu-max-width: 100%;
|
||||
--content-display: none;
|
||||
--border-width: 0;
|
||||
}
|
||||
|
||||
:host(.content-only) {
|
||||
--menu-display: none;
|
||||
--border-width: 0;
|
||||
}
|
||||
|
||||
:host-context(ion-app.md) {
|
||||
--border: 1px solid var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-150, rgba(0, 0, 0, .13))));
|
||||
--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))));
|
||||
}
|
||||
|
||||
:host-context(ion-app.ios) {
|
||||
--border: .55px solid var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-250, #c8c7cc)));
|
||||
--border: calc(var(--border-width) * .55px) solid var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-250, #c8c7cc)));
|
||||
}
|
||||
|
||||
ion-content,
|
||||
ion-router-outlet {
|
||||
.menu,
|
||||
.content {
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
|
@ -38,49 +50,25 @@ ion-router-outlet {
|
|||
z-index: 0;
|
||||
}
|
||||
|
||||
ion-content {
|
||||
display: flex;
|
||||
.menu {
|
||||
display: var(--menu-display);
|
||||
flex-shrink: 0;
|
||||
order: -1;
|
||||
border-left: unset;
|
||||
border-right: unset;
|
||||
border-inline-start: 0;
|
||||
border-inline-end: 0;
|
||||
border-inline-end: var(--border);
|
||||
min-width: var(--menu-min-width);
|
||||
max-width: var(--menu-max-width);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
ion-router-outlet {
|
||||
.content {
|
||||
display: var(--content-display);
|
||||
flex: 1;
|
||||
display: none;
|
||||
|
||||
::ng-deep ion-header {
|
||||
display: none;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
:host(.outlet-activated) {
|
||||
|
||||
ion-router-outlet {
|
||||
display: block;
|
||||
}
|
||||
|
||||
ion-content {
|
||||
display: none;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media (min-width: $breakpoint-tablet) {
|
||||
|
||||
ion-content {
|
||||
border-inline-end: var(--border);
|
||||
min-width: var(--side-min-width);
|
||||
max-width: var(--side-max-width);
|
||||
}
|
||||
|
||||
:host(.outlet-activated) ion-content {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,10 +12,17 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { AfterViewInit, Component, HostBinding, OnDestroy, ViewChild } from '@angular/core';
|
||||
import { AfterViewInit, Component, ElementRef, HostBinding, OnDestroy, ViewChild } from '@angular/core';
|
||||
import { IonRouterOutlet } from '@ionic/angular';
|
||||
import { CoreScreen } from '@services/screen';
|
||||
import { Subscription } from 'rxjs';
|
||||
|
||||
enum CoreSplitViewMode {
|
||||
Default = '', // Shows both menu and content.
|
||||
MenuOnly = 'menu-only', // Hides content.
|
||||
ContentOnly = 'content-only', // Hides menu.
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'core-split-view',
|
||||
templateUrl: 'split-view.html',
|
||||
|
@ -24,19 +31,25 @@ import { Subscription } from 'rxjs';
|
|||
export class CoreSplitViewComponent implements AfterViewInit, OnDestroy {
|
||||
|
||||
@ViewChild(IonRouterOutlet) outlet!: IonRouterOutlet;
|
||||
@HostBinding('class.outlet-activated') outletActivated = false;
|
||||
@HostBinding('class') classes = '';
|
||||
|
||||
private isNestedSplitView = false;
|
||||
private subscriptions?: Subscription[];
|
||||
|
||||
constructor(private element: ElementRef<HTMLElement>) {}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
ngAfterViewInit(): void {
|
||||
this.outletActivated = this.outlet.isActivated;
|
||||
this.isNestedSplitView = !!this.element.nativeElement.parentElement?.closest('core-split-view');
|
||||
this.subscriptions = [
|
||||
this.outlet.activateEvents.subscribe(() => this.outletActivated = true),
|
||||
this.outlet.deactivateEvents.subscribe(() => this.outletActivated = false),
|
||||
this.outlet.activateEvents.subscribe(() => this.updateClasses()),
|
||||
this.outlet.deactivateEvents.subscribe(() => this.updateClasses()),
|
||||
CoreScreen.instance.layoutObservable.subscribe(() => this.updateClasses()),
|
||||
];
|
||||
|
||||
this.updateClasses();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -46,4 +59,31 @@ export class CoreSplitViewComponent implements AfterViewInit, OnDestroy {
|
|||
this.subscriptions?.forEach(subscription => subscription.unsubscribe());
|
||||
}
|
||||
|
||||
/**
|
||||
* Update host classes.
|
||||
*/
|
||||
private updateClasses(): void {
|
||||
this.classes = this.getCurrentMode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current mode. Depending on the layout, outlet status, and whether this split view
|
||||
* is nested or not, this method will indicate which parts of the split view should be visible.
|
||||
*
|
||||
* @return Split view mode.
|
||||
*/
|
||||
private getCurrentMode(): CoreSplitViewMode {
|
||||
if (this.isNestedSplitView) {
|
||||
return CoreSplitViewMode.MenuOnly;
|
||||
}
|
||||
|
||||
if (CoreScreen.instance.isMobile) {
|
||||
return this.outlet.isActivated
|
||||
? CoreSplitViewMode.ContentOnly
|
||||
: CoreSplitViewMode.MenuOnly;
|
||||
}
|
||||
|
||||
return CoreSplitViewMode.Default;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
/*
|
||||
* Layout Breakpoints
|
||||
*
|
||||
* https://ionicframework.com/docs/layout/grid#default-breakpoints
|
||||
*/
|
||||
|
||||
$breakpoint-xs: 0px;
|
||||
$breakpoint-sm: 576px;
|
||||
$breakpoint-md: 768px;
|
||||
$breakpoint-lg: 992px;
|
||||
$breakpoint-xl: 1200px;
|
||||
|
||||
$breakpoint-tablet: $breakpoint-lg;
|
Loading…
Reference in New Issue