Skip to content

Commit d464904

Browse files
crisbetokara
authored andcommitted
update(panel): constrain panel to viewport boundries (angular#9651)
Prevents the panel from going outside the viewport by adjusting the position. If developers want more control over how the panel gets repositioned, they can specify addition fallback positions via `addPanelPosition`. Related to angular#9641. Fixes angular#7878.
1 parent 2c286b4 commit d464904

File tree

2 files changed

+239
-94
lines changed

2 files changed

+239
-94
lines changed

src/components/panel/panel.js

+47-1
Original file line numberDiff line numberDiff line change
@@ -2153,6 +2153,12 @@ MdPanelPosition.absPosition = {
21532153
LEFT: 'left'
21542154
};
21552155

2156+
/**
2157+
* Margin between the edges of a panel and the viewport.
2158+
* @const {number}
2159+
*/
2160+
MdPanelPosition.viewportMargin = 8;
2161+
21562162

21572163
/**
21582164
* Sets absolute positioning for the panel.
@@ -2536,6 +2542,9 @@ MdPanelPosition.prototype._reduceTranslateValues =
25362542
* @private
25372543
*/
25382544
MdPanelPosition.prototype._setPanelPosition = function(panelEl) {
2545+
// Remove the class in case it has been added before.
2546+
panelEl.removeClass('_md-panel-position-adjusted');
2547+
25392548
// Only calculate the position if necessary.
25402549
if (this._absolute) {
25412550
this._setTransform(panelEl);
@@ -2554,12 +2563,49 @@ MdPanelPosition.prototype._setPanelPosition = function(panelEl) {
25542563
this._setTransform(panelEl);
25552564

25562565
if (this._isOnscreen(panelEl)) {
2557-
break;
2566+
return;
25582567
}
25592568
}
2569+
2570+
// Class that can be used to re-style the panel if it was repositioned.
2571+
panelEl.addClass('_md-panel-position-adjusted');
2572+
this._constrainToViewport(panelEl);
25602573
};
25612574

25622575

2576+
/**
2577+
* Constrains a panel's position to the viewport.
2578+
* @param {!angular.JQLite} panelEl
2579+
* @private
2580+
*/
2581+
MdPanelPosition.prototype._constrainToViewport = function(panelEl) {
2582+
var margin = MdPanelPosition.viewportMargin;
2583+
2584+
if (this.getTop()) {
2585+
var top = parseInt(this.getTop());
2586+
var bottom = panelEl[0].offsetHeight + top;
2587+
var viewportHeight = this._$window.innerHeight;
2588+
2589+
if (top < margin) {
2590+
this._top = margin + 'px';
2591+
} else if (bottom > viewportHeight) {
2592+
this._top = top - (bottom - viewportHeight + margin) + 'px';
2593+
}
2594+
}
2595+
2596+
if (this.getLeft()) {
2597+
var left = parseInt(this.getLeft());
2598+
var right = panelEl[0].offsetWidth + left;
2599+
var viewportWidth = this._$window.innerWidth;
2600+
2601+
if (left < margin) {
2602+
this._left = margin + 'px';
2603+
} else if (right > viewportWidth) {
2604+
this._left = left - (right - viewportWidth + margin) + 'px';
2605+
}
2606+
}
2607+
};
2608+
25632609
/**
25642610
* Switches between 'start' and 'end'.
25652611
* @param {string} position Horizontal position of the panel

0 commit comments

Comments
 (0)