Skip to content
This repository has been archived by the owner on May 29, 2019. It is now read-only.

Commit

Permalink
feat(tabs): add the ability to set the direction of the tabs
Browse files Browse the repository at this point in the history
Add the ability to set the direction of the tabs, the possible
values are 'right', 'left' and 'below'. If no direction is defined
the tabs are rendered on the top as they do now

Closes #659
  • Loading branch information
lgalfaso authored and ajoslin committed Jul 27, 2013
1 parent d9e5bc9 commit 220e7b6
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 7 deletions.
34 changes: 31 additions & 3 deletions src/tabs/tabs.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ function TabsetCtrl($scope, $element) {
* Tabset is the outer container for the tabs directive
*
* @param {boolean=} vertical Whether or not to use vertical styling for the tabs.
* @param {string=} direction What direction the tabs should be rendered. Available:
* 'right', 'left', 'below'.
*
* @example
<example module="ui.bootstrap">
Expand All @@ -77,12 +79,19 @@ function TabsetCtrl($scope, $element) {
restrict: 'EA',
transclude: true,
replace: true,
require: '^tabset',
scope: {},
controller: 'TabsetController',
templateUrl: 'template/tabs/tabset.html',
link: function(scope, element, attrs) {
scope.vertical = angular.isDefined(attrs.vertical) ? scope.$eval(attrs.vertical) : false;
scope.type = angular.isDefined(attrs.type) ? scope.$parent.$eval(attrs.type) : 'tabs';
compile: function(elm, attrs, transclude) {
return function(scope, element, attrs, tabsetCtrl) {
scope.vertical = angular.isDefined(attrs.vertical) ? scope.$eval(attrs.vertical) : false;
scope.type = angular.isDefined(attrs.type) ? scope.$parent.$eval(attrs.type) : 'tabs';
scope.direction = angular.isDefined(attrs.direction) ? scope.$parent.$eval(attrs.direction) : 'top';
scope.tabsAbove = (scope.direction != 'below');
tabsetCtrl.$scope = scope;
tabsetCtrl.$transcludeFn = transclude;
};
}
};
})
Expand Down Expand Up @@ -284,5 +293,24 @@ function($parse, $http, $templateCache, $compile) {
}
}])

.directive('tabsetTitles', function($http) {
return {
restrict: 'A',
require: '^tabset',
templateUrl: 'template/tabs/tabset-titles.html',
replace: true,
link: function(scope, elm, attrs, tabsetCtrl) {
if (!scope.$eval(attrs.tabsetTitles)) {
elm.remove();
} else {
//now that tabs location has been decided, transclude the tab titles in
tabsetCtrl.$transcludeFn(tabsetCtrl.$scope.$parent, function(node) {
elm.append(node);
});
}
}
};
})

;

52 changes: 51 additions & 1 deletion src/tabs/test/tabsSpec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
describe('tabs', function() {
beforeEach(module('ui.bootstrap.tabs', 'template/tabs/tabset.html', 'template/tabs/tab.html'));
beforeEach(module('ui.bootstrap.tabs', 'template/tabs/tabset.html', 'template/tabs/tab.html', 'template/tabs/tabset-titles.html'));

var elm, scope;
function titles() {
Expand Down Expand Up @@ -493,6 +493,56 @@ describe('tabs', function() {
});
});

describe('direction', function() {
it('should not have `tab-left`, `tab-right` nor `tabs-below` classes if the direction is undefined', inject(function($compile, $rootScope) {
scope = $rootScope.$new();
scope.direction = undefined;

elm = $compile('<tabset direction="direction"></tabset>')(scope);
scope.$apply();
expect(elm).not.toHaveClass('tabs-left');
expect(elm).not.toHaveClass('tabs-right');
expect(elm).not.toHaveClass('tabs-below');
expect(elm.find('.nav + .tab-content').length).toBe(1);
}));

it('should only have the `tab-left` direction class if the direction is "left"', inject(function($compile, $rootScope) {
scope = $rootScope.$new();
scope.direction = 'left';

elm = $compile('<tabset direction="direction"></tabset>')(scope);
scope.$apply();
expect(elm).toHaveClass('tabs-left');
expect(elm).not.toHaveClass('tabs-right');
expect(elm).not.toHaveClass('tabs-below');
expect(elm.find('.nav + .tab-content').length).toBe(1);
}));

it('should only have the `tab-right direction class if the direction is "right"', inject(function($compile, $rootScope) {
scope = $rootScope.$new();
scope.direction = 'right';

elm = $compile('<tabset direction="direction"></tabset>')(scope);
scope.$apply();
expect(elm).not.toHaveClass('tabs-left');
expect(elm).toHaveClass('tabs-right');
expect(elm).not.toHaveClass('tabs-below');
expect(elm.find('.nav + .tab-content').length).toBe(1);
}));

it('should only have the `tab-below direction class if the direction is "below"', inject(function($compile, $rootScope) {
scope = $rootScope.$new();
scope.direction = 'below';

elm = $compile('<tabset direction="direction"></tabset>')(scope);
scope.$apply();
expect(elm).not.toHaveClass('tabs-left');
expect(elm).not.toHaveClass('tabs-right');
expect(elm).toHaveClass('tabs-below');
expect(elm.find('.tab-content + .nav').length).toBe(1);
}));
});

//https://github.com/angular-ui/bootstrap/issues/524
describe('child compilation', function() {

Expand Down
2 changes: 2 additions & 0 deletions template/tabs/tabset-titles.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<ul class="nav {{type && 'nav-' + type}}" ng-class="{'nav-stacked': vertical}">
</ul>
6 changes: 3 additions & 3 deletions template/tabs/tabset.html
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@

<div class="tabbable">
<ul class="nav {{type && 'nav-' + type}}" ng-class="{'nav-stacked': vertical}" ng-transclude>
</ul>
<div class="tabbable" ng-class="{'tabs-right': direction == 'right', 'tabs-left': direction == 'left', 'tabs-below': direction == 'below'}">
<div tabset-titles="tabsAbove"></div>
<div class="tab-content">
<div class="tab-pane"
ng-repeat="tab in tabs"
ng-class="{active: tab.active}"
tab-content-transclude="tab">
</div>
</div>
<div tabset-titles="!tabsAbove"></div>
</div>

0 comments on commit 220e7b6

Please sign in to comment.