Skip to content

Commit

Permalink
feat(tabset): add nav justification and orientation
Browse files Browse the repository at this point in the history
Closes #1472
Closes #1239
  • Loading branch information
ktriek authored and pkozlowski-opensource committed Aug 17, 2017
1 parent 9447f5d commit 73ba757
Show file tree
Hide file tree
Showing 9 changed files with 191 additions and 9 deletions.
16 changes: 14 additions & 2 deletions demo/src/app/components/tabset/demos/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@ import {NgbdTabsetPills} from './pills/tabset-pills';
import {NgbdTabsetPreventchange} from './preventchange/tabset-preventchange';
import {NgbdTabsetSelectbyid} from './selectbyid/tabset-selectbyid';
import {NgbdTabsetConfig} from './config/tabset-config';
import {NgbdTabsetJustify} from './justify/tabset-justify';
import {NgbdTabsetOrientation} from './orientation/tabset-orientation';

export const DEMO_DIRECTIVES =
[NgbdTabsetBasic, NgbdTabsetPills, NgbdTabsetPreventchange, NgbdTabsetSelectbyid, NgbdTabsetConfig];
export const DEMO_DIRECTIVES = [
NgbdTabsetBasic, NgbdTabsetPills, NgbdTabsetPreventchange, NgbdTabsetSelectbyid,
NgbdTabsetConfig, NgbdTabsetJustify, NgbdTabsetOrientation
];

