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

Commit

Permalink
fix(fabSpeedDial): Make hovering an option via CSS.
Browse files Browse the repository at this point in the history
Initially, the speed dial was designed to always open
when the user hovered over any portion of the speed
dial (including the area where the actions would
eventually appear). However, this made the speed dial
unusable on mobile (and sometimes unusable on desktop)
because it disallowed the user from pressing anything
underneath the actions.

*  Add the `md-hover-full` CSS class to allow developer configuration of this behavior.
*  Ensure fabToolbar also works this way, and fix jumpy animation.
*  Also updated the docs/demos and made the demos easier to use on mobile.

BREAKING CHANGE - The fabSpeedDial no longer automatically
opens when hovering over the invisible actions. Add the
`md-hover-full` class to enable this interaction.

Fixes #4259. Closes #4847.
  • Loading branch information
topherfangio authored and ThomasBurleson committed Oct 6, 2015
1 parent 546eb84 commit bbbc475
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 97 deletions.
10 changes: 3 additions & 7 deletions src/components/fabSpeedDial/demoBasicUsage/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
</div>

<div layout="row" layout-align="space-around">
<div layout="column">
<div layout="column" layout-align="start center">
<b>Direction</b>

<md-radio-group ng-model="demo.selectedDirection">
Expand All @@ -40,7 +40,7 @@
</md-radio-group>
</div>

<div layout="column">
<div layout="column" layout-align="start center">
<b>Open/Closed</b>

<md-radio-group ng-model="demo.isOpen">
Expand All @@ -49,7 +49,7 @@
</md-radio-group>
</div>

<div layout="column">
<div layout="column" layout-align="start center">
<b>Animation Modes</b>

<md-radio-group ng-model="demo.selectedMode">
Expand All @@ -60,9 +60,5 @@
</div>
</div>

<p class="note">
Note that you can also hover over the directive's area or tab through each button to open and
activate the speed dial menu.
</p>
</md-content>
</div>
126 changes: 72 additions & 54 deletions src/components/fabSpeedDial/demoMoreOptions/index.html
Original file line number Diff line number Diff line change
@@ -1,36 +1,68 @@
<div layout="column" ng-controller="DemoCtrl as demo" ng-cloak>
<md-content class="md-padding" layout="column">
<p>

<p class="intro">
The speed dial supports many advanced usage scenarios. This demo shows many of them mixed
together.
together... and even includes a Toolbar - SpeedDial combination.
</p>

<div class="lock-size" layout="row" layout-align="center center">
<md-fab-speed-dial ng-hide="demo.hidden" md-direction="down" class="md-fling"
md-open="demo.isOpen"
ng-mouseenter="demo.isOpen=true" ng-mouseleave="demo.isOpen=false">
<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" aria-label="menu"></md-icon>
<md-toolbar>
<h3>
<md-button>Test</md-button>
<md-button>Test</md-button>
<md-button hide-sm>Test</md-button>
<md-button hide-sm>Test</md-button>
<md-button hide-sm>Test</md-button>
<md-button hide-sm>Test</md-button>
<md-button hide-sm>Test</md-button>
</h3>
</md-toolbar>

<md-fab-speed-dial ng-hide="demo.hidden" md-direction="left" md-open="demo.isOpen"
class="md-scale md-fab-top-right" ng-class="{ 'md-hover-full': demo.hover }"
ng-mouseenter="demo.isOpen=true" ng-mouseleave="demo.isOpen=false">
<md-fab-trigger>
<md-button aria-label="menu" class="md-fab md-warn">
<md-tooltip md-direction="top" md-visible="tooltipVisible">Menu</md-tooltip>
<md-icon md-svg-src="img/icons/menu.svg" aria-label="menu"></md-icon>
</md-button>
</md-fab-trigger>

<md-fab-actions>
<div ng-repeat="item in demo.items">
<md-button aria-label="{{item.name}}" class="md-fab md-raised md-mini"
ng-click="demo.openDialog($event, item)">
<md-tooltip md-direction="{{item.direction}}" md-visible="tooltipVisible"
md-autohide="false">
{{item.name}}
</md-tooltip>

<md-icon md-svg-src="{{item.icon}}" aria-label="{{item.name}}"></md-icon>
</md-button>
</md-fab-trigger>

