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

Commit d127991

Browse files
EladBezalelThomasBurleson
authored andcommitted
feat(panel): add RTL support
- If the application is in RTL mode we swap the `OFFSET` and `ALIGN` - `START` and `END` positions, it tricks the function to switch it origin point and calculate the panel position right. - Added `start` and `end` APIs to support bidi fixes #8974 Closes #8990
1 parent 11ff76b commit d127991

File tree

2 files changed

+251
-31
lines changed

2 files changed

+251
-31
lines changed

src/components/panel/panel.js

Lines changed: 133 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -386,8 +386,8 @@ angular
386386
* @ngdoc method
387387
* @name MdPanelPosition#top
388388
* @description
389-
* Sets the value of `top` for the panel. Clears any previously set
390-
* vertical position.
389+
* Sets the value of `top` for the panel. Clears any previously set vertical
390+
* position.
391391
* @param {string=} top Value of `top`. Defaults to '0'.
392392
* @returns {MdPanelPosition}
393393
*/
@@ -396,12 +396,32 @@ angular
396396
* @ngdoc method
397397
* @name MdPanelPosition#bottom
398398
* @description
399-
* Sets the value of `bottom` for the panel. Clears any previously set
400-
* vertical position.
399+
* Sets the value of `bottom` for the panel. Clears any previously set vertical
400+
* position.
401401
* @param {string=} bottom Value of `bottom`. Defaults to '0'.
402402
* @returns {MdPanelPosition}
403403
*/
404404

405+
/**
406+
* @ngdoc method
407+
* @name MdPanelPosition#start
408+
* @description
409+
* Sets the panel to the start of the page - `left` if `ltr` or `right` for `rtl`. Clears any previously set
410+
* horizontal position.
411+
* @param {string=} start Value of position. Defaults to '0'.
412+
* @returns {MdPanelPosition}
413+
*/
414+
415+
/**
416+
* @ngdoc method
417+
* @name MdPanelPosition#end
418+
* @description
419+
* Sets the panel to the end of the page - `right` if `ltr` or `left` for `rtl`. Clears any previously set
420+
* horizontal position.
421+
* @param {string=} end Value of position. Defaults to '0'.
422+
* @returns {MdPanelPosition}
423+
*/
424+
405425
/**
406426
* @ngdoc method
407427
* @name MdPanelPosition#left
@@ -713,7 +733,7 @@ MdPanelService.prototype.open = function(config) {
713733
* @returns {MdPanelPosition}
714734
*/
715735
MdPanelService.prototype.newPanelPosition = function() {
716-
return new MdPanelPosition(this._$window);
736+
return new MdPanelPosition(this._$injector);
717737
};
718738

719739

@@ -1243,10 +1263,10 @@ MdPanelRef.prototype._updatePosition = function(init) {
12431263
this._panelContainer.addClass(MD_PANEL_HIDDEN);
12441264
}
12451265

1246-
this._panelEl.css('top', positionConfig.getTop());
1247-
this._panelEl.css('bottom', positionConfig.getBottom());
1248-
this._panelEl.css('left', positionConfig.getLeft());
1249-
this._panelEl.css('right', positionConfig.getRight());
1266+
this._panelEl.css(MdPanelPosition.absPosition.TOP, positionConfig.getTop());
1267+
this._panelEl.css(MdPanelPosition.absPosition.BOTTOM, positionConfig.getBottom());
1268+
this._panelEl.css(MdPanelPosition.absPosition.LEFT, positionConfig.getLeft());
1269+
this._panelEl.css(MdPanelPosition.absPosition.RIGHT, positionConfig.getRight());
12501270

