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

Commit

Permalink
fix(fabSpeedDial): fix many visual issues
Browse files Browse the repository at this point in the history
* maintain state when focusing/bluring/tabbing through actions

   speed dial would previously show a very short and erroneous animation
   when tabbing, or rapidly blurring/focusing, through child items

 * add demo showing tooltip usage

 * fix $digest in-progress error when opening a dialog

   cebor reported a $digest in progress bug when trying to open a dialog
   from within the speed dial; haven't figured out how to create a test
   that demonstrates it, but I added a demo which shows failure

 * animations fail on Safari

   update webkitTransform styles and set height to initial instead of 100%

 * make changes suggested by gkalpak

 * more fixes suggested by gkalpak

closes #3213. closes #3338. closes #3277. closes #3236. closes #3375. Closes #3468.
  • Loading branch information
topherfangio authored and ThomasBurleson committed Jun 29, 2015
1 parent 1414b3c commit 288285c
Show file tree
Hide file tree
Showing 8 changed files with 151 additions and 21 deletions.
4 changes: 2 additions & 2 deletions src/components/fabSpeedDial/demoBasicUsage/index.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div ng-controller="AppCtrl" layout="column">
<div ng-controller="DemoCtrl as demo" layout="column">
<md-content class="md-padding" layout="column">
<p>
You may supply a direction of <code>left</code>, <code>up</code>, <code>down</code>, or
Expand All @@ -21,7 +21,7 @@
<md-button aria-label="facebook" class="md-fab md-raised md-mini">
<md-icon md-svg-src="img/icons/facebook.svg"></md-icon>
</md-button>
<md-button aria-label="Google hangout" class="md-fab md-raised md-mini">
<md-button aria-label="Google Hangout" class="md-fab md-raised md-mini">
<md-icon md-svg-src="img/icons/hangout.svg"></md-icon>
</md-button>
</md-fab-actions>
Expand Down
18 changes: 8 additions & 10 deletions src/components/fabSpeedDial/demoBasicUsage/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,16 @@
'use strict';

angular.module('fabSpeedDialBasicUsageDemo', ['ngMaterial'])
.controller('AppCtrl', function($scope) {
$scope.demo = {
topDirections: ['left', 'up'],
bottomDirections: ['down', 'right'],
.controller('DemoCtrl', function() {
this.topDirections = ['left', 'up'];
this.bottomDirections = ['down', 'right'];

isOpen: false,
this.isOpen = false;

availableModes: ['md-fling', 'md-scale'],
selectedMode: 'md-fling',
this.availableModes = ['md-fling', 'md-scale'];
this.selectedMode = 'md-fling';

availableDirections: ['up', 'down', 'left', 'right'],
selectedDirection: 'up'
};
this.availableDirections = ['up', 'down', 'left', 'right'];
this.selectedDirection = 'up';
});
})();
59 changes: 59 additions & 0 deletions src/components/fabSpeedDial/demoTooltips/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<div layout="column" ng-controller="DemoCtrl as demo" >
<md-content class="md-padding" layout="column">
<p>
You may add tooltips to both the trigger and actions...<br/>
Note: you can easily open a dialog with a Fab action.
</p>

<div class="lock-size" layout="row" layout-align="center center">
<md-fab-speed-dial md-direction="down" class="md-fling">
<md-fab-trigger>
<md-button aria-label="menu" class="md-fab md-warn">
<md-tooltip md-direction="top">Menu</md-tooltip>
<md-icon md-svg-src="img/icons/menu.svg"></md-icon>
</md-button>
</md-fab-trigger>

<md-fab-actions>
<md-button aria-label="twitter" class="md-fab md-raised md-mini">
<md-tooltip md-direction="left">Twitter</md-tooltip>
<md-icon md-svg-src="img/icons/twitter.svg"></md-icon>
</md-button>

<md-button aria-label="facebook" class="md-fab md-raised md-mini">
<md-tooltip md-direction="right">Facebook</md-tooltip>
<md-icon md-svg-src="img/icons/facebook.svg"></md-icon>
</md-button>

