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

Commit 623496e

Browse files
fix(backdrop, dialog, css): improve position and animations of backdrop
improve backdrop animations and css to account for scroll and parenting: - backdrop - css uses transition and ng-enter/ng-leav - css transitions opacity instead of background-color - css no longer uses key frames - postLink uses $animate.pin if available - postLink logs a warning if the backdrop parent has a style 'position:static' - util - disableElementScroll uses specified element or body; used by dialog to disable dialog parent scrolling when parent is explicitly specified - refactor(util): centralize use of backdrop $compile - dialog - css for 'md-dialog-container' is now 'position:absolute'; 'fixed' is deprecated - hide backdrop now runs in parallel with hide dialog - basic demo #1 now uses element '#popupContainer' as parent; instead of document.body - basic demo #1 has #popupContainer 'position:relative' styling Fixes #3826, Fixes #3828, Fixes #1967, Fixes #1106. Closes #3841.
1 parent c5c148d commit 623496e

File tree

17 files changed

+89
-59
lines changed

17 files changed

+89
-59
lines changed

config/build.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ var fs = require('fs');
33
var versionFile = __dirname + '/../dist/commit';
44

55
module.exports = {
6-
ngVersion: '1.3.15',
6+
ngVersion: '1.4.3',
77
version: pkg.version,
88
repository: pkg.repository.url
99
.replace(/^git/,'https')

src/components/backdrop/backdrop.js

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,35 @@
1717
*
1818
*/
1919

20-
angular.module('material.components.backdrop', [
21-
'material.core'
22-
])
23-
.directive('mdBackdrop', BackdropDirective);
24-
25-
function BackdropDirective($mdTheming) {
26-
return $mdTheming;
27-
}
20+
angular
21+
.module('material.components.backdrop', ['material.core'])
22+
.directive('mdBackdrop', function BackdropDirective($mdTheming, $animate, $rootElement, $window, $log, $$rAF) {
23+
24+
return {
25+
restrict: 'E',
26+
link: postLink
27+
};
28+
29+
function postLink(scope, element, attrs) {
30+
// backdrop may be outside the $rootElement, tell ngAnimate to animate regardless
31+
if( $animate.pin ) $animate.pin(element,$rootElement);
32+
33+
$$rAF(function(){
34+
// Often $animate.enter() is used to append the backDrop element
35+
// so let's wait until $animate is done...
36+
37+
var parent = element.parent()[0];
38+
if ( parent ) {
39+
var position = $window.getComputedStyle(parent).getPropertyValue('position');
40+
if (position == 'static') {
41+
// backdrop uses position:absolute and will not work properly with parent position:static (default)
42+
var positionError = "<md-backdrop> may not work properly in a scrolled, static-positioned parent container.";
43+
$log.warn( positionError );
44+
}
45+
}
46+
47+
$mdTheming.inherit(element, element.parent());
48+
});
49+
50+
};
51+
});

src/components/backdrop/backdrop.scss

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ md-backdrop {
1616
z-index: $z-index-sidenav - 1;
1717
}
1818

19+
opacity: 1;
20+
transition: opacity 600ms $swift-ease-in-timing-function;
21+
1922
background-color: rgba(0,0,0,0);
2023

2124
position: absolute;
@@ -25,27 +28,27 @@ md-backdrop {
2528
right: 0;
2629

2730
&.md-click-catcher {
28-
top: 0;
2931
position: fixed;
3032
}
3133

3234
&.ng-enter {
33-
animation: $swift-ease-out-timing-function mdBackdropFadeIn 0.5s both;
35+
opacity: 0;
36+
&.ng-enter-active {
37+
opacity: 1;
38+
}
3439
}
40+
3541
&.ng-leave {
36-
animation: $swift-ease-in-timing-function mdBackdropFadeOut 0.4s both;
42+
opacity: 1;
43+
transition: opacity 400ms linear;
44+
45+
&.ng-leave-active {
46+
opacity: 0;
47+
}
3748
}
3849

3950
&.md-opaque {
4051
background-color: rgba(0,0,0,0.42);
4152
}
4253
}
4354

44-
@keyframes mdBackdropFadeIn {
45-
from { opacity: 0; }
46-
to { opacity: 1; }
47-
}
48-
@keyframes mdBackdropFadeOut {
49-
from { opacity: 1; }
50-
to { opacity: 0; }
51-
}

src/components/bottomSheet/bottomSheet.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ function MdBottomSheetProvider($$interimElementProvider) {
125125
});
126126

