From 19269f36f908c4673e7cde8d58f995bd9fb2af18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Fri, 8 Jun 2018 15:59:06 +0200 Subject: [PATCH] MOBILE-2430 tabs: Add tab sliding effect --- .../index/addon-mod-wiki-index.html | 2 +- src/components/tabs/core-tabs.html | 30 +++++-- src/components/tabs/tabs.scss | 28 +++++- src/components/tabs/tabs.ts | 85 ++++++++++++++++++- 4 files changed, 131 insertions(+), 14 deletions(-) diff --git a/src/addon/mod/wiki/components/index/addon-mod-wiki-index.html b/src/addon/mod/wiki/components/index/addon-mod-wiki-index.html index 268a90f4d..532649f9a 100644 --- a/src/addon/mod/wiki/components/index/addon-mod-wiki-index.html +++ b/src/addon/mod/wiki/components/index/addon-mod-wiki-index.html @@ -25,7 +25,7 @@ - + diff --git a/src/components/tabs/core-tabs.html b/src/components/tabs/core-tabs.html index 4fee27fb6..4045a3264 100644 --- a/src/components/tabs/core-tabs.html +++ b/src/components/tabs/core-tabs.html @@ -1,14 +1,28 @@
-
\ No newline at end of file +
diff --git a/src/components/tabs/tabs.scss b/src/components/tabs/tabs.scss index 56b3113aa..429f386d5 100644 --- a/src/components/tabs/tabs.scss +++ b/src/components/tabs/tabs.scss @@ -6,7 +6,11 @@ width: 100%; background: $core-top-tabs-background; - > a { + .row { + width: 100%; + } + + a.tab-slide { @extend .tab-button; background: $core-top-tabs-background; @@ -20,9 +24,25 @@ border-bottom: 2px solid $core-top-tabs-color-active !important; } } + + ion-col { + text-align: center; + font-size: 1.6rem; + line-height: 1.6rem; + + &.col-with-arrow { + display: flex; + justify-content: center; + align-items: center; + + ion-icon { + color: #ccc; + } + } + } } -.md .core-tabs-bar > a { +.md .core-tabs-bar a.tab-slide { // @extend .tabs-md .tab-button; min-height: $tabs-md-tab-min-height; @@ -30,7 +50,7 @@ color: $tabs-md-tab-text-color; } -.ios .core-tabs-bar > a { +.ios .core-tabs-bar a.tab-slide { // @extend .tabs-ios .tab-button; max-width: $tabs-ios-tab-max-width; min-height: $tabs-ios-tab-min-height; @@ -40,7 +60,7 @@ color: $tabs-ios-tab-text-color; } -.wp .core-tabs-bar > a { +.wp .core-tabs-bar a.tab-slide { //@extend .tabs-wp .tab-button; @include border-radius(0); diff --git a/src/components/tabs/tabs.ts b/src/components/tabs/tabs.ts index b86f59082..2629763ae 100644 --- a/src/components/tabs/tabs.ts +++ b/src/components/tabs/tabs.ts @@ -17,7 +17,7 @@ import { SimpleChange } from '@angular/core'; import { CoreTabComponent } from './tab'; -import { Content } from 'ionic-angular'; +import { Content, Slides } from 'ionic-angular'; /** * This component displays some tabs that usually share data between them. @@ -48,9 +48,16 @@ export class CoreTabsComponent implements OnInit, AfterViewInit, OnChanges { @Output() ionChange: EventEmitter = new EventEmitter(); // Emitted when the tab changes. @ViewChild('originalTabs') originalTabsRef: ElementRef; @ViewChild('topTabs') topTabs: ElementRef; + @ViewChild(Slides) slides: Slides; tabs: CoreTabComponent[] = []; // List of tabs. selected: number; // Selected tab number. + showPrevButton: boolean; + showNextButton: boolean; + maxSlides = 3; + slidesShown = this.maxSlides; + numTabsShown = 0; + protected originalTabsContainer: HTMLElement; // The container of the original tabs. It will include each tab's content. protected initialized = false; protected afterViewInitTriggered = false; @@ -77,10 +84,16 @@ export class CoreTabsComponent implements OnInit, AfterViewInit, OnChanges { */ ngAfterViewInit(): void { this.afterViewInitTriggered = true; + if (!this.initialized && this.hideUntil) { // Tabs should be shown, initialize them. this.initializeTabs(); } + + window.addEventListener('resize', () => { + this.calculateMaxSlides(); + this.updateSlides(); + }); } /** @@ -107,6 +120,7 @@ export class CoreTabsComponent implements OnInit, AfterViewInit, OnChanges { if (this.getIndex(tab) == -1) { this.tabs.push(tab); this.sortTabs(); + this.updateSlides(); if (this.initialized && this.tabs.length > 1 && this.tabBarHeight == 0) { // Calculate the tabBarHeight again now that there is more than 1 tab and the bar will be seen. @@ -190,9 +204,72 @@ export class CoreTabsComponent implements OnInit, AfterViewInit, OnChanges { } } + // Check which arrows should be shown + this.calculateMaxSlides(); + this.updateSlides(); + this.initialized = true; } + /** + * Method executed when the slides are changed. + */ + slideChanged(): void { + const currentIndex = this.slides.getActiveIndex(); + if (this.slidesShown >= this.numTabsShown) { + this.showPrevButton = false; + this.showNextButton = false; + } else if (typeof currentIndex !== 'undefined') { + this.showPrevButton = currentIndex > 0; + this.showNextButton = currentIndex < this.numTabsShown - this.slidesShown; + } else { + this.showPrevButton = false; + this.showNextButton = this.numTabsShown > this.slidesShown; + } + } + + /** + * Update slides. + */ + protected updateSlides(): void { + this.numTabsShown = this.tabs.reduce((prev: number, current: any) => { + return current.show ? prev + 1 : prev; + }, 0); + + this.slidesShown = Math.min(this.maxSlides, this.numTabsShown); + this.slides.update(); + this.slides.resize(); + + this.slideChanged(); + } + + protected calculateMaxSlides(): void { + if (this.slides && this.slides.renderedWidth) { + this.maxSlides = Math.floor(this.slides.renderedWidth / 120); + + return; + } + this.maxSlides = 3; + } + + /** + * Method that shows the next slide. + */ + slideNext(): void { + if (this.showNextButton) { + this.slides.slideNext(); + } + } + + /** + * Method that shows the previous slide. + */ + slidePrev(): void { + if (this.showPrevButton) { + this.slides.slidePrev(); + } + } + /** * Show or hide the tabs. This is used when the user is scrolling inside a tab. * @@ -221,6 +298,8 @@ export class CoreTabsComponent implements OnInit, AfterViewInit, OnChanges { removeTab(tab: CoreTabComponent): void { const index = this.getIndex(tab); this.tabs.splice(index, 1); + + this.updateSlides(); } /** @@ -252,6 +331,10 @@ export class CoreTabsComponent implements OnInit, AfterViewInit, OnChanges { currentTab.unselectTab(); } + if (this.selected) { + this.slides.slideTo(index); + } + this.selected = index; newTab.selectTab(); this.ionChange.emit(newTab);