@@ -338,14 +338,13 @@ 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+ * .withPanelPosition ($mdPanel.xPosition.ALIGN_START,
342+ * $mdPanel.yPosition.ALIGN_TOPS);`
343343 *
344344 * Aligning the panel with the bottom of an element:
345345 * `new MdPanelPosition()
346346 * .relativeTo(someElement)
347- * .withPanelXPosition($mdPanel.xPosition.CENTER)
348- * .withPanelYPosition($mdPanel.yPosition.BELOW);`
347+ * .withPanelPosition($mdPanel.xPosition.CENTER, $mdPanel.yPosition.BELOW);
349348 */
350349
351350/**
@@ -438,10 +437,11 @@ angular
438437
439438/**
440439 * @ngdoc method
441- * @name MdPanelPosition#withPanelXPosition
442- * @param {string } xPosition
440+ * @name MdPanelPosition#withPanelPosition
441+ * @param {string } xpos
442+ * @param {string } ypos
443443 * @description
444- * Sets the x position for the panel relative to another element.
444+ * Sets the x and y position for the panel relative to another element.
445445 * xPosition must be one of the following values available on
446446 * $mdPanel.xPosition:
447447 *
@@ -459,14 +459,7 @@ angular
459459 * C: CENTER
460460 * D: ALIGN_END (for LTR displays)
461461 * 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.
462+ *
470463 * yPosition must be one of the following values available on
471464 * $mdPanel.yPosition:
472465 *
@@ -487,6 +480,16 @@ angular
487480 * J: ABOVE
488481 */
489482
483+ /**
484+ * @ngdoc method
485+ * @name MdPanelPosition#tryPanelPositions
486+ * @description
487+ * Specify an ordered list of panel positions. The first position which
488+ * allows the panel to be completely on-screen will be chosen; the last position
489+ * will be chose whether it is on-screen or not.
490+ * @param {!Array<{y: string, x:string}> } posArray
491+ */
492+
490493/**
491494 * @ngdoc method
492495 * @name MdPanelPosition#withOffsetX
@@ -1090,7 +1093,7 @@ MdPanelRef.prototype._addStyles = function() {
10901093 return this . _$q ( function ( resolve ) {
10911094 self . _panelContainer . css ( 'z-index' , self . _config [ 'zIndex' ] ) ;
10921095 self . _panelEl . css ( 'z-index' , self . _config [ 'zIndex' ] + 1 ) ;
1093-
1096+
10941097 if ( self . _config [ 'fullscreen' ] ) {
10951098 self . _panelEl . addClass ( '_md-panel-fullscreen' ) ;
10961099 resolve ( self ) ;
@@ -1436,11 +1439,8 @@ function MdPanelPosition() {
14361439 /** @private {!Array<string>} */
14371440 this . _translateY = [ ] ;
14381441
1439- /** @private {string} */
1440- this . _xPosition = '' ;
1441-
1442- /** @private {string} */
1443- this . _yPosition = '' ;
1442+ /** @private {!Array<{x:string, y:string}> } */
1443+ this . _positions = [ ] ;
14441444}
14451445
14461446
@@ -1583,60 +1583,92 @@ MdPanelPosition.prototype.relativeTo = function(element) {
15831583
15841584
15851585/**
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
1590- * @returns {MdPanelPosition }
1586+ * Sets the x and y postion for the panel relative to another element.
1587+ * @param {string } x must be one of the MdPanelPosition.xPosition values.
1588+ * @param {string } y must be one of the MdPanelPosition.yPosition values.
15911589 */
1592- MdPanelPosition . prototype . withPanelXPosition = function ( xPosition ) {
1590+ MdPanelPosition . prototype . withPanelPosition = function ( x , y ) {
15931591 if ( ! this . _relativeToRect ) {
1594- throw new Error ( 'withPanelXPosition can only be used with relative' +
1592+ throw new Error ( 'withPanelPosition can only be used with relative ' +
15951593 'positioning. Set relativeTo first.' ) ;
15961594 }
15971595
1598- var positionKeys = Object . keys ( MdPanelPosition . xPosition ) ;
1599- var positionValues = [ ] ;
1600- for ( var key , i = 0 ; key = positionKeys [ i ] ; i ++ ) {
1601- var position = MdPanelPosition . xPosition [ key ] ;
1602- positionValues . push ( position ) ;
1603- if ( position === xPosition ) {
1604- this . _xPosition = xPosition ;
1605- return this ;
1606- }
1607- }
1596+ // validate
1597+ this . _validateXPosition ( x ) ;
1598+ this . _validateYPosition ( y ) ;
16081599
1609- throw new Error ( 'withPanelXPosition only accepts the following values:\n' +
1610- positionValues . join ( ' | ' ) ) ;
1600+ this . _positions . push ( {
1601+ x : x ,
1602+ y : y ,
1603+ } ) ;
1604+ return this ;
16111605} ;
16121606
16131607
16141608/**
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 }
1609+ * Specify an ordered list of panel positions. The first position which
1610+ * allows the panel to be completely on-screen will be chosen; the last position
1611+ * will be chose whether it is on-screen or not.
1612+ * @param {!Array<{x:string, y:string}> } pos
16201613 */
1621- MdPanelPosition . prototype . withPanelYPosition = function ( yPosition ) {
1614+ MdPanelPosition . prototype . tryPanelPositions = function ( posArray ) {
16221615 if ( ! this . _relativeToRect ) {
1623- throw new Error ( 'withPanelYPosition can only be used with relative ' +
1616+ throw new Error ( 'tryPanelPositions can only be used with relative ' +
16241617 'positioning. Set relativeTo first.' ) ;
16251618 }
16261619
1620+ // validate
1621+ for ( var i = 0 ; i < pos . length ; i ++ ) {
1622+ this . _validateXPosition ( pos . x ) ;
1623+ this . _validateYPosition ( pos . y ) ;
1624+ } ;
1625+
1626+ this . _positions = this . _positions . concat ( posArray ) ;
1627+ return this ;
1628+ } ;
1629+
1630+
1631+ MdPanelPosition . prototype . _validateYPosition = function ( ypos ) {
1632+ // empty is ok
1633+ if ( ypos == null ) {
1634+ return true ;
1635+ }
1636+
16271637 var positionKeys = Object . keys ( MdPanelPosition . yPosition ) ;
16281638 var positionValues = [ ] ;
16291639 for ( var key , i = 0 ; key = positionKeys [ i ] ; i ++ ) {
16301640 var position = MdPanelPosition . yPosition [ key ] ;
16311641 positionValues . push ( position ) ;
1632- if ( position === yPosition ) {
1633- this . _yPosition = yPosition ;
1634- return this ;
1642+
1643+ if ( position === ypos ) {
1644+ return ;
16351645 }
16361646 }
16371647
1638- throw new Error ( 'withPanelYPosition only accepts the following values:\n' +
1648+ throw new Error ( 'Panel y position only accepts the following values:\n' +
1649+ positionValues . join ( ' | ' ) ) ;
1650+ } ;
1651+
1652+
1653+ MdPanelPosition . prototype . _validateXPosition = function ( xpos ) {
1654+ // empty is ok
1655+ if ( xpos == null ) {
1656+ return true ;
1657+ }
1658+
1659+ var positionKeys = Object . keys ( MdPanelPosition . xPosition ) ;
1660+ var positionValues = [ ] ;
1661+ for ( var key , i = 0 ; key = positionKeys [ i ] ; i ++ ) {
1662+ var position = MdPanelPosition . xPosition [ key ] ;
1663+ positionValues . push ( position ) ;
1664+ if ( position === xpos ) {
1665+ return ;
1666+ }
1667+ }
1668+
1669+ throw new Error ( 'Panel x Position only accepts the following values:\n' +
16391670 positionValues . join ( ' | ' ) ) ;
1671+
16401672} ;
16411673
16421674
@@ -1765,7 +1797,10 @@ MdPanelPosition.prototype._calculatePanelPosition = function(panelEl) {
17651797 var targetRight = targetBounds . right ;
17661798 var targetWidth = targetBounds . width ;
17671799
1768- switch ( this . _xPosition ) {
1800+ // TODO(gmoothart): intelligently pick the first on-screen position.
1801+ var pos = this . _positions [ 0 ] || { } ;
1802+
1803+ switch ( pos . x ) {
17691804 case MdPanelPosition . xPosition . OFFSET_START :
17701805 // TODO(ErinCoughlan): Change OFFSET_START for rtl vs ltr.
17711806 this . _left = targetLeft - panelWidth + 'px' ;
@@ -1792,7 +1827,7 @@ MdPanelPosition.prototype._calculatePanelPosition = function(panelEl) {
17921827 var targetBottom = targetBounds . bottom ;
17931828 var targetHeight = targetBounds . height ;
17941829
1795- switch ( this . _yPosition ) {
1830+ switch ( pos . y ) {
17961831 case MdPanelPosition . yPosition . ABOVE :
17971832 this . _top = targetTop - panelHeight + 'px' ;
17981833 break ;
0 commit comments