Skip to content

Commit 30ed4ad

Browse files
mateusjmafjhonyeduardo
authored andcommitted
feat(tabs): habilita scroll horizontal das tabs em dispositivos moveis
Implementada verificação no tratamento de múltiplas abas para alternar o comportamento da exibição em telas pequenas (mobile). Fixes DTHFUI-1416
1 parent eee5463 commit 30ed4ad

File tree

5 files changed

+104
-33
lines changed

5 files changed

+104
-33
lines changed

projects/ui/src/lib/components/po-tabs/po-tab-button/po-tab-button.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
(click)="onClick()"
88
(keyup.enter)="onClick()">
99

10-
<span class="po-tab-button-label">
10+
<span class="po-tab-button-label po-text-ellipsis">
1111
{{label}}
1212
</span>
1313
</div>

projects/ui/src/lib/components/po-tabs/po-tabs-base.component.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ import { convertToBoolean } from '../../utils/util';
88
* O componente `po-tabs` é responsável por agrupar [abas](/documentation/po-tab) dispostas numa linha horizontal,
99
* ideal para facilitar a organização de conteúdos.
1010
*
11-
* Até cinco abas o componente exibe todas normalmente. Contudo, a partir de seis abas, o componente torna visível
12-
* apenas as quatro primeiras, agrupando todas as demais na quinta aba rotulada de **Mais**.
11+
* Em dispositivos móveis o componente exibirá tadas as abas de maneira linear gerando um *scroll* na horizontal. Já em telas telas com
12+
* resoluções maiores, o componente exibirá até cinco abas normalmente, porém, à partir de seis abas o componente automaticamente torna
13+
* visível apenas as quatro primeiras, agrupando as subsequentes na quinta aba rotulada de **Mais**.
1314
*
1415
* > As abas que estiverem agrupadas serão dispostas numa cascata suspensa que será exibida ao clicar no botão **Mais**.
1516
*
Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,38 @@
1-
<div class="po-tabs-header">
1+
<div class="po-tabs-container"
2+
[class.po-tabs-container-mobile]="isMobileDevice">
3+
<div class="po-tabs-header">
24

3-
<ng-container *ngFor="let tab of tabs; trackBy: trackByFn">
4-
<po-tab-button *ngIf="isVisibleTab(tab)"
5-
class="po-tab-button"
6-
[p-active]="tab.active"
7-
[p-disabled]="tab.disabled"
8-
[p-id]="tab.id"
9-
[p-hide]="tab.hide"
10-
[p-label]="tab.label"
11-
[p-small]="small"
12-
(keyup.enter)="closePopover()"
13-
(p-activated)="onTabActive(tab)"
14-
(p-change-state)="onTabChangeState(tab)"
15-
(p-click)="selectedTab(tab)">
16-
</po-tab-button>
17-
</ng-container>
5+
<ng-container *ngFor="let tab of tabs; trackBy: trackByFn">
6+
<po-tab-button *ngIf="isVisibleTab(tab)"
7+
class="po-tab-button"
8+
[class.po-tab-button-mobile]="isMobileDevice"
9+
[p-active]="tab.active"
10+
[p-disabled]="tab.disabled"
11+
[p-hide]="tab.hide"
12+
[p-id]="tab.id"
13+
[p-label]="tab.label"
14+
[p-small]="small"
15+
(keyup.enter)="closePopover()"
16+
(p-activated)="onTabActive(tab)"
17+
(p-change-state)="onTabChangeState(tab)"
18+
(p-click)="selectedTab(tab)">
19+
</po-tab-button>
20+
</ng-container>
1821

19-
<po-tab-dropdown #tabDropdown
20-
*ngIf="isShowTabDropdown"
21-
class="po-tab-button po-tab-dropdown"
22-
p-label="Mais"
23-
[p-small]="small"
24-
[p-tabs]="overflowedTabs"
25-
(p-activated)="onTabActive($event)"
26-
(p-change-state)="onTabChangeState($event)"
27-
(p-click)="selectedTab($event)">
28-
</po-tab-dropdown>
22+
<po-tab-dropdown #tabDropdown
23+
*ngIf="isShowTabDropdown"
24+
class="po-tab-button po-tab-dropdown"
25+
p-label="Mais"
26+
[p-small]="small"
27+
[p-tabs]="overflowedTabs"
28+
(p-activated)="onTabActive($event)"
29+
(p-change-state)="onTabChangeState($event)"
30+
(p-click)="selectedTab($event)">
31+
</po-tab-dropdown>
32+
</div>
2933
</div>
3034

31-
<div class="po-tabs-container">
35+
<div class="po-tabs-content">
3236
<ng-content></ng-content>
3337
</div>
3438

projects/ui/src/lib/components/po-tabs/po-tabs.component.spec.ts

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ import { By } from '@angular/platform-browser';
22
import { ComponentFixture, TestBed } from '@angular/core/testing';
33

44
import { configureTestSuite } from './../../util-test/util-expect.spec';
5+
import * as UtilsFunction from './../../utils/util';
56

67
import { PoTabsComponent } from './po-tabs.component';
78
import { PoTabsModule } from './po-tabs.module';
89

