From efde63c4673ca60085013f9d4caa6121c8110c30 Mon Sep 17 00:00:00 2001 From: Robert Messerle Date: Tue, 31 Mar 2015 17:14:37 -0700 Subject: [PATCH] feat(tabs): adds support for dynamic height based on tab contents Closes #2088 --- .../tabs/demoDynamicTabs/style.scss | 14 +++++--- src/components/tabs/js/tabsController.js | 36 ++++++++++++++----- src/components/tabs/js/tabsDirective.js | 18 +++++++--- src/components/tabs/tabs.scss | 8 +++++ 4 files changed, 57 insertions(+), 19 deletions(-) diff --git a/src/components/tabs/demoDynamicTabs/style.scss b/src/components/tabs/demoDynamicTabs/style.scss index bd7057edbbc..552abf6597e 100644 --- a/src/components/tabs/demoDynamicTabs/style.scss +++ b/src/components/tabs/demoDynamicTabs/style.scss @@ -28,11 +28,15 @@ label { [layout-align] > * { margin-left: 8px; } -form > [layout] > * { - margin-left: 8px; -} -form > [layout] > span { - padding-top:2px +form { + > [layout] { + > * { + margin-left: 8px; + } + > span { + padding-top:2px + } + } } .long > input { width: 264px; diff --git a/src/components/tabs/js/tabsController.js b/src/components/tabs/js/tabsController.js index 93c85f67bd6..bf28e798aec 100644 --- a/src/components/tabs/js/tabsController.js +++ b/src/components/tabs/js/tabsController.js @@ -44,15 +44,24 @@ $scope.$watch('$mdTabsCtrl.offsetLeft', handleOffsetChange); angular.element($window).on('resize', function () { $scope.$apply(handleWindowResize); }); $timeout(updateInkBarStyles, 0, false); + $timeout(updateHeightFromContent, 0, false); } function getElements () { - var elements = {}; - elements.canvas = $element[0].getElementsByTagName('md-tabs-canvas')[0]; - elements.wrapper = elements.canvas.getElementsByTagName('md-pagination-wrapper')[0]; - elements.tabs = elements.wrapper.getElementsByTagName('md-tab-item'); - elements.dummies = elements.canvas.getElementsByTagName('md-dummy-tab'); - elements.inkBar = elements.wrapper.getElementsByTagName('md-ink-bar')[0]; + var elements = {}; + + //-- gather tab bar elements + elements.wrapper = $element[0].getElementsByTagName('md-tabs-wrapper')[0]; + elements.canvas = elements.wrapper.getElementsByTagName('md-tabs-canvas')[0]; + elements.paging = elements.canvas.getElementsByTagName('md-pagination-wrapper')[0]; + elements.tabs = elements.paging.getElementsByTagName('md-tab-item'); + elements.dummies = elements.canvas.getElementsByTagName('md-dummy-tab'); + elements.inkBar = elements.paging.getElementsByTagName('md-ink-bar')[0]; + + //-- gather tab content elements + elements.contentsWrapper = $element[0].getElementsByTagName('md-tabs-content-wrapper')[0]; + elements.contents = elements.contentsWrapper.getElementsByTagName('md-tab-content'); + return elements; } @@ -88,7 +97,7 @@ } function handleOffsetChange (left) { - angular.element(elements.wrapper).css('left', '-' + left + 'px'); + angular.element(elements.paging).css('left', '-' + left + 'px'); $scope.$broadcast('$mdTabsPaginationChanged'); } @@ -158,6 +167,7 @@ $scope.selectedIndex = getNearestSafeIndex(newValue); ctrl.lastSelectedIndex = oldValue; updateInkBarStyles(); + updateHeightFromContent(); $scope.$broadcast('$mdTabsChanged'); } @@ -182,19 +192,27 @@ }); } + function updateHeightFromContent () { + if (!$scope.dynamicHeight) return $element.css('height', ''); + var tabContent = elements.contents[$scope.selectedIndex], + contentHeight = tabContent.offsetHeight, + tabsHeight = elements.wrapper.offsetHeight, + newHeight = contentHeight + tabsHeight; + $element.css('height', newHeight + 'px'); + } + function updateInkBarStyles () { if (!ctrl.tabs.length) return; //-- if the element is not visible, we will not be able to calculate sizes until it is //-- we should treat that as a resize event rather than just updating the ink bar if (!$element.prop('offsetParent')) return handleResizeWhenVisible(); var index = $scope.selectedIndex, - totalWidth = elements.wrapper.offsetWidth, + totalWidth = elements.paging.offsetWidth, tab = elements.tabs[index], left = tab.offsetLeft, right = totalWidth - left - tab.offsetWidth; updateInkBarClassName(); angular.element(elements.inkBar).css({ left: left + 'px', right: right + 'px' }); - } function updateInkBarClassName () { diff --git a/src/components/tabs/js/tabsDirective.js b/src/components/tabs/js/tabsDirective.js index 3583efc1636..14fbac7f49b 100644 --- a/src/components/tabs/js/tabsDirective.js +++ b/src/components/tabs/js/tabsDirective.js @@ -56,6 +56,7 @@ * @param {boolean=} md-no-bar If present, disables the selection ink bar. * @param {string=} md-align-tabs Attribute to indicate position of tab buttons: `bottom` or `top`; default is `top` * @param {string=} md-stretch-tabs Attribute to indicate whether or not to stretch tabs: `auto`, `always`, or `never`; default is `auto` + * @param {boolean=} md-dynamic-height When enabled, the tab wrapper will resize based on the contents of the selected tab * * @usage * @@ -89,7 +90,8 @@ function MdTabs ($mdTheming) { return { scope: { - selectedIndex: '=?mdSelected', + dynamicHeight: '=?mdDynamicHeight', + selectedIndex: '=mdSelected', stretchTabs: '@?mdStretchTabs' }, transclude: true, @@ -159,15 +161,16 @@ \ \ \ - \ + \