127127
/* @ngInject */
128-
function bottomSheetDefaults($animate, $mdConstant, $mdUtil, $compile, $mdTheming, $mdBottomSheet, $rootElement, $mdGesture) {
128+
function bottomSheetDefaults($animate, $mdConstant, $mdUtil, $mdTheming, $mdBottomSheet, $rootElement, $mdGesture) {
129129
var backdrop;
130130

131131
return {
@@ -143,7 +143,7 @@ function MdBottomSheetProvider($$interimElementProvider) {
143143
element = $mdUtil.extractElementByName(element, 'md-bottom-sheet');
144144

145145
// Add a backdrop that will close on click
146-
backdrop = $compile('<md-backdrop class="md-opaque md-bottom-sheet-backdrop">')(scope);
146+
backdrop = $mdUtil.createBackdrop(scope, "md-bottom-sheet-backdrop md-opaque");
147147
backdrop.on('click', function() {
148148
$mdUtil.nextTick($mdBottomSheet.cancel,true);
149149
});

src/components/dialog/demoBasicUsage/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
<div ng-controller="AppCtrl" class="md-padding">
1+
<div ng-controller="AppCtrl" class="md-padding" id="popupContainer">
22
<p class="inset">
33
Open a dialog over the app's content. Press escape or click outside to close the dialog and
44
send focus back to the triggering button.
55
</p>
66

7-
<div class="dialog-demo-content" layout="row" layout-wrap>
7+
<div class="dialog-demo-content" layout="row" layout-wrap >
88
<md-button class="md-primary md-raised" ng-click="showAlert($event)" flex flex-md="100">
99
Alert Dialog
1010
</md-button>

src/components/dialog/demoBasicUsage/script.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ angular.module('dialogDemo1', ['ngMaterial'])
99
// to prevent interaction outside of dialog
1010
$mdDialog.show(
1111
$mdDialog.alert()
12-
.parent(angular.element(document.body))
12+
.parent(angular.element(document.querySelector('#popupContainer')))
1313
.clickOutsideToClose(true)
1414
.title('This is an alert title')
1515
.content('You can specify some description text in here.')
@@ -22,7 +22,6 @@ angular.module('dialogDemo1', ['ngMaterial'])
2222
$scope.showConfirm = function(ev) {
2323
// Appending dialog to document.body to cover sidenav in docs app
2424
var confirm = $mdDialog.confirm()
25-
.parent(angular.element(document.body))
2625
.title('Would you like to delete your debt?')
2726
.content('All of the banks have agreed to forgive you your debts.')
2827
.ariaLabel('Lucky day')
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#popupContainer {
2+
position:relative;
3+
}

src/components/dialog/dialog.js

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -430,8 +430,7 @@ function MdDialogProvider($$interimElementProvider) {
430430
}
431431

432432
/* @ngInject */
433-
function dialogDefaultOptions($mdAria, $document, $mdUtil, $mdConstant, $mdTheming, $mdDialog, $animate, $q ) {
434-
433+
function dialogDefaultOptions($mdDialog, $mdAria, $mdUtil, $mdConstant, $animate, $document) {
435434
return {
436435
hasBackdrop: true,
437436
isolateScope: true,
@@ -456,7 +455,7 @@ function MdDialogProvider($$interimElementProvider) {
456455

457456
captureSourceAndParent(element, options);
458457
configureAria(element.find('md-dialog'), options);
459-
showBackdrop(element, options);
458+
showBackdrop(scope, element, options);
460459

461460
return dialogPopIn(element, options)
462461
.then(function () {
@@ -492,10 +491,11 @@ function MdDialogProvider($$interimElementProvider) {
492491
options.deactivateListeners();
493492
options.unlockScreenReader();
494493

494+
options.hideBackdrop();
495+
495496
return dialogPopOut(element, options)
496497
.finally(function () {
497498
angular.element($document[0].body).removeClass('md-dialog-is-showing');
498-
options.hideBackdrop();
499499
element.remove();
500500

501501
options.origin.focus();
@@ -522,7 +522,7 @@ function MdDialogProvider($$interimElementProvider) {
522522
options.parent = angular.element(options.parent);
523523

524524
if (options.disableParentScroll) {
525-
options.restoreScroll = $mdUtil.disableScrollAround(element);
525+
options.restoreScroll = $mdUtil.disableScrollAround(element,options.parent);
526526
}
527527
}
528528

@@ -594,7 +594,7 @@ function MdDialogProvider($$interimElementProvider) {
594594
/**
595595
* Show modal backdrop element...
596596
*/
597-
function showBackdrop(element, options) {
597+
function showBackdrop(scope, element, options) {
598598

599599
if (options.hasBackdrop) {
600600
// Fix for IE 10
@@ -605,9 +605,7 @@ function MdDialogProvider($$interimElementProvider) {
605605

606606
element.css('top', parentOffset + 'px');
607607

608-
options.backdrop = angular.element('<md-backdrop class="md-dialog-backdrop md-opaque">');
609-
options.backdrop.css('top', parentOffset + 'px');
610-
$mdTheming.inherit(options.backdrop, options.parent);
608+
options.backdrop = $mdUtil.createBackdrop(scope, "md-dialog-backdrop md-opaque");
611609

612610
$animate.enter(options.backdrop, options.parent);
613611
}

src/components/dialog/dialog.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ $dialog-padding: $baseline-grid * 3;
77
display: flex;
88
justify-content: center;
99
align-items: center;
10-
position: fixed;
10+
position: absolute;
1111
top: 0;
1212
left: 0;
1313
width: 100%;

src/components/menu/_menu.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,6 @@ function MenuDirective($mdMenu) {
151151
triggerElement = triggerElement.querySelector('[ng-click]');
152152
}
153153
triggerElement && triggerElement.setAttribute('aria-haspopup', 'true');
154-
triggerElement.setAttribute('type', 'button');
155154
if (templateElement.children().length != 2) {
156155
throw Error('Invalid HTML for md-menu. Expected two children elements.');
157156
}

0 commit comments

Comments
 (0)