910
describe('PoTabsComponent:', () => {
1011
let component: PoTabsComponent;
1112
let fixture: ComponentFixture<PoTabsComponent>;
13+
let nativeElement: any;
1214

1315
let defaultTab;
1416
let activeTab;
@@ -33,6 +35,8 @@ describe('PoTabsComponent:', () => {
3335
hiddenTab = { id: '4', hide: true, label: 'Tab 4' };
3436

3537
fixture.detectChanges();
38+
39+
nativeElement = fixture.debugElement.nativeElement;
3640
});
3741

3842
it('should be created', () => {
@@ -49,13 +53,15 @@ describe('PoTabsComponent:', () => {
4953
expect(component.overflowedTabs).toEqual(overflowedTabs);
5054
});
5155

52-
it('isShowTabDropdown: should return `true` if `visibleTabs` is greater than `maxNumberOfTabs`', () => {
56+
it('isShowTabDropdown: should return `true` if `visibleTabs` is greater than `maxNumberOfTabs` and isn`t a mobile device.', () => {
57+
spyOn(UtilsFunction, <any> 'isMobile').and.returnValue(false);
5358
component.tabs = <any> [defaultTab, defaultTab, defaultTab, defaultTab, defaultTab, defaultTab];
5459

5560
expect(component.isShowTabDropdown).toBe(true);
5661
});
5762

58-
it('isShowTabDropdown: should return `false` if `visibleTabs` is lower than `maxNumberOfTabs`', () => {
63+
it('isShowTabDropdown: should return `false` if `visibleTabs` is lower than `maxNumberOfTabs` and is a mobile device.', () => {
64+
spyOn(UtilsFunction, <any> 'isMobile').and.returnValue(true);
5965
component.tabs = <any> [defaultTab, defaultTab, defaultTab, defaultTab];
6066

6167
expect(component.isShowTabDropdown).toBe(false);
@@ -248,6 +254,16 @@ describe('PoTabsComponent:', () => {
248254

249255
describe('Templates:', () => {
250256

257+
const sixTabs = <any> [
258+
{id: '0', label: '0'},
259+
{id: '1', label: '1'},
260+
{id: '2', label: '2'},
261+
{id: '3', label: '3'},
262+
{id: '4', label: '4'},
263+
{id: '5', label: '5'},
264+
{id: '6', label: '6'}
265+
];
266+
251267
it('should call `closePopover` if `enter` is pressed in `po-tab-button`.', () => {
252268
component.tabs = <any> [{id: '0', label: '0'}];
253269
fixture.detectChanges();
@@ -261,6 +277,46 @@ describe('PoTabsComponent:', () => {
261277
expect(spyOnClosePopover).toHaveBeenCalled();
262278
});
263279

280+
it('should display `po-tab-dropdown` if has six tabs or more and is not a mobile devide.', () => {
281+
component.tabs = sixTabs;
282+
spyOn(UtilsFunction, <any> 'isMobile').and.returnValue(false);
283+
284+
fixture.detectChanges();
285+
const poTabDropdown = nativeElement.querySelector('.po-tab-button.po-tab-dropdown');
286+
287+
expect(poTabDropdown).toBeTruthy();
288+
});
289+
290+
it('shouldn`t display `po-tab-dropdown` if has six tabs or more but is a mobile devide.', () => {
291+
component.tabs = sixTabs;
292+
spyOn(UtilsFunction, <any> 'isMobile').and.returnValue(true);
293+
294+
fixture.detectChanges();
295+
const poTabDropdown = nativeElement.querySelector('.po-tab-button.po-tab-dropdown');
296+
297+
expect(poTabDropdown).toBeNull();
298+
});
299+
300+
it('should find `po-tabs-container-mobile` if mobile device', () => {
301+
component.tabs = sixTabs;
302+
spyOn(UtilsFunction, <any> 'isMobile').and.returnValue(true);
303+
304+
fixture.detectChanges();
305+
const poTabContainerMobile = nativeElement.querySelector('.po-tabs-container-mobile');
306+
307+
expect(poTabContainerMobile).toBeTruthy();
308+
});
309+
310+
it('should find `po-tab-button-mobile` if mobile device', () => {
311+
component.tabs = sixTabs;
312+
spyOn(UtilsFunction, <any> 'isMobile').and.returnValue(true);
313+
314+
fixture.detectChanges();
315+
const poTabButtonMobile = nativeElement.querySelector('.po-tab-button-mobile');
316+
317+
expect(poTabButtonMobile).toBeTruthy();
318+
});
319+
264320
});
265321

266322
});

projects/ui/src/lib/components/po-tabs/po-tabs.component.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { ChangeDetectorRef, Component, ContentChildren, QueryList, ViewChild } from '@angular/core';
22

3+
import { isMobile } from './../../utils/util';
4+
35
import { PoTabComponent } from './po-tab/po-tab.component';
46
import { PoTabDropdownComponent } from './po-tab-dropdown/po-tab-dropdown.component';
57
import { PoTabsBaseComponent } from './po-tabs-base.component';
@@ -50,8 +52,12 @@ export class PoTabsComponent extends PoTabsBaseComponent {
5052
super();
5153
}
5254

55+
get isMobileDevice() {
56+
return isMobile();
57+
}
58+
5359
get isShowTabDropdown() {
54-
return this.visibleTabs.length > this.maxNumberOfTabs;
60+
return !this.isMobileDevice && this.visibleTabs.length > this.maxNumberOfTabs;
5561
}
5662

5763
// tabs que serão apresentadas na aba "Mais"
@@ -72,6 +78,10 @@ export class PoTabsComponent extends PoTabsBaseComponent {
7278
}
7379

7480
isVisibleTab(tab) {
81+
if (this.isMobileDevice) {
82+
return true;
83+
}
84+
7585
const visibleTabIndex = this.visibleTabs.findIndex(visibleTab => visibleTab.id === tab.id);
7686

7787
return (this.visibleTabs.length <= this.maxNumberOfTabs) || (visibleTabIndex < (this.maxNumberOfTabs - 1));

0 commit comments

Comments
 (0)