From 14eebf42bfeb3190d018a99fcb8d181adb5cb542 Mon Sep 17 00:00:00 2001 From: Topher Fangio Date: Thu, 29 Oct 2015 15:13:41 -0700 Subject: [PATCH] fix(speedDial): non-fab clicks no longer close immediately In the demo application and some user's apps, the `md-open` attribute was bound to an input element, but clicking this element while the FAB Speed Dial was open would open and then immediately close the speed dial since the user clicked outside of the speed dial. Fix by delaying the check for outside clicks until the next digest loop. Also fix a tiny positioning issue with the fling animation. Fixes #5243. Closes #5440. --- .../fabSpeedDial/demoBasicUsage/index.html | 7 +++---- src/components/fabSpeedDial/fabController.js | 13 ++++++++----- src/components/fabSpeedDial/fabSpeedDial.js | 14 ++++++++++---- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/components/fabSpeedDial/demoBasicUsage/index.html b/src/components/fabSpeedDial/demoBasicUsage/index.html index 4d78006f67b..939bd91d5ae 100644 --- a/src/components/fabSpeedDial/demoBasicUsage/index.html +++ b/src/components/fabSpeedDial/demoBasicUsage/index.html @@ -43,10 +43,9 @@
Open/Closed - - Open - Closed - + + Open +
diff --git a/src/components/fabSpeedDial/fabController.js b/src/components/fabSpeedDial/fabController.js index 01ab1b88ae9..967ca061c15 100644 --- a/src/components/fabSpeedDial/fabController.js +++ b/src/components/fabSpeedDial/fabController.js @@ -7,7 +7,7 @@ function FabController($scope, $element, $animate, $mdUtil, $mdConstant, $timeout) { var vm = this; - // NOTE: We use async evals below to avoid conflicts with any existing digest loops + // NOTE: We use async eval(s) below to avoid conflicts with any existing digest loops vm.open = function() { $scope.$evalAsync("vm.isOpen = true"); @@ -142,8 +142,12 @@ function enableKeyboard() { $element.on('keydown', keyPressed); - angular.element(document).on('click', checkForOutsideClick); - angular.element(document).on('touchend', checkForOutsideClick); + + // On the next tick, setup a check for outside clicks; we do this on the next tick to avoid + // clicks/touches that result in the isOpen attribute changing (e.g. a bound radio button) + $mdUtil.nextTick(function() { + angular.element(document).on('click touchend', checkForOutsideClick); + }); // TODO: On desktop, we should be able to reset the indexes so you cannot tab through, but // this breaks accessibility, especially on mobile, since you have no arrow keys to press @@ -152,8 +156,7 @@ function disableKeyboard() { $element.off('keydown', keyPressed); - angular.element(document).off('click', checkForOutsideClick); - angular.element(document).off('touchend', checkForOutsideClick); + angular.element(document).off('click touchend', checkForOutsideClick); } function checkForOutsideClick(event) { diff --git a/src/components/fabSpeedDial/fabSpeedDial.js b/src/components/fabSpeedDial/fabSpeedDial.js index bd9c29b23cd..7f8f538becd 100644 --- a/src/components/fabSpeedDial/fabSpeedDial.js +++ b/src/components/fabSpeedDial/fabSpeedDial.js @@ -148,21 +148,27 @@ var newPosition, axis; var styles = item.style; + // Make sure to account for differences in the dimensions of the trigger verses the items + // so that we can properly center everything; this helps hide the item's shadows behind + // the trigger. + var triggerItemHeightOffset = (triggerElement.clientHeight - item.clientHeight) / 2; + var triggerItemWidthOffset = (triggerElement.clientWidth - item.clientWidth) / 2; + switch (ctrl.direction) { case 'up': - newPosition = item.scrollHeight * (index + 1); + newPosition = (item.scrollHeight * (index + 1) + triggerItemHeightOffset); axis = 'Y'; break; case 'down': - newPosition = -item.scrollHeight * (index + 1); + newPosition = -(item.scrollHeight * (index + 1) + triggerItemHeightOffset); axis = 'Y'; break; case 'left': - newPosition = item.scrollWidth * (index + 1); + newPosition = (item.scrollWidth * (index + 1) + triggerItemWidthOffset); axis = 'X'; break; case 'right': - newPosition = -item.scrollWidth * (index + 1); + newPosition = -(item.scrollWidth * (index + 1) + triggerItemWidthOffset); axis = 'X'; break; }