Skip to content

Commit

Permalink
feat(bsProgressbar): add bsProgressbar directive
Browse files Browse the repository at this point in the history
add a directive for a progress bar, with tests and docs

resolve mgcrea#379
  • Loading branch information
DaveWM authored and Richard Zschech committed Nov 11, 2016
1 parent 679fa05 commit b9e775a
Show file tree
Hide file tree
Showing 8 changed files with 242 additions and 1 deletion.
9 changes: 9 additions & 0 deletions docs/views/partials/affixed-sidebar.html
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,15 @@
</li>
</ul>
</li>
<li>
<a href="#progressbar">Progress Bar</a>
<ul class="nav">
<li><a href="#progressbar-examples">Examples</a>
</li>
<li><a href="#progressbar-usage">Usage</a>
</li>
</ul>
</li>
<!--
<li>
Expand Down
9 changes: 9 additions & 0 deletions docs/views/partials/sidebar.html
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,15 @@
</li>
</ul>
</li>
<li>
<a href="#progressbar">Progress Bar</a>
<ul class="nav">
<li><a href="#progressbar-examples">Examples</a>
</li>
<li><a href="#progressbar-usage">Usage</a>
</li>
</ul>
</li>
<!--
<li>
Expand Down
3 changes: 2 additions & 1 deletion src/module.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ angular.module('mgcrea.ngStrap', [
'mgcrea.ngStrap.scrollspy',
'mgcrea.ngStrap.affix',
'mgcrea.ngStrap.tab',
'mgcrea.ngStrap.collapse'
'mgcrea.ngStrap.collapse',
'mgcrea.ngStrap.progressbar'
]);
76 changes: 76 additions & 0 deletions src/progressbar/docs/progressbar.demo.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<div class="bs-docs-section" ng-controller="ProgressbarDemoCtrl">

<div class="page-header">
<h1 id="progressbar">Progress Bar <a class="small" href="//github.com/mgcrea/angular-strap/blob/master/src/progressbar/progressbar.js" target="_blank">progressbar.js</a>
</h1>
<code>mgcrea.ngStrap.progressbar</code>
</div>


<h2 id="progressbar-examples">Examples</h2>
<p>Add an animated progress bar.</p>

<h3>Live demo <a class="small edit-plunkr" data-module-name="mgcrea.ngStrapDocs" data-content-html-url="progressbar/docs/progressbar.demo.html" data-content-js-url="progressbar/docs/progressbar.demo.js" ng-plunkr data-title="edit in plunker" data-placement="right" bs-tooltip></a></h3>
<div class="bs-example" append-source>
<bs-progressbar value="value">{{value}}%</bs-progressbar>
</div>

<h2 id="progressbar-usage">Usage</h2>
<p>Add a <code>bs-progressbar</code> element to create a progress bar</p>
<p>HTML within the <code>bs-progressbar</code> element will be transcluded.</p>


<h3>Options</h3>
<p>Options can be passed via data attributes, append the option name to <code>data-</code>, as in <code>data-route-attr=""</code>.</p>
<div class="table-responsive">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th style="width: 100px;">Name</th>
<th style="width: 100px;">type</th>
<th style="width: 50px;">default</th>
<th>description</th>
</tr>
</thead>
<tbody>
<tr>
<td>value</td>
<td>number</td>
<td>0</td>
<td>Current value of the progress bar. Should be between 0 and 100.</td>
</tr>
<tr>
<td>animate</td>
<td>boolean expression</td>
<td>true</td>
<td>Toggles whether the progress bar is animated.</td>
</tr>
<tr>
<td>type</td>
<td>string</td>
<td>null</td>
<td>Determines the type of the progress bar. Can be success, info, warning, danger, or null for the default type.</td>
</tr>
</tbody>
</table>
</div>
<div class="callout callout-info">
<h4>Default options</h4>
<p>You can override global defaults for the plugin with <code>$progressbar.defaults</code></p>
<div class="highlight">
<pre class="bs-exemple-code">
<code class="javascript" highlight-block>
angular.module('myApp')
.config(function($progressbar) {
angular.extend($progressbar.defaults, {
animate: false,
barType: 'warning'
});
})
</code>
</pre>
</div>
</div>

</div>

14 changes: 14 additions & 0 deletions src/progressbar/docs/progressbar.demo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
'use strict';

