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

feat(collapse): add possibility to collapse horizontally #6010

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 97 additions & 36 deletions src/collapse/collapse.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,26 @@ angular.module('ui.bootstrap.collapse', [])
var expandingExpr = $parse(attrs.expanding),
expandedExpr = $parse(attrs.expanded),
collapsingExpr = $parse(attrs.collapsing),
collapsedExpr = $parse(attrs.collapsed);
collapsedExpr = $parse(attrs.collapsed),
horizontal = false;

horizontal = !!('horizontal' in attrs);

if (!scope.$eval(attrs.uibCollapse)) {
element.addClass('in')
.addClass('collapse')
.attr('aria-expanded', true)
.attr('aria-hidden', false)
.css({height: 'auto'});
if (horizontal) {
element.addClass('in')
.addClass('collapse')
.attr('aria-expanded', true)
.attr('aria-hidden', false)
.css({width: 'auto'})
.css({height: 'inherit'});
} else {
element.addClass('in')
.addClass('collapse')
.attr('aria-expanded', true)
.attr('aria-hidden', false)
.css({height: 'auto'});
}
}

function expand() {
Expand All @@ -29,24 +41,44 @@ angular.module('ui.bootstrap.collapse', [])
.attr('aria-expanded', true)
.attr('aria-hidden', false);

if ($animateCss) {
$animateCss(element, {
addClass: 'in',
easing: 'ease',
to: { height: element[0].scrollHeight + 'px' }
}).start()['finally'](expandDone);
if (horizontal) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It probably would be worthwhile converting everything in here into a helper function to avoid duplication between horizontal and vertical collapsing.

if ($animateCss) {
$animateCss(element, {
addClass: 'in',
easing: 'ease',
to: {width: element[0].scrollWidth + 'px'}
}).start()['finally'](expandDone);
} else {
$animate.addClass(element, 'in', {
to: {width: element[0].scrollWidth + 'px'}
}).then(expandDone);
}
} else {
$animate.addClass(element, 'in', {
to: { height: element[0].scrollHeight + 'px' }
}).then(expandDone);
if ($animateCss) {
$animateCss(element, {
addClass: 'in',
easing: 'ease',
to: {height: element[0].scrollHeight + 'px'}
}).start()['finally'](expandDone);
} else {
$animate.addClass(element, 'in', {
to: {height: element[0].scrollHeight + 'px'}
}).then(expandDone);
}
}
});
}

function expandDone() {
Copy link
Contributor

@wesleycho wesleycho Jun 15, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modify function so we can DRY this up, i.e.

function expandDone(prop) {
  return function() {
    var css = {};
    css[prop] = 'auto';
    ...
  };
}

Or just pass the desired object wholesale

element.removeClass('collapsing')
.addClass('collapse')
.css({height: 'auto'});
if (horizontal) {
element.removeClass('collapsing')
.addClass('collapse')
.css({width: 'auto'});
} else {
element.removeClass('collapsing')
.addClass('collapse')
.css({height: 'auto'});
}
expandedExpr(scope);
}

Expand All @@ -57,33 +89,62 @@ angular.module('ui.bootstrap.collapse', [])

$q.resolve(collapsingExpr(scope))
.then(function() {
element
if (horizontal) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrap all the logic in a helper function to help DRY up

element
// IMPORTANT: The width must be set before adding "collapsing" class.
// Otherwise, the browser attempts to animate from width 0 (in
// collapsing class) to the given width here.
.css({width: element[0].scrollWidth + 'px'})
// initially all panel collapse have the collapse class, this removal
// prevents the animation from jumping to collapsed state
.removeClass('collapse')
.addClass('collapsing')
.attr('aria-expanded', false)
.attr('aria-hidden', true);

if ($animateCss) {
$animateCss(element, {
removeClass: 'in',
to: {width: '0'}
}).start()['finally'](collapseDone);
} else {
$animate.removeClass(element, 'in', {
to: {width: '0'}
}).then(collapseDone);
}
} else {
element
// IMPORTANT: The height must be set before adding "collapsing" class.
// Otherwise, the browser attempts to animate from height 0 (in
// collapsing class) to the given height here.
.css({height: element[0].scrollHeight + 'px'})
// initially all panel collapse have the collapse class, this removal
// prevents the animation from jumping to collapsed state
.removeClass('collapse')
.addClass('collapsing')
.attr('aria-expanded', false)
.attr('aria-hidden', true);
.css({height: element[0].scrollHeight + 'px'})
// initially all panel collapse have the collapse class, this removal
// prevents the animation from jumping to collapsed state
.removeClass('collapse')
.addClass('collapsing')
.attr('aria-expanded', false)
.attr('aria-hidden', true);

if ($animateCss) {
$animateCss(element, {
removeClass: 'in',
to: {height: '0'}
}).start()['finally'](collapseDone);
} else {
$animate.removeClass(element, 'in', {
to: {height: '0'}
}).then(collapseDone);
if ($animateCss) {
$animateCss(element, {
removeClass: 'in',
to: {height: '0'}
}).start()['finally'](collapseDone);
} else {
$animate.removeClass(element, 'in', {
to: {height: '0'}
}).then(collapseDone);
}
}
});
}

function collapseDone() {
element.css({height: '0'}); // Required so that collapse works when animation is disabled
if (horizontal) {
element.css({width: '0'}); // Required so that collapse works when animation is disabled
} else {
element.css({height: '0'}); // Required so that collapse works when animation is disabled
}
element.removeClass('collapsing')
.addClass('collapse');
collapsedExpr(scope);
Expand Down
8 changes: 7 additions & 1 deletion src/collapse/docs/demo.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
<div ng-controller="CollapseDemoCtrl">
<button type="button" class="btn btn-default" ng-click="isCollapsed = !isCollapsed">Toggle collapse</button>
<button type="button" class="btn btn-default" ng-click="isCollapsed = !isCollapsed">Toggle collapse Vertically</button>
<hr>
<div uib-collapse="isCollapsed">
<div class="well well-lg">Some content</div>
</div>

<button type="button" class="btn btn-default" ng-click="isCollapsedHorizontal = !isCollapsedHorizontal">Toggle collapse Horizontally</button>
<hr>
<div uib-collapse="isCollapsedHorizontal" horizontal>
<div class="well well-lg">Some content</div>
</div>
</div>
1 change: 1 addition & 0 deletions src/collapse/docs/demo.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
angular.module('ui.bootstrap.demo').controller('CollapseDemoCtrl', function ($scope) {
$scope.isCollapsed = false;
$scope.isCollapsedHorizontal = false;
});
4 changes: 4 additions & 0 deletions src/collapse/docs/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,8 @@
<i class="glyphicon glyphicon-eye-open"></i>
_(Default: `false`)_ -
Whether the element should be collapsed or not.

* `horizontal`
<small class="badge">$</small> -
An optional attribute that permit to collapse horizontally.

Loading