UNPKG

angular-ui-bootstrap

Version:

Native AngularJS (Angular) directives for Bootstrap

134 lines (120 loc) 4.3 kB
angular.module('ui.bootstrap.collapse', []) .directive('uibCollapse', ['$animate', '$q', '$parse', '$injector', function($animate, $q, $parse, $injector) { var $animateCss = $injector.has('$animateCss') ? $injector.get('$animateCss') : null; return { link: function(scope, element, attrs) { var expandingExpr = $parse(attrs.expanding), expandedExpr = $parse(attrs.expanded), collapsingExpr = $parse(attrs.collapsing), collapsedExpr = $parse(attrs.collapsed), horizontal = false, css = {}, cssTo = {}; init(); function init() { horizontal = !!('horizontal' in attrs); if (horizontal) { css = { width: '' }; cssTo = {width: '0'}; } else { css = { height: '' }; cssTo = {height: '0'}; } if (!scope.$eval(attrs.uibCollapse)) { element.addClass('in') .addClass('collapse') .attr('aria-expanded', true) .attr('aria-hidden', false) .css(css); } } function getScrollFromElement(element) { if (horizontal) { return {width: element.scrollWidth + 'px'}; } return {height: element.scrollHeight + 'px'}; } function expand() { if (element.hasClass('collapse') && element.hasClass('in')) { return; } $q.resolve(expandingExpr(scope)) .then(function() { element.removeClass('collapse') .addClass('collapsing') .attr('aria-expanded', true) .attr('aria-hidden', false); if ($animateCss) { $animateCss(element, { addClass: 'in', easing: 'ease', css: { overflow: 'hidden' }, to: getScrollFromElement(element[0]) }).start()['finally'](expandDone); } else { $animate.addClass(element, 'in', { css: { overflow: 'hidden' }, to: getScrollFromElement(element[0]) }).then(expandDone); } }, angular.noop); } function expandDone() { element.removeClass('collapsing') .addClass('collapse') .css(css); expandedExpr(scope); } function collapse() { if (!element.hasClass('collapse') && !element.hasClass('in')) { return collapseDone(); } $q.resolve(collapsingExpr(scope)) .then(function() { 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(getScrollFromElement(element[0])) // 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: cssTo }).start()['finally'](collapseDone); } else { $animate.removeClass(element, 'in', { to: cssTo }).then(collapseDone); } }, angular.noop); } function collapseDone() { element.css(cssTo); // Required so that collapse works when animation is disabled element.removeClass('collapsing') .addClass('collapse'); collapsedExpr(scope); } scope.$watch(attrs.uibCollapse, function(shouldCollapse) { if (shouldCollapse) { collapse(); } else { expand(); } }); } }; }]);