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

Commit 288285c

Browse files
topherfangioThomasBurleson
authored andcommitted
fix(fabSpeedDial): fix many visual issues
* 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.
1 parent 1414b3c commit 288285c

File tree

8 files changed

+151
-21
lines changed

8 files changed

+151
-21
lines changed

src/components/fabSpeedDial/demoBasicUsage/index.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<div ng-controller="AppCtrl" layout="column">
1+
<div ng-controller="DemoCtrl as demo" layout="column">
22
<md-content class="md-padding" layout="column">
33
<p>
44
You may supply a direction of <code>left</code>, <code>up</code>, <code>down</code>, or
@@ -21,7 +21,7 @@
2121
<md-button aria-label="facebook" class="md-fab md-raised md-mini">
2222
<md-icon md-svg-src="img/icons/facebook.svg"></md-icon>
2323
</md-button>
24-
<md-button aria-label="Google hangout" class="md-fab md-raised md-mini">
24+
<md-button aria-label="Google Hangout" class="md-fab md-raised md-mini">
2525
<md-icon md-svg-src="img/icons/hangout.svg"></md-icon>
2626
</md-button>
2727
</md-fab-actions>

src/components/fabSpeedDial/demoBasicUsage/script.js

+8-10
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,16 @@
22
'use strict';
33

44
angular.module('fabSpeedDialBasicUsageDemo', ['ngMaterial'])
5-
.controller('AppCtrl', function($scope) {
6-
$scope.demo = {
7-
topDirections: ['left', 'up'],
8-
bottomDirections: ['down', 'right'],
5+
.controller('DemoCtrl', function() {
6+
this.topDirections = ['left', 'up'];
7+
this.bottomDirections = ['down', 'right'];
98

10-
isOpen: false,
9+
this.isOpen = false;
1110

12-
availableModes: ['md-fling', 'md-scale'],
13-
selectedMode: 'md-fling',
11+
this.availableModes = ['md-fling', 'md-scale'];
12+
this.selectedMode = 'md-fling';
1413

15-
availableDirections: ['up', 'down', 'left', 'right'],
16-
selectedDirection: 'up'
17-
};
14+
this.availableDirections = ['up', 'down', 'left', 'right'];
15+
this.selectedDirection = 'up';
1816
});
1917
})();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<div layout="column" ng-controller="DemoCtrl as demo" >
2+
<md-content class="md-padding" layout="column">
3+
<p>
4+
You may add tooltips to both the trigger and actions...<br/>
5+
Note: you can easily open a dialog with a Fab action.
6+
</p>
7+
8+
<div class="lock-size" layout="row" layout-align="center center">
9+
<md-fab-speed-dial md-direction="down" class="md-fling">
10+
<md-fab-trigger>
11+
<md-button aria-label="menu" class="md-fab md-warn">
12+
<md-tooltip md-direction="top">Menu</md-tooltip>
13+
<md-icon md-svg-src="img/icons/menu.svg"></md-icon>
14+
</md-button>
15+
</md-fab-trigger>
16+
17+
<md-fab-actions>
18+
<md-button aria-label="twitter" class="md-fab md-raised md-mini">
19+
<md-tooltip md-direction="left">Twitter</md-tooltip>
20+
<md-icon md-svg-src="img/icons/twitter.svg"></md-icon>
21+
</md-button>
22+
23+
<md-button aria-label="facebook" class="md-fab md-raised md-mini">
24+
<md-tooltip md-direction="right">Facebook</md-tooltip>
25+
<md-icon md-svg-src="img/icons/facebook.svg"></md-icon>
26+
</md-button>
27+
28+
<md-button aria-label="Google Hangout" class="md-fab md-raised md-mini">
29+
<md-tooltip md-direction="left">Google Hangout</md-tooltip>
30+
<md-icon md-svg-src="img/icons/hangout.svg"></md-icon>
31+
</md-button>
32+
33+
<md-button aria-label="Open dialog" class="md-fab md-raised md-mini demo-fab action-fab"
34+
ng-click="demo.openDialog($event)">
35+
<md-tooltip md-direction="right">Open dialog</md-tooltip>
36+
<md-icon md-svg-src="img/icons/launch.svg"></md-icon>
37+
</md-button>
38+
</md-fab-actions>
39+
</md-fab-speed-dial>
40+
</div>
41+
</md-content>
42+
43+
<script type="text/ng-template" id="dialog.html">
44+
<md-dialog>
45+
<md-dialog-content>Hello User!!!</md-dialog-content>
46+
47+
<div class="md-actions">
48+
<md-button aria-label="Close dialog" ng-click="dialog.close()" class="md-primary">
49+
Close Greeting
50+
</md-button>
51+
52+
<md-button aria-label="Submit dialog" ng-click="dialog.submit()" class="md-primary">
53+
Submit
54+
</md-button>
55+
</div>
56+
</md-dialog>
57+
</script>
58+
59+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
(function() {
2+
'use strict';
3+
4+
angular.module('fabSpeedDialModalDemo', ['ngMaterial'])
5+
.controller('DemoCtrl', function($mdDialog) {
6+
this.openDialog = function($event) {
7+
$mdDialog.show({
8+
clickOutsideToClose: true,
9+
controller: function($mdDialog) {
10+
this.close = function() {
11+
$mdDialog.cancel();
12+
};
13+
this.submit = function() {
14+
$mdDialog.hide();
15+
};
16+
},
17+
controllerAs: 'dialog',
18+
templateUrl: 'dialog.html',
19+
targetEvent: $event
20+
});
21+
}
22+
});
23+
})();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
.text-capitalize {
2+
text-transform: capitalize;
3+
}
4+
5+
.md-fab:hover, .md-fab.md-focused {
6+
background-color: #000 !important;
7+
}
8+
9+
p.note {
10+
font-size: 1.2rem;
11+
}
12+
13+
.lock-size {
14+
min-width: 300px;
15+
min-height: 300px;
16+
width: 300px;
17+
height: 300px;
18+
margin-left: auto;
19+
margin-right: auto;
20+
}
21+
22+
.md-fab.demo-fab.trigger-fab, .md-fab.demo-fab.action-fab {
23+
&:hover, &.md-focused {
24+
background-color: #333;
25+
}
26+
}
27+
28+
.md-fab.demo-fab.action-fab {
29+
background-color: #aaa;
30+
}