<md-fab-actions>
<div ng-repeat="item in demo.items">
<md-button aria-label="{{item.name}}" class="md-fab md-raised md-mini"
ng-click="demo.openDialog($event, item)">
<md-tooltip md-direction="{{item.direction}}">{{item.name}}</md-tooltip>
<md-icon md-svg-src="{{item.icon}}" aria-label="{{item.name}}"></md-icon>
</md-button>
</div>
</md-fab-actions>
</md-fab-speed-dial>
</div>
</div>
</md-fab-actions>
</md-fab-speed-dial>
</md-content>

<md-content class="md-padding" layout="row">
<div flex="50">
<md-content class="md-padding" layout="row" layout-sm="column" layout-align="space-around">
<div flex-gt-sm="45">
<h3>Tooltips</h3>

<p>
Each action item supports a tooltip using the standard approach as can be seen above.
</p>

<h3>ngHide</h3>

<p>
The speed dial also supports hiding using the standard <code>ng-hide</code> attribute. View
the source to see how to apply the animation effect.

<md-checkbox ng-model="demo.hidden">
Hide the speed dial.
</md-checkbox>
</p>

<h3>ngRepeat</h3>

<p>
Expand All @@ -43,53 +75,39 @@ <h3>ngRepeat</h3>
that wraps your items.
</p>
</div>
<div flex="50">
<h3>$mdDialog</h3>

<div flex-gt-sm="45">
<h3>Hovering</h3>

<p>
You can also use the buttons to open a dialog. When clicked, the buttons above will open a
dialog showing a message which item was clicked.
You can also easily setup the speed dial to open on hover using the
<code>ng-mouseenter</code> and <code>ng-mouseleave</code> attributes.
</p>
</div>
</md-content>

<md-content class="md-padding" layout="row">
<div flex="50">
<h3>ngHide</h3>

<p>
The speed dial also supports hiding using the standard <code>ng-hide</code> attribute.
If you want the user to be able to hover over the empty area where the
actions will eventually appear, you must also add the
<code>md-hover-full</code> class to the speed dial element.

<md-checkbox ng-model="demo.hidden">
Hide the speed dial.
<md-checkbox ng-model="demo.hover">
Enable "full hover" mode.
</md-checkbox>
</p>
</div>
<div flex="50">
<h3>Tooltips</h3>

<p>
Each action item supports a tooltip using the standard approach as can be seen above.
Notice that in "full hover" mode, you cannot click on the last "Test" buttons on the toolbar
as they are hidden by the speed dial. See the example code and docs for more information.
</p>
</div>
</md-content>

<md-content class="md-padding" layout="row">
<div flex="50">
<h3>Hovering</h3>

<p>
You can also easily setup the speed dial to open on hover using the
<code>ng-mouseenter</code> and <code>ng-mouseleave</code> attributes.
</p>
<h3>$mdDialog</h3>

<p>
See the example code for more information.
You can also use the buttons to open a dialog. When clicked, the buttons above will open a
dialog showing a message which item was clicked.
</p>
</div>
</md-content>


<script type="text/ng-template" id="dialog.html">
<md-dialog>
<md-dialog-content>Hello User! You clicked {{dialog.item.name}}.</md-dialog-content>
Expand Down
22 changes: 18 additions & 4 deletions src/components/fabSpeedDial/demoMoreOptions/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,29 @@
'use strict';

