diff --git a/src/button/button.js b/src/button/button.js
new file mode 100644
index 0000000000..ffcb39dc9e
--- /dev/null
+++ b/src/button/button.js
@@ -0,0 +1,33 @@
+angular.module('ui.bootstrap.button', [])
+
+ .directive('button', ['$parse', function($parse) {
+ return {
+ restrict: 'E',
+ compile:function (tElement, tAttrs, transclude) {
+ tElement.addClass('btn');
+ return function (scope, element, attrs) {
+ if (attrs.toggle){
+
+ var exprGetter = $parse(attrs.toggle);
+ var exprSetter = exprGetter.assign;
+
+ //watch model changes
+ scope.$watch(attrs.toggle, function(newVal){
+ if (newVal) {
+ element.addClass('active');
+ } else {
+ element.removeClass('active');
+ }
+ });
+
+ //watch click events
+ element.bind('click', function(){
+ scope.$apply(function(){
+ exprSetter(scope, !exprGetter(scope));
+ });
+ });
+ }
+ };
+ }
+ };
+ }]);
\ No newline at end of file
diff --git a/src/button/docs/demo.html b/src/button/docs/demo.html
new file mode 100644
index 0000000000..ef73338834
--- /dev/null
+++ b/src/button/docs/demo.html
@@ -0,0 +1,14 @@
+
+
+
Single toggle
+
+
{{single | json}}
+
+
Checkbox
+
+
+
+
+
+
{{group | json}}
+
\ No newline at end of file
diff --git a/src/button/docs/demo.js b/src/button/docs/demo.js
new file mode 100644
index 0000000000..9eac491651
--- /dev/null
+++ b/src/button/docs/demo.js
@@ -0,0 +1,11 @@
+var ButtonCtrl = function ($scope) {
+ $scope.single = {
+ selected: true
+ };
+
+ $scope.group = {
+ left:false,
+ middle:true,
+ right:false
+ };
+};
\ No newline at end of file
diff --git a/src/button/docs/readme.md b/src/button/docs/readme.md
new file mode 100644
index 0000000000..cb397a0097
--- /dev/null
+++ b/src/button/docs/readme.md
@@ -0,0 +1,3 @@
+The `button` directive will style all the buttons with the `btn` class.
+
+Additionally it adds support for the `toggle='expression'` attribute. This attribute, if pointed to an assignable expression, will turn a button into a fancy check-box.
\ No newline at end of file
diff --git a/src/button/test/button.spec.js b/src/button/test/button.spec.js
new file mode 100644
index 0000000000..afc0cafb3f
--- /dev/null
+++ b/src/button/test/button.spec.js
@@ -0,0 +1,49 @@
+describe('button', function () {
+
+ var $rootScope, $compile;
+ beforeEach(module('ui.bootstrap.button'));
+ beforeEach(inject(function (_$rootScope_, _$compile_) {
+ $rootScope = _$rootScope_;
+ $compile = _$compile_;
+ }));
+
+ describe('initial state', function () {
+ it('should render button without active class if no toggle attribute present selected', function () {
+ var elm = $compile('')($rootScope);
+ $rootScope.$digest();
+
+ expect(elm).toHaveClass('btn');
+ expect(elm).not.toHaveClass('active');
+ });
+
+ it('should render button without active class if the toggle attribute evaluates to false', function () {
+ var elm = $compile('')($rootScope);
+ $rootScope.$apply('selected = false');
+
+ expect(elm).toHaveClass('btn');
+ expect(elm).not.toHaveClass('active');
+ });
+
+ it('should render button with active class if the toggle attribute evaluates to true', function () {
+ var elm = $compile('')($rootScope);
+ $rootScope.$apply('selected = true');
+
+ expect(elm).toHaveClass('btn');
+ expect(elm).toHaveClass('active');
+ });
+ });
+
+ describe('click event', function () {
+
+ it('should toggle class on click if the toggle attribute is present', function () {
+ var elm = $compile('')($rootScope);
+ $rootScope.$apply('selected = true');
+
+ expect($rootScope.selected).toEqual(true);
+ elm.click();
+ expect($rootScope.selected).toEqual(false);
+ elm.click();
+ expect($rootScope.selected).toEqual(true);
+ });
+ });
+});
\ No newline at end of file