<md-button aria-label="Google Hangout" class="md-fab md-raised md-mini">
<md-tooltip md-direction="left">Google Hangout</md-tooltip>
<md-icon md-svg-src="img/icons/hangout.svg"></md-icon>
</md-button>

<md-button aria-label="Open dialog" class="md-fab md-raised md-mini demo-fab action-fab"
ng-click="demo.openDialog($event)">
<md-tooltip md-direction="right">Open dialog</md-tooltip>
<md-icon md-svg-src="img/icons/launch.svg"></md-icon>
</md-button>
</md-fab-actions>
</md-fab-speed-dial>
</div>
</md-content>

<script type="text/ng-template" id="dialog.html">
<md-dialog>
<md-dialog-content>Hello User!!!</md-dialog-content>

<div class="md-actions">
<md-button aria-label="Close dialog" ng-click="dialog.close()" class="md-primary">
Close Greeting
</md-button>

<md-button aria-label="Submit dialog" ng-click="dialog.submit()" class="md-primary">
Submit
</md-button>
</div>
</md-dialog>
</script>

</div>
23 changes: 23 additions & 0 deletions src/components/fabSpeedDial/demoTooltips/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
(function() {
'use strict';

angular.module('fabSpeedDialModalDemo', ['ngMaterial'])
.controller('DemoCtrl', function($mdDialog) {
this.openDialog = function($event) {
$mdDialog.show({
clickOutsideToClose: true,
controller: function($mdDialog) {
this.close = function() {
$mdDialog.cancel();
};
this.submit = function() {
$mdDialog.hide();
};
},
controllerAs: 'dialog',
templateUrl: 'dialog.html',
targetEvent: $event
});
}
});
})();
30 changes: 30 additions & 0 deletions src/components/fabSpeedDial/demoTooltips/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
.text-capitalize {
text-transform: capitalize;
}

.md-fab:hover, .md-fab.md-focused {
background-color: #000 !important;
}

p.note {
font-size: 1.2rem;
}

.lock-size {
min-width: 300px;
min-height: 300px;
width: 300px;
height: 300px;
margin-left: auto;
margin-right: auto;
}

.md-fab.demo-fab.trigger-fab, .md-fab.demo-fab.action-fab {
&:hover, &.md-focused {
background-color: #333;
}
}

.md-fab.demo-fab.action-fab {
background-color: #aaa;
}
32 changes: 24 additions & 8 deletions src/components/fabSpeedDial/fabSpeedDial.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,24 @@
// Define our open/close functions
// Note: Used by fabTrigger and fabActions directives
vm.open = function() {
$scope.$apply('vm.isOpen = true');
// Async eval to avoid conflicts with existing digest loops
$scope.$evalAsync("vm.isOpen = true");
};

vm.close = function() {
$scope.$apply('vm.isOpen = false');
// Async eval to avoid conflicts with existing digest loops
// Only close if we do not currently have mouse focus (since child elements can call this)
!vm.moused && $scope.$evalAsync("vm.isOpen = false");
};

vm.mouseenter = function() {
vm.moused = true;
vm.open();
};

vm.mouseleave = function() {
vm.moused = false;
vm.close();
};

setupDefaults();
Expand All @@ -101,8 +114,8 @@

// Setup our event listeners
function setupListeners() {
$element.on('mouseenter', vm.open);
$element.on('mouseleave', vm.close);
$element.on('mouseenter', vm.mouseenter);

This comment has been minimized.

Copy link
@bdteo

bdteo Jul 25, 2015

Hm, doesn't this open speed dial even if child elements are hovered? Isn't it only fabTrigger that should open speed dial?

This comment has been minimized.

Copy link
@topherfangio

topherfangio Aug 3, 2015

Author Contributor

@bdteo There was a request that the speed dial would work like the Google Inbox version does where it appears when you hover over the area of the speed dial. I'm currently working on a separate commit which gives you more control so you can specify how you want it to work, but I still feel like this is a good default for the speed dial at least (this is horrible for the toolbar and that will be fixed ASAP).

$element.on('mouseleave', vm.mouseleave);
}