angular.module('fabSpeedDialDemoMoreOptions', ['ngMaterial'])
.controller('DemoCtrl', function($mdDialog) {
.controller('DemoCtrl', function($scope, $mdDialog, $timeout) {
var self = this;

self.hidden = false;
self.isOpen = false;
self.hover = false;

// On opening, add a delayed property which shows tooltips after the speed dial has opened
// so that they have the proper position; if closing, immediately hide the tooltips
$scope.$watch('demo.isOpen', function(isOpen) {
if (isOpen) {
$timeout(function() {
$scope.tooltipVisible = self.isOpen;
}, 600);
} else {
$scope.tooltipVisible = self.isOpen;
}
});

self.items = [
{name: "Twitter", icon: "img/icons/twitter.svg", direction: "left" },
{name: "Facebook", icon: "img/icons/facebook.svg", direction: "right" },
{name: "Google Hangout", icon: "img/icons/hangout.svg", direction: "left" }
{ name: "Twitter", icon: "img/icons/twitter.svg", direction: "bottom" },
{ name: "Facebook", icon: "img/icons/facebook.svg", direction: "top" },
{ name: "Google Hangout", icon: "img/icons/hangout.svg", direction: "bottom" }
];

self.openDialog = function($event, item) {
Expand Down
46 changes: 39 additions & 7 deletions src/components/fabSpeedDial/demoMoreOptions/style.scss
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
.lock-size {
min-width: 300px;
min-height: 300px;
width: 300px;
height: 300px;
margin-left: auto;
margin-right: auto;
// Line the fab up properly on different screen sizes/layouts
.md-fab-top-right {
top: 16px;
}

@media only screen and (max-device-width: 600px) {
.md-fab-top-right {
top: 9px;
right: 9px;
}
}

.md-fab.demo-fab.trigger-fab, .md-fab.demo-fab.action-fab {
Expand All @@ -23,3 +26,32 @@ md-content div {
padding: 15px;
}
}


md-fab-speed-dial {

// Offset to align with toolbar area
margin-top: 89px;

// Add a simple scale transition to the trigger when hiding/showing the speed dial
md-fab-trigger {
transition: all 0.3s ease-in-out;
transform: scale(1);
}

// Note: you MUST use an existing CSS class for the animation to fire properly
&.md-scale, &.md-fling {
&.ng-hide {
// Use !important to override ng-hide's `display: none !important`
display: flex !important;

md-fab-trigger {
transform: scale(0);
}
}
}
}

.intro {
padding-left:5px;
}
14 changes: 14 additions & 0 deletions src/components/fabSpeedDial/fabSpeedDial.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@
* These CSS classes use `position: absolute`, so you need to ensure that the container element
* also uses `position: absolute` or `position: relative` in order for them to work.
*
* Additionally, you may use the standard `ng-mouseenter` and `ng-mouseleave` directives to
* open or close the speed dial. However, if you wish to allow users to hover over the empty
* space where the actions will appear, you must also add the `md-hover-full` class to the speed
* dial element. Without this, the hover effect will only occur on top of the trigger.
*
* @usage
* <hljs lang="html">
* <md-fab-speed-dial md-direction="up" class="md-fling">
Expand Down Expand Up @@ -182,6 +187,12 @@
var ctrl = element.controller('mdFabSpeedDial');
var items = el.querySelectorAll('.md-fab-action-item');

// Grab our element which stores CSS variables
var variablesElement = el.querySelector('.md-css-variables');

// Setup JS variables based on our CSS variables
var startZIndex = parseInt(window.getComputedStyle(variablesElement).zIndex);

// Always reset the items to their natural position/state
angular.forEach(items, function(item, index) {
var styles = item.style,
Expand All @@ -190,6 +201,9 @@
styles.opacity = ctrl.isOpen ? 1 : 0;
styles.transform = styles.webkitTransform = ctrl.isOpen ? 'scale(1)' : 'scale(0)';
styles.transitionDelay = (ctrl.isOpen ? offsetDelay : (items.length - offsetDelay)) + 'ms';

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

Expand Down
21 changes: 20 additions & 1 deletion src/components/fabSpeedDial/fabSpeedDial.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,27 @@ md-fab-speed-dial {
display: flex;
align-items: center;

// Include the top/left/bottom/right fab positions
// Include the top/left/bottom/right fab positions and set the z-index for absolute positioning
@include fab-all-positions();
z-index: $z-index-fab;

// Allow users to enable/disable hovering over the entire speed dial (i.e. the empty space where
// items will eventually appear)
&:not(.md-hover-full) {
// Turn off pointer events when closed
pointer-events: none;

md-fab-trigger, .md-fab-action-item {
// Always make the trigger and action items always have pointer events (the tooltip looks
// for the first parent with pointer-events, so we must set this for tooltips to work)
pointer-events: auto;
}

&.md-is-open {
// Turn on pointer events when open
pointer-events: auto;
}
}

.md-css-variables {
z-index: $z-index-fab;
Expand Down
Loading

0 comments on commit bbbc475

Please sign in to comment.