Skip to content
This repository was archived by the owner on Sep 5, 2024. It is now read-only.

Commit 4b56087

Browse files
devversionThomasBurleson
authored andcommitted
docs(): add jump to top fab button (#9786)
* Adds a Jump to Top Fab button at the right bottom of the docs page. * The FAB button automatically shows when the content is scrolling (this runs outside of Angular to not trigger a digest per each scroll event)
1 parent 24ac328 commit 4b56087

File tree

5 files changed

+71
-6
lines changed

5 files changed

+71
-6
lines changed

docs/app/css/style.css

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,22 @@ body.docs-body {
3333
color: inherit;
3434
}
3535

36+
.md-fab.docs-scroll-fab {
37+
position: fixed !important;
38+
39+
transform: scale(0);
40+
41+
/* Manually prefix because the docs won't be prefixed. See #9785 */
42+
-webkit-transition: transform 0.2s;
43+
-moz-transition: transform 0.2s;
44+
-o-transition: transform 0.2s;
45+
transition: transform 0.2s;
46+
}
47+
48+
.docs-scroll-fab.scrolling {
49+
transform: scale(1);
50+
}
51+
3652
#license-footer {
3753
align-self: flex-end;
3854
padding: 16px 32px;
Lines changed: 4 additions & 0 deletions
Loading

docs/app/js/app.js

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,8 @@ function(SERVICES, COMPONENTS, DEMOS, PAGES, $location, $rootScope, $http, $wind
575575
'menu',
576576
'$location',
577577
'$rootScope',
578-
function($scope, COMPONENTS, BUILDCONFIG, $mdSidenav, $timeout, $mdDialog, menu, $location, $rootScope) {
578+
'$mdUtil',
579+
function($scope, COMPONENTS, BUILDCONFIG, $mdSidenav, $timeout, $mdDialog, menu, $location, $rootScope, $mdUtil) {
579580
var self = this;
580581

581582
$scope.COMPONENTS = COMPONENTS;
@@ -587,6 +588,7 @@ function($scope, COMPONENTS, BUILDCONFIG, $mdSidenav, $timeout, $mdDialog, menu,
587588
$scope.openMenu = openMenu;
588589
$scope.closeMenu = closeMenu;
589590
$scope.isSectionSelected = isSectionSelected;
591+
$scope.scrollTop = scrollTop;
590592

591593
// Grab the current year so we don't have to update the license every year
592594
$scope.thisYear = (new Date()).getFullYear();
@@ -615,6 +617,8 @@ function($scope, COMPONENTS, BUILDCONFIG, $mdSidenav, $timeout, $mdDialog, menu,
615617

616618

617619
var mainContentArea = document.querySelector("[role='main']");
620+
var scrollContentEl = mainContentArea.querySelector('md-content[md-scroll-y]');
621+
618622

619623
// *********************
620624
// Internal methods
@@ -632,6 +636,10 @@ function($scope, COMPONENTS, BUILDCONFIG, $mdSidenav, $timeout, $mdDialog, menu,
632636
return $location.path();
633637
}
634638

639+
function scrollTop() {
640+
$mdUtil.animateScrollTo(scrollContentEl, 0, 200);
641+
}
642+
635643
function goHome($event) {
636644
menu.selectPage(null, null);
637645
$location.path( '/' );
@@ -826,4 +834,32 @@ function($rootScope, $scope, component, demos, $templateRequest) {
826834
// Just return the original string if we don't know what to do with it
827835
return str;
828836
};
837+
})
838+
839+
/** Directive which applies a specified class to the element when being scrolled */
840+
.directive('docsScrollClass', function() {
841+
return {
842+
restrict: 'A',
843+
link: function(scope, element, attr) {
844+
845+
var scrollParent = element.parent();
846+
var isScrolling = false;
847+
848+
// Initial update of the state.
849+
updateState();
850+
851+
// Register a scroll listener, which updates the state.
852+
scrollParent.on('scroll', updateState);
853+
854+
function updateState() {
855+
var newState = scrollParent[0].scrollTop !== 0;
856+
857+
if (newState !== isScrolling) {
858+
element.toggleClass(attr.docsScrollClass, newState);
859+
}
860+
861+
isScrolling = newState;
862+
}
863+
}
864+
};
829865
});

docs/config/template/index.template.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,14 @@ <h2 class="md-toolbar-item md-breadcrumb md-headline">
164164
<a href="http://creativecommons.org/licenses/by/4.0/" target="_blank" class="md-default-theme md-accent">CC BY 4.0</a>.
165165
</div>
166166
</div>
167+
168+
<md-button class="md-fab md-fab-bottom-right docs-scroll-fab"
169+
docs-scroll-class="scrolling"
170+
ng-click="scrollTop()"
171+
aria-label="Jump to top">
172+
<md-icon md-svg-src="img/icons/ic_arrow_up_24px.svg"></md-icon>
173+
</md-button>
174+
167175
</md-content>
168176

169177
</div>

src/core/util/util.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -792,10 +792,11 @@ function UtilFactory($document, $timeout, $compile, $rootScope, $$mdAnimate, $in
792792
/**
793793
* Animate the requested element's scrollTop to the requested scrollPosition with basic easing.
794794
*
795-
* @param element The element to scroll.
796-
* @param scrollEnd The new/final scroll position.
795+
* @param {!HTMLElement} element The element to scroll.
796+
* @param {number} scrollEnd The new/final scroll position.
797+
* @param {number=} duration Duration of the scroll. Default is 1000ms.
797798
*/
798-
animateScrollTo: function(element, scrollEnd) {
799+
animateScrollTo: function(element, scrollEnd, duration) {
799800
var scrollStart = element.scrollTop;
800801
var scrollChange = scrollEnd - scrollStart;
801802
var scrollingDown = scrollStart < scrollEnd;
@@ -814,10 +815,10 @@ function UtilFactory($document, $timeout, $compile, $rootScope, $$mdAnimate, $in
814815
}
815816

816817
function calculateNewPosition() {
817-
var duration = 1000;
818+
var easeDuration = duration || 1000;
818819
var currentTime = $mdUtil.now() - startTime;
819820

820-
return ease(currentTime, scrollStart, scrollChange, duration);
821+
return ease(currentTime, scrollStart, scrollChange, easeDuration);
821822
}
822823

823824
function ease(currentTime, start, change, duration) {

0 commit comments

Comments
 (0)