// Setup our watchers
Expand Down Expand Up @@ -142,18 +155,19 @@
angular.forEach(items, function(item, index) {
var styles = item.style;

styles.transform = '';
styles.transform = styles.webkitTransform = '';

This comment has been minimized.

Copy link
@ThomasBurleson

ThomasBurleson Jul 9, 2015

Contributor

@topherfangio - What about other vendor browser prefixes?

$(element).css({
    "webkitTransform":"",
    "MozTransform":"",
    "msTransform":"",
    "OTransform":"",
    "transform":""
});

@see Coding Vendor Prefixes with Javascript

This comment has been minimized.

Copy link
@topherfangio

topherfangio Jul 9, 2015

Author Contributor

I've been meaning to ask about that. The browser prefixes are generally for older browser support, and in this particular case, it was to fix a bug in Chrome because something else was setting the webkitTransform which apparently has a higher precedence than the standard transform.

For Material, do we recommend using all of the prefixes? If so, is this something that we could use an existing utility to provide, or should we make a utility for this?

This comment has been minimized.

Copy link
@ThomasBurleson

ThomasBurleson Jul 10, 2015

Contributor

We use gulp-autoprefixer as part of our build process. But Javascript-injected styles [are not managed by this process] must be manually prefixed. I think only transform is the issue... at least in this case.

It appears that our policy of support N-1 Current Browsers only requires a webKit prefix.

Here are the AutoPrefixer Rules if you want to review these. Note this internally uses the Can I Use service.

This comment has been minimized.

Copy link
@ThomasBurleson

ThomasBurleson Jul 10, 2015

Contributor

I forgot to mention that we have a programmatic solution for this with $mdConstant.CSS.TRANSFORM which at runtime initialization internally makes calls vendorProperty() and uses $sniffer...

styles[$mdConstant.CSS.TRANSFORM] = 'translate' + axis + '(' + newPosition + 'px)';
styles.transitionDelay = '';
styles.opacity = 1;

// Make the items closest to the trigger have the highest z-index
item.style.zIndex = (items.length - index) + startZIndex;
styles.zIndex = (items.length - index) + startZIndex;
});

// If the control is closed, hide the items behind the trigger
if (!ctrl.isOpen) {
angular.forEach(items, function(item, index) {
var newPosition, axis;
var styles = item.style;

switch (ctrl.direction) {
case 'up':
Expand All @@ -174,7 +188,9 @@
break;
}

item.style.transform = 'translate' + axis + '(' + newPosition + 'px)';
var newTranslate = 'translate' + axis + '(' + newPosition + 'px)';

styles.transform = styles.webkitTransform = newTranslate;
});
}
}
Expand Down Expand Up @@ -205,7 +221,7 @@
offsetDelay = index * delay;

styles.opacity = ctrl.isOpen ? 1 : 0;
styles.transform = ctrl.isOpen ? 'scale(1)' : 'scale(0)';
styles.transform = styles.webkitTransform = ctrl.isOpen ? 'scale(1)' : 'scale(0)';
styles.transitionDelay = (ctrl.isOpen ? offsetDelay : (items.length - offsetDelay)) + 'ms';
});
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/fabSpeedDial/fabSpeedDial.scss
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ md-fab-speed-dial {
display: flex;

// Set the height so that the z-index in the JS animation works
height: 100%;
height: initial;

.md-fab-action-item {
visibility: hidden;
Expand Down
4 changes: 4 additions & 0 deletions src/components/fabSpeedDial/fabSpeedDial.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ describe('<md-fab-speed-dial> directive', function() {
);

element.find('button').triggerHandler('focus');
pageScope.$digest();
expect(controller.isOpen).toBe(true);
}));

Expand All @@ -47,6 +48,7 @@ describe('<md-fab-speed-dial> directive', function() {
);

element.find('button').triggerHandler('focus');
pageScope.$digest();
expect(controller.isOpen).toBe(true);
}));

Expand All @@ -56,9 +58,11 @@ describe('<md-fab-speed-dial> directive', function() {
);

element.find('button').triggerHandler('focus');
pageScope.$digest();
expect(controller.isOpen).toBe(true);

element.find('button').triggerHandler('blur');
pageScope.$digest();
expect(controller.isOpen).toBe(false);
}));

Expand Down

0 comments on commit 288285c

Please sign in to comment.