src/components/fabSpeedDial/fabSpeedDial.js

+24-8
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,24 @@
7979
// Define our open/close functions
8080
// Note: Used by fabTrigger and fabActions directives
8181
vm.open = function() {
82-
$scope.$apply('vm.isOpen = true');
82+
// Async eval to avoid conflicts with existing digest loops
83+
$scope.$evalAsync("vm.isOpen = true");
8384
};
8485

8586
vm.close = function() {
86-
$scope.$apply('vm.isOpen = false');
87+
// Async eval to avoid conflicts with existing digest loops
88+
// Only close if we do not currently have mouse focus (since child elements can call this)
89+
!vm.moused && $scope.$evalAsync("vm.isOpen = false");
90+
};
91+
92+
vm.mouseenter = function() {
93+
vm.moused = true;
94+
vm.open();
95+
};
96+
97+
vm.mouseleave = function() {
98+
vm.moused = false;
99+
vm.close();
87100
};
88101

89102
setupDefaults();
@@ -101,8 +114,8 @@
101114

102115
// Setup our event listeners
103116
function setupListeners() {
104-
$element.on('mouseenter', vm.open);
105-
$element.on('mouseleave', vm.close);
117+
$element.on('mouseenter', vm.mouseenter);
118+
$element.on('mouseleave', vm.mouseleave);
106119
}
107120

108121
// Setup our watchers
@@ -142,18 +155,19 @@
142155
angular.forEach(items, function(item, index) {
143156
var styles = item.style;
144157

145-
styles.transform = '';
158+
styles.transform = styles.webkitTransform = '';
146159
styles.transitionDelay = '';
147160
styles.opacity = 1;
148161

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

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

158172
switch (ctrl.direction) {
159173
case 'up':
@@ -174,7 +188,9 @@
174188
break;
175189
}
176190

177-
item.style.transform = 'translate' + axis + '(' + newPosition + 'px)';
191+
var newTranslate = 'translate' + axis + '(' + newPosition + 'px)';
192+
193+
styles.transform = styles.webkitTransform = newTranslate;
178194
});
179195
}
180196
}
@@ -205,7 +221,7 @@
205221
offsetDelay = index * delay;
206222

207223
styles.opacity = ctrl.isOpen ? 1 : 0;
208-
styles.transform = ctrl.isOpen ? 'scale(1)' : 'scale(0)';
224+
styles.transform = styles.webkitTransform = ctrl.isOpen ? 'scale(1)' : 'scale(0)';
209225
styles.transitionDelay = (ctrl.isOpen ? offsetDelay : (items.length - offsetDelay)) + 'ms';
210226
});
211227
}

src/components/fabSpeedDial/fabSpeedDial.scss

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ md-fab-speed-dial {
1717
display: flex;
1818

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

2222
.md-fab-action-item {
2323
visibility: hidden;

src/components/fabSpeedDial/fabSpeedDial.spec.js

+4
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ describe('<md-fab-speed-dial> directive', function() {
3838
);
3939

4040
element.find('button').triggerHandler('focus');
41+
pageScope.$digest();
4142
expect(controller.isOpen).toBe(true);
4243
}));
4344

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

4950
element.find('button').triggerHandler('focus');
51+
pageScope.$digest();
5052
expect(controller.isOpen).toBe(true);
5153
}));
5254

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

5860
element.find('button').triggerHandler('focus');
61+
pageScope.$digest();
5962
expect(controller.isOpen).toBe(true);
6063

6164
element.find('button').triggerHandler('blur');
65+
pageScope.$digest();
6266
expect(controller.isOpen).toBe(false);
6367
}));
6468

0 commit comments

Comments
 (0)