angular.module('mgcrea.ngStrapDocs')

.controller('ProgressbarDemoCtrl', function($scope, $interval) {
$scope.value = 50;

$interval(function (){
if($scope.value < 100)
$scope.value+=10;
else
$scope.value = 0;
}, 2000);
});
40 changes: 40 additions & 0 deletions src/progressbar/progressbar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
'use strict';

angular.module('mgcrea.ngStrap.progressbar', [])
.provider('$progressbar', function (){
var defaults = {
barType: '',
animate: function (){ return true;}
};

this.$get = function (){
return {
defaults: defaults
};
};
})
.directive('bsProgressbar', function ($progressbar){
return {
restrict: 'E',
transclude: true,
replace: true,
templateUrl: 'progressbar/progressbar.tpl.html',
scope:{
value: '=',
type: '@',
animate: '&'
},
link: function (scope, element, attr){
scope.type = scope.type || $progressbar.defaults.barType;
scope.animate = angular.isDefined(scope.animate()) ? scope.animate : $progressbar.defaults.animate;
scope.$watch('type', function (){
if(scope.type) {
scope.barClass = 'progress-bar-' + scope.type;
}
else{
scope.barClass = null;
}
});
}
};
});
8 changes: 8 additions & 0 deletions src/progressbar/progressbar.tpl.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<div class="progress">
<div class="progress-bar" ng-class="barClass" role="progressbar" aria-valuenow="{{value}}"
aria-valuemin="0" aria-valuemax="100"
ng-style="{width: value + '%', 'webkit-transition': animate() ? null : 'none', 'transition': animate() ? null : 'none'}">
<span class="sr-only">{{value}}%</span>
<div ng-transclude></div>
</div>
</div>
84 changes: 84 additions & 0 deletions src/progressbar/test/progressbar.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
'use strict';

describe('progressbar', function () {
beforeEach(module('mgcrea.ngStrap.progressbar'));

var templates = {
'default': {
element: '<bs-progressbar animate="animate" type="{{type}}" value="value"><span>{{value}}%</span></bs-progressbar>',
scope: {
value: 50
}
}
};
var scope, $compile;
beforeEach(inject(function (_$compile_, $rootScope){
$compile = _$compile_;
scope = $rootScope.$new();
}));

afterEach(function() {
scope.$destroy();
});

function compileDirective(template, locals) {
template = templates[template];
angular.extend(scope, angular.copy(template.scope || templates['default'].scope), locals);
var element = $compile(template.element)(scope);
scope.$digest();
return jQuery(element[0]);
}

it("should correctly compile the inner content", function (){
var element = compileDirective('default');
expect(element.hasClass('progress')).toBe(true);

var bar = element.children().eq(0);
expect(bar.hasClass('progress-bar')).toBe(true);
expect(bar.css('width')).toBe(scope.value + '%');
expect(bar.attr('aria-valuenow')).toBe(scope.value.toString());
expect(bar.attr('aria-valuemin')).toBe('0');
expect(bar.attr('aria-valuemax')).toBe('100');

var srValue = bar.children().eq(0);
expect(srValue.text()).toBe(scope.value+'%');

var transcludedElem = bar.children().eq(1);
expect(transcludedElem.text()).toBe(scope.value+'%');
});

it("should update the progress bar width when the value is changed", function (){
var element = compileDirective('default');
var bar = element.children().eq(0);

expect(bar.css('width')).toBe(scope.value + '%');
scope.value = 10;
scope.$digest();
expect(bar.css('width')).toBe(scope.value + '%');
});

it("should disable css transitions if and only if animate is false", function (){
scope.animate = false;
var element = compileDirective('default');
var bar = element.children().eq(0);
// look for webkit transition because phantomjs doesn't support the "transition" css property
expect(bar.css('webkit-transition')).toBe('none');

scope.animate = true;
scope.$digest();
expect(bar.css('webkit-transition')).toBeFalsy();
});

it("should use the specified type of progress bar", function (){
scope.type = 'success';
var element = compileDirective('default');
var bar = element.children().eq(0);

expect(bar.hasClass('progress-bar-success')).toBe(true);

scope.type = "info";
scope.$digest();
expect(bar.hasClass('progress-bar-info')).toBe(true);
expect(bar.hasClass('progress-bar-success')).toBe(false);
});
});

0 comments on commit b9e775a

Please sign in to comment.