12511271
// Use the vendor prefixed version of transform.
12521272
var prefixedTransform = this._$mdConstant.CSS.TRANSFORM;
@@ -1570,12 +1590,15 @@ MdPanelRef.prototype._done = function(callback, self) {
15701590
* position: panelPosition
15711591
* });
15721592
*
1573-
* @param {!angular.$window} $window
1593+
* @param {!angular.$injector} $injector
15741594
* @final @constructor
15751595
*/
1576-
function MdPanelPosition($window) {
1577-
/** @private @const */
1578-
this._$window = $window;
1596+
function MdPanelPosition($injector) {
1597+
/** @private @const {!angular.$window} */
1598+
this._$window = $injector.get('$window');
1599+
1600+
/** @private {boolean} */
1601+
this._isRTL = $injector.get('$mdUtil').bidi() === 'rtl';
15791602

15801603
/** @private {boolean} */
15811604
this._absolute = false;
@@ -1635,6 +1658,18 @@ MdPanelPosition.yPosition = {
16351658
};
16361659

16371660

1661+
/**
1662+
* Possible values of absolute position.
1663+
* @enum {string}
1664+
*/
1665+
MdPanelPosition.absPosition = {
1666+
TOP: 'top',
1667+
RIGHT: 'right',
1668+
BOTTOM: 'bottom',
1669+
LEFT: 'left'
1670+
};
1671+
1672+
16381673
/**
16391674
* Sets absolute positioning for the panel.
16401675
* @return {!MdPanelPosition}
@@ -1644,6 +1679,31 @@ MdPanelPosition.prototype.absolute = function() {
16441679
return this;
16451680
};
16461681

1682+
/**
1683+
* Sets the value of a position for the panel. Clears any previously set position.
1684+
* @param {string} position Position to set
1685+
* @param {string=} value Value of the position. Defaults to '0'.
1686+
* @returns {MdPanelPosition}
1687+
* @private
1688+
*/
1689+
MdPanelPosition.prototype._setPosition = function(position, value) {
1690+
if (position === MdPanelPosition.absPosition.RIGHT || position === MdPanelPosition.absPosition.LEFT) {
1691+
this._left = this._right = '';
1692+
}
1693+
else if (position === MdPanelPosition.absPosition.BOTTOM || position === MdPanelPosition.absPosition.TOP) {
1694+
this._top = this._bottom = '';
1695+
}
1696+
else {
1697+
var positions = Object.keys(MdPanelPosition.absPosition).join().toLowerCase();
1698+
1699+
throw new Error('Position must be one of ' + positions + '.');
1700+
}
1701+
1702+
this['_' + position] = angular.isString(value) ? value : '0';
1703+
1704+
return this;
1705+
};
1706+
16471707

16481708
/**
16491709
* Sets the value of `top` for the panel. Clears any previously set vertical
@@ -1652,9 +1712,7 @@ MdPanelPosition.prototype.absolute = function() {
16521712
* @returns {MdPanelPosition}
16531713
*/
16541714
MdPanelPosition.prototype.top = function(top) {
1655-
this._bottom = '';
1656-
this._top = top || '0';
1657-
return this;
1715+
return this._setPosition(MdPanelPosition.absPosition.TOP, top);
16581716
};
16591717

16601718

@@ -1665,9 +1723,31 @@ MdPanelPosition.prototype.top = function(top) {
16651723
* @returns {MdPanelPosition}
16661724
*/
16671725
MdPanelPosition.prototype.bottom = function(bottom) {
1668-
this._top = '';
1669-
this._bottom = bottom || '0';
1670-
return this;
1726+
return this._setPosition(MdPanelPosition.absPosition.BOTTOM, bottom);
1727+
};
1728+
1729+
1730+
/**
1731+
* Sets the panel to the start of the page - `left` if `ltr` or `right` for `rtl`. Clears any previously set
1732+
* horizontal position.
1733+
* @param {string=} start Value of position. Defaults to '0'.
1734+
* @returns {MdPanelPosition}
1735+
*/
1736+
MdPanelPosition.prototype.start = function(start) {
1737+
var position = this._isRTL ? MdPanelPosition.absPosition.RIGHT : MdPanelPosition.absPosition.LEFT;
1738+
return this._setPosition(position, start);
1739+
};
1740+
1741+
1742+
/**
1743+
* Sets the panel to the end of the page - `right` if `ltr` or `left` for `rtl`. Clears any previously set
1744+
* horizontal position.
1745+
* @param {string=} end Value of position. Defaults to '0'.
1746+
* @returns {MdPanelPosition}
1747+
*/
1748+
MdPanelPosition.prototype.end = function(end) {
1749+
var position = this._isRTL ? MdPanelPosition.absPosition.LEFT : MdPanelPosition.absPosition.RIGHT;
1750+
return this._setPosition(position, end);
16711751
};
16721752

16731753

@@ -1678,9 +1758,7 @@ MdPanelPosition.prototype.bottom = function(bottom) {
16781758
* @returns {MdPanelPosition}
16791759
*/
16801760
MdPanelPosition.prototype.left = function(left) {
1681-
this._right = '';
1682-
this._left = left || '0';
1683-
return this;
1761+
return this._setPosition(MdPanelPosition.absPosition.LEFT, left);
16841762
};
16851763

16861764

@@ -1689,11 +1767,9 @@ MdPanelPosition.prototype.left = function(left) {
16891767
* horizontal position.
16901768
* @param {string=} right Value of `right`. Defaults to '0'.
16911769
* @returns {MdPanelPosition}
1692-
*/
1770+
*/
16931771
MdPanelPosition.prototype.right = function(right) {
1694-
this._left = '';
1695-
this._right = right || '0';
1696-
return this;
1772+
return this._setPosition(MdPanelPosition.absPosition.RIGHT, right);
16971773
};
16981774

16991775

@@ -1971,6 +2047,36 @@ MdPanelPosition.prototype._setPanelPosition = function(panelEl) {
19712047
}
19722048
};
19732049

2050+
2051+
/**
2052+
* Switching between 'start' and 'end'
2053+
* @param {string} position Horizontal position of the panel
2054+
* @returns {string} Reversed position
2055+
* @private
2056+
*/
2057+
MdPanelPosition.prototype._reverseXPosition = function(position) {
2058+
if (position === MdPanelPosition.xPosition.CENTER) {
2059+
return;
2060+
}
2061+
2062+
var start = 'start';
2063+
var end = 'end';
2064+
2065+
return position.indexOf(start) > -1 ? position.replace(start, end) : position.replace(end, start);
2066+
};
2067+
2068+
2069+
/**
2070+
* Handles horizontal positioning in rtl or ltr environments
2071+
* @param {string} position Horizontal position of the panel
2072+
* @returns {string} The correct position according the page direction
2073+
* @private
2074+
*/
2075+
MdPanelPosition.prototype._bidi = function(position) {
2076+
return this._isRTL ? this._reverseXPosition(position) : position;
2077+
};
2078+
2079+
19742080
/**
19752081
* Calculates the panel position based on the created panel element and the
19762082
* provided positioning.
@@ -1990,25 +2096,21 @@ MdPanelPosition.prototype._calculatePanelPosition = function(panelEl, position)
19902096
var targetRight = targetBounds.right;
19912097
var targetWidth = targetBounds.width;
19922098

1993-
switch (position.x) {
2099+
switch (this._bidi(position.x)) {
19942100
case MdPanelPosition.xPosition.OFFSET_START:
1995-
// TODO(ErinCoughlan): Change OFFSET_START for rtl vs ltr.
19962101
this._left = targetLeft - panelWidth + 'px';
19972102
break;
19982103
case MdPanelPosition.xPosition.ALIGN_END:
1999-
// TODO(ErinCoughlan): Change ALIGN_END for rtl vs ltr.
20002104
this._left = targetRight - panelWidth + 'px';
20012105
break;
20022106
case MdPanelPosition.xPosition.CENTER:
20032107
var left = targetLeft + (0.5 * targetWidth) - (0.5 * panelWidth);
20042108
this._left = left + 'px';
20052109
break;
20062110
case MdPanelPosition.xPosition.ALIGN_START:
2007-
// TODO(ErinCoughlan): Change ALIGN_START for rtl vs ltr.
20082111
this._left = targetLeft + 'px';
20092112
break;
20102113
case MdPanelPosition.xPosition.OFFSET_END:
2011-
// TODO(ErinCoughlan): Change OFFSET_END for rtl vs ltr.
20122114
this._left = targetRight + 'px';
20132115
break;
20142116
}

0 commit comments

Comments
 (0)