@@ -338,14 +338,12 @@ angular
338338 * Overlapping the panel with an element:
339339 * `new MdPanelPosition()
340340 * .relativeTo(someElement)
341- * .withPanelXPosition($mdPanel.xPosition.ALIGN_START)
342- * .withPanelYPosition($mdPanel.yPosition.ALIGN_TOPS);`
341+ * .addPanelPosition($mdPanel.xPosition.ALIGN_START, $mdPanel.yPosition.ALIGN_TOPS);`
343342 *
344343 * Aligning the panel with the bottom of an element:
345344 * `new MdPanelPosition()
346345 * .relativeTo(someElement)
347- * .withPanelXPosition($mdPanel.xPosition.CENTER)
348- * .withPanelYPosition($mdPanel.yPosition.BELOW);`
346+ * .addPanelPosition($mdPanel.xPosition.CENTER, $mdPanel.yPosition.BELOW);
349347 */
350348
351349/**
@@ -438,10 +436,15 @@ angular
438436
439437/**
440438 * @ngdoc method
441- * @name MdPanelPosition#withPanelXPosition
439+ * @name MdPanelPosition#addPanelPosition
442440 * @param {string } xPosition
441+ * @param {string } yPosition
443442 * @description
444- * Sets the x position for the panel relative to another element.
443+ * Sets the x and y position for the panel relative to another element. Can be
444+ * called multiple times to specify an ordered list of panel positions. The
445+ * first position which allows the panel to be completely on-screen will be
446+ * chosen; the last position will be chose whether it is on-screen or not.
447+ *
445448 * xPosition must be one of the following values available on
446449 * $mdPanel.xPosition:
447450 *
@@ -459,14 +462,7 @@ angular
459462 * C: CENTER
460463 * D: ALIGN_END (for LTR displays)
461464 * E: OFFSET_END (for LTR displays)
462- */
463-
464- /**
465- * @ngdoc method
466- * @name MdPanelPosition#withPanelYPosition
467- * @param {string } yPosition
468- * @description
469- * Sets the y position for the panel relative to another element.
465+ *
470466 * yPosition must be one of the following values available on
471467 * $mdPanel.yPosition:
472468 *
@@ -485,6 +481,7 @@ angular
485481 * H: CENTER
486482 * I: ALIGN_BOTTOMS
487483 * J: ABOVE
484+ * @returns {MdPanelPosition }
488485 */
489486
490487/**
@@ -1090,7 +1087,7 @@ MdPanelRef.prototype._addStyles = function() {
10901087 return this . _$q ( function ( resolve ) {
10911088 self . _panelContainer . css ( 'z-index' , self . _config [ 'zIndex' ] ) ;
10921089 self . _panelEl . css ( 'z-index' , self . _config [ 'zIndex' ] + 1 ) ;
1093-
1090+
10941091 if ( self . _config [ 'fullscreen' ] ) {
10951092 self . _panelEl . addClass ( '_md-panel-fullscreen' ) ;
10961093 resolve ( self ) ;
@@ -1436,11 +1433,8 @@ function MdPanelPosition() {
14361433 /** @private {!Array<string>} */
14371434 this . _translateY = [ ] ;
14381435
1439- /** @private {string} */
1440- this . _xPosition = '' ;
1441-
1442- /** @private {string} */
1443- this . _yPosition = '' ;
1436+ /** @private {!Array<{x:string, y:string}> } */
1437+ this . _positions = [ ] ;
14441438}
14451439
14461440
@@ -1583,60 +1577,77 @@ MdPanelPosition.prototype.relativeTo = function(element) {
15831577
15841578
15851579/**
1586- * Sets the x position for the panel relative to another element.
1587- * xPosition must be one of the MdPanelPosition.xPosition values.
1588- *
1589- * @param {string } xPosition
1580+ * Sets the x and y positions for the panel relative to another element.
1581+ * @param {string } xPosition must be one of the MdPanelPosition.xPosition values.
1582+ * @param {string } yPosition must be one of the MdPanelPosition.yPosition values.
15901583 * @returns {MdPanelPosition }
15911584 */
1592- MdPanelPosition . prototype . withPanelXPosition = function ( xPosition ) {
1585+ MdPanelPosition . prototype . addPanelPosition = function ( xPosition , yPosition ) {
15931586 if ( ! this . _relativeToRect ) {
1594- throw new Error ( 'withPanelXPosition can only be used with relative' +
1587+ throw new Error ( 'addPanelPosition can only be used with relative ' +
15951588 'positioning. Set relativeTo first.' ) ;
15961589 }
15971590
1598- var positionKeys = Object . keys ( MdPanelPosition . xPosition ) ;
1591+ this . _validateXPosition ( xPosition ) ;
1592+ this . _validateYPosition ( yPosition ) ;
1593+
1594+ this . _positions . push ( {
1595+ x : xPosition ,
1596+ y : yPosition ,
1597+ } ) ;
1598+ return this ;
1599+ } ;
1600+
1601+
1602+ /**
1603+ * Ensure that yPosition is a valid position name. Throw an exception if not.
1604+ * @param {string } yPosition
1605+ */
1606+ MdPanelPosition . prototype . _validateYPosition = function ( yPosition ) {
1607+ // empty is ok
1608+ if ( yPosition == null ) {
1609+ return ;
1610+ }
1611+
1612+ var positionKeys = Object . keys ( MdPanelPosition . yPosition ) ;
15991613 var positionValues = [ ] ;
16001614 for ( var key , i = 0 ; key = positionKeys [ i ] ; i ++ ) {
1601- var position = MdPanelPosition . xPosition [ key ] ;
1615+ var position = MdPanelPosition . yPosition [ key ] ;
16021616 positionValues . push ( position ) ;
1603- if ( position === xPosition ) {
1604- this . _xPosition = xPosition ;
1605- return this ;
1617+
1618+ if ( position === yPosition ) {
1619+ return ;
16061620 }
16071621 }
16081622
1609- throw new Error ( 'withPanelXPosition only accepts the following values:\n' +
1610- positionValues . join ( ' | ' ) ) ;
1623+ throw new Error ( 'Panel y position only accepts the following values:\n' +
1624+ positionValues . join ( ' | ' ) ) ;
16111625} ;
16121626
16131627
16141628/**
1615- * Sets the y position for the panel relative to another element.
1616- * yPosition must be one of the MdPanelPosition.yPosition values.
1617- *
1618- * @param {string } yPosition
1619- * @returns {MdPanelPosition }
1629+ * Ensure that xPosition is a valid position name. Throw an exception if not.
1630+ * @param {string } xPosition
16201631 */
1621- MdPanelPosition . prototype . withPanelYPosition = function ( yPosition ) {
1622- if ( ! this . _relativeToRect ) {
1623- throw new Error ( 'withPanelYPosition can only be used with relative ' +
1624- 'positioning. Set relativeTo first.' ) ;
1632+ MdPanelPosition . prototype . _validateXPosition = function ( xPosition ) {
1633+ // empty is ok
1634+ if ( xPosition == null ) {
1635+ return ;
16251636 }
16261637
1627- var positionKeys = Object . keys ( MdPanelPosition . yPosition ) ;
1638+ var positionKeys = Object . keys ( MdPanelPosition . xPosition ) ;
16281639 var positionValues = [ ] ;
16291640 for ( var key , i = 0 ; key = positionKeys [ i ] ; i ++ ) {
1630- var position = MdPanelPosition . yPosition [ key ] ;
1641+ var position = MdPanelPosition . xPosition [ key ] ;
16311642 positionValues . push ( position ) ;
1632- if ( position === yPosition ) {
1633- this . _yPosition = yPosition ;
1634- return this ;
1643+ if ( position === xPosition ) {
1644+ return ;
16351645 }
16361646 }
16371647
1638- throw new Error ( 'withPanelYPosition only accepts the following values:\n' +
1648+ throw new Error ( 'Panel x Position only accepts the following values:\n' +
16391649 positionValues . join ( ' | ' ) ) ;
1650+
16401651} ;
16411652
16421653
@@ -1722,6 +1733,16 @@ MdPanelPosition.prototype.getTransform = function() {
17221733} ;
17231734
17241735
1736+ /**
1737+ * Gets the first x/y position that can fit on-screen.
1738+ * @returns {string }
1739+ */
1740+ MdPanelPosition . prototype . getActualPosition = function ( ) {
1741+ // TODO(gmoothart): intelligently pick the first on-screen position.
1742+ return this . _positions [ 0 ] || { } ;
1743+ } ;
1744+
1745+
17251746/**
17261747 * Reduces a list of translate values to a string that can be used within
17271748 * transform.
@@ -1765,7 +1786,9 @@ MdPanelPosition.prototype._calculatePanelPosition = function(panelEl) {
17651786 var targetRight = targetBounds . right ;
17661787 var targetWidth = targetBounds . width ;
17671788
1768- switch ( this . _xPosition ) {
1789+ var pos = this . getActualPosition ( ) ;
1790+
1791+ switch ( pos . x ) {
17691792 case MdPanelPosition . xPosition . OFFSET_START :
17701793 // TODO(ErinCoughlan): Change OFFSET_START for rtl vs ltr.
17711794 this . _left = targetLeft - panelWidth + 'px' ;
@@ -1792,7 +1815,7 @@ MdPanelPosition.prototype._calculatePanelPosition = function(panelEl) {
17921815 var targetBottom = targetBounds . bottom ;
17931816 var targetHeight = targetBounds . height ;
17941817
1795- switch ( this . _yPosition ) {
1818+ switch ( pos . y ) {
17961819 case MdPanelPosition . yPosition . ABOVE :
17971820 this . _top = targetTop - panelHeight + 'px' ;
17981821 break ;
0 commit comments