export const DEMO_SNIPPETS = {
'basic': {
Expand All @@ -24,6 +28,14 @@ export const DEMO_SNIPPETS = {
'code': require('!!prismjs-loader?lang=typescript!./selectbyid/tabset-selectbyid'),
'markup': require('!!prismjs-loader?lang=markup!./selectbyid/tabset-selectbyid.html')
},
'justify': {
'code': require('!!prismjs-loader?lang=typescript!./justify/tabset-justify'),
'markup': require('!!prismjs-loader?lang=markup!./justify/tabset-justify.html')
},
'orientation': {
'code': require('!!prismjs-loader?lang=typescript!./orientation/tabset-orientation'),
'markup': require('!!prismjs-loader?lang=markup!./orientation/tabset-orientation.html')
},
'config': {
'code': require('!!prismjs-loader?lang=typescript!./config/tabset-config'),
'markup': require('!!prismjs-loader?lang=markup!./config/tabset-config.html')
Expand Down
47 changes: 47 additions & 0 deletions demo/src/app/components/tabset/demos/justify/tabset-justify.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<ngb-tabset [justify]="currentJustify">
<ngb-tab title="Simple">
<ng-template ngbTabContent>
<p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth
master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh
dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum
iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
</ng-template>
</ngb-tab>
<ngb-tab>
<ng-template ngbTabTitle><b>Fancy</b> title</ng-template>
<ng-template ngbTabContent>Food truck fixie locavore, accusamus mcsweeney's marfa nulla single-origin coffee squid.
<p>Exercitation +1 labore velit, blog sartorial PBR leggings next level wes anderson artisan four loko farm-to-table
craft beer twee. Qui photo booth letterpress, commodo enim craft beer mlkshk aliquip jean shorts ullamco ad vinyl
cillum PBR. Homo nostrud organic, assumenda labore aesthetic magna delectus mollit. Keytar helvetica VHS salvia
yr, vero magna velit sapiente labore stumptown. Vegan fanny pack odio cillum wes anderson 8-bit, sustainable jean
shorts beard ut DIY ethical culpa terry richardson biodiesel. Art party scenester stumptown, tumblr butcher vero
sint qui sapiente accusamus tattooed echo park.</p>
</ng-template>
</ngb-tab>
<ngb-tab title="A very long nav title">
<ng-template ngbTabContent>
<p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth
master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh
dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum
iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
</ng-template>
</ngb-tab>
</ngb-tabset>

<div class="btn-group" ngbRadioGroup [(ngModel)]="currentJustify">
<label ngbButtonLabel class="btn-outline-primary btn-sm">
<input ngbButton type="radio" value="start">Start
</label>
<label ngbButtonLabel class="btn-outline-primary btn-sm">
<input ngbButton type="radio" value="center">Center
</label>
<label ngbButtonLabel class="btn-outline-primary btn-sm">
<input ngbButton type="radio" value="end">End
</label>
<label ngbButtonLabel class="btn-outline-primary btn-sm">
<input ngbButton type="radio" value="fill">Fill
</label>
<label ngbButtonLabel class="btn-outline-primary btn-sm">
<input ngbButton type="radio" value="justified">Justified
</label>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {Component} from '@angular/core';

@Component({
selector: 'ngbd-tabset-justify',
templateUrl: './tabset-justify.html'
})
export class NgbdTabsetJustify {
currentJustify = 'start';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<ngb-tabset type="pills" [orientation]="currentOrientation">
<ngb-tab title="Simple">
<ng-template ngbTabContent>
<p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth
master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh
dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum
iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
</ng-template>
</ngb-tab>
<ngb-tab>
<ng-template ngbTabTitle><b>Fancy</b> title</ng-template>
<ng-template ngbTabContent>Food truck fixie locavore, accusamus mcsweeney's marfa nulla single-origin coffee squid.
<p>Exercitation +1 labore velit, blog sartorial PBR leggings next level wes anderson artisan four loko farm-to-table
craft beer twee. Qui photo booth letterpress, commodo enim craft beer mlkshk aliquip jean shorts ullamco ad vinyl
cillum PBR. Homo nostrud organic, assumenda labore aesthetic magna delectus mollit. Keytar helvetica VHS salvia
yr, vero magna velit sapiente labore stumptown. Vegan fanny pack odio cillum wes anderson 8-bit, sustainable jean
shorts beard ut DIY ethical culpa terry richardson biodiesel. Art party scenester stumptown, tumblr butcher vero
sint qui sapiente accusamus tattooed echo park.</p>
</ng-template>
</ngb-tab>
<ngb-tab title="Disabled" [disabled]="true">
<ng-template ngbTabContent>
<p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth
master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh
dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum
iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
</ng-template>
</ngb-tab>
</ngb-tabset>

<div class="btn-group" ngbRadioGroup [(ngModel)]="currentOrientation">
<label ngbButtonLabel class="btn-outline-primary btn-sm">
<input ngbButton type="radio" value="horizontal">Horizontal
</label>
<label ngbButtonLabel class="btn-outline-primary btn-sm">
<input ngbButton type="radio" value="vertical">Vertical
</label>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {Component} from '@angular/core';

@Component({
selector: 'ngbd-tabset-orientation',
templateUrl: './tabset-orientation.html'
})
export class NgbdTabsetOrientation {
currentOrientation = 'horizontal';
}
6 changes: 6 additions & 0 deletions demo/src/app/components/tabset/tabset.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ import {DEMO_SNIPPETS} from './demos';
<ngbd-example-box demoTitle="Prevent tab change" [snippets]="snippets" component="tabset" demo="preventchange">
<ngbd-tabset-preventchange></ngbd-tabset-preventchange>
</ngbd-example-box>
<ngbd-example-box demoTitle="Nav justification" [snippets]="snippets" component="tabset" demo="justify">
<ngbd-tabset-justify></ngbd-tabset-justify>
</ngbd-example-box>
<ngbd-example-box demoTitle="Nav orientation" [snippets]="snippets" component="tabset" demo="orientation">
<ngbd-tabset-orientation></ngbd-tabset-orientation>
</ngbd-example-box>
<ngbd-example-box demoTitle="Global configuration of tabs" [snippets]="snippets" component="tabset" demo="config">
<ngbd-tabset-config></ngbd-tabset-config>
</ngbd-example-box>
Expand Down
3 changes: 2 additions & 1 deletion src/tabset/tabset-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {Injectable} from '@angular/core';
*/
@Injectable()
export class NgbTabsetConfig {
justify: 'start' | 'center' | 'end' = 'start';
justify: 'start' | 'center' | 'end' | 'fill' | 'justified' = 'start';
orientation: 'horizontal' | 'vertical' = 'horizontal';
type: 'tabs' | 'pills' = 'tabs';
}
48 changes: 45 additions & 3 deletions src/tabset/tabset.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ describe('ngb-tabset', () => {
expect(fixture.nativeElement.querySelector('ul')).not.toHaveCssClass('nav-tabs');
});

it('should have the nav left-aligned by default', () => {
it('should have the "justify-content-start" class by default', () => {
const fixture = createTestComponent(`
<ngb-tabset>
<ngb-tab title="bar"><ng-template ngbTabContent>Bar</ng-template></ngb-tab>
Expand All @@ -305,7 +305,7 @@ describe('ngb-tabset', () => {
expect(fixture.nativeElement.querySelector('ul')).toHaveCssClass('justify-content-start');
});

it('should have the nav center-aligned upon setting justify center', () => {
it('should have the "justify-content-center" class upon setting justify to center', () => {
const fixture = createTestComponent(`
<ngb-tabset justify="center">
<ngb-tab title="bar"><ng-template ngbTabContent>Bar</ng-template></ngb-tab>
Expand All @@ -315,7 +315,7 @@ describe('ngb-tabset', () => {
expect(fixture.nativeElement.querySelector('ul')).toHaveCssClass('justify-content-center');
});

it('should have the nav right-aligned upon setting justify end', () => {
it('should have the "justify-content-end" upon setting justify to end', () => {
const fixture = createTestComponent(`
<ngb-tabset justify="end">
<ngb-tab title="bar"><ng-template ngbTabContent>Bar</ng-template></ngb-tab>
Expand All @@ -325,6 +325,48 @@ describe('ngb-tabset', () => {
expect(fixture.nativeElement.querySelector('ul')).toHaveCssClass('justify-content-end');
});

it('should have the "nav-fill" class upon setting justify to fill', () => {
const fixture = createTestComponent(`
<ngb-tabset justify="fill">
<ngb-tab title="bar"><ng-template ngbTabContent>Bar</ng-template></ngb-tab>
</ngb-tabset>
`);

expect(fixture.nativeElement.querySelector('ul')).toHaveCssClass('nav-fill');
});

it('should have the "nav-justified" class upon setting justify to justified', () => {
const fixture = createTestComponent(`
<ngb-tabset justify="justified">
<ngb-tab title="bar"><ng-template ngbTabContent>Bar</ng-template></ngb-tab>
</ngb-tabset>
`);

expect(fixture.nativeElement.querySelector('ul')).toHaveCssClass('nav-justified');
});

it('should have the "justify-content-start" class upon setting orientation to horizontal', () => {
const fixture = createTestComponent(`
<ngb-tabset orientation="horizontal">
<ngb-tab title="bar"><ng-template ngbTabContent>Bar</ng-template></ngb-tab>
</ngb-tabset>
`);

expect(fixture.nativeElement.querySelector('ul')).not.toHaveCssClass('flex-column');
expect(fixture.nativeElement.querySelector('ul')).toHaveCssClass('justify-content-start');
});

it('should have the "flex-column" class upon setting orientation to vertical', () => {
const fixture = createTestComponent(`
<ngb-tabset orientation="vertical">
<ngb-tab title="bar"><ng-template ngbTabContent>Bar</ng-template></ngb-tab>
</ngb-tabset>
`);

expect(fixture.nativeElement.querySelector('ul')).toHaveCssClass('flex-column');
expect(fixture.nativeElement.querySelector('ul')).not.toHaveCssClass('justify-content-start');
});


it('should change active tab by calling select on an exported directive instance', () => {
const fixture = createTestComponent(`
Expand Down
24 changes: 21 additions & 3 deletions src/tabset/tabset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export interface NgbTabChangeEvent {
selector: 'ngb-tabset',
exportAs: 'ngbTabset',
template: `
<ul [class]="'nav nav-' + type + ' justify-content-' + justify" role="tablist">
<ul [class]="'nav nav-' + type + (orientation == 'horizontal'? ' ' + justifyClass : ' flex-column')" role="tablist">
<li class="nav-item" *ngFor="let tab of tabs">
<a [id]="tab.id" class="nav-link" [class.active]="tab.id === activeId" [class.disabled]="tab.disabled"
href (click)="!!select(tab.id)" role="tab" [attr.tabindex]="(tab.disabled ? '-1': undefined)"
Expand All @@ -104,6 +104,8 @@ export interface NgbTabChangeEvent {
`
})
export class NgbTabset implements AfterContentChecked {
justifyClass: string;

@ContentChildren(NgbTab) tabs: QueryList<NgbTab>;

/**
Expand All @@ -117,9 +119,24 @@ export class NgbTabset implements AfterContentChecked {
@Input() destroyOnHide: boolean = true;

/**
* The horizontal alignment of the nav with flexbox utilities. Can be one of 'start', 'center' or 'end'
* The horizontal alignment of the nav with flexbox utilities. Can be one of 'start', 'center', 'end', 'fill' or
* 'justified'
* The default value is 'start'.
*/
@Input()
set justify(className: 'start' | 'center' | 'end' | 'fill' | 'justified') {
if (className === 'fill' || className === 'justified') {
this.justifyClass = `nav-${className}`;
} else {
this.justifyClass = `justify-content-${className}`;
}
}

/**
* The orientation of the nav (horizontal or vertical).
* The default value is 'horizontal'.
*/
@Input() justify: 'start' | 'center' | 'end';
@Input() orientation: 'horizontal' | 'vertical';

/**
* Type of navigation to be used for tabs. Can be one of 'tabs' or 'pills'.
Expand All @@ -134,6 +151,7 @@ export class NgbTabset implements AfterContentChecked {
constructor(config: NgbTabsetConfig) {
this.type = config.type;
this.justify = config.justify;
this.orientation = config.orientation;
}

/**
Expand Down

0 comments on commit 73ba757

Please sign in to comment.