diff --git a/src/components/list/list.js b/src/components/list/list.js
index e627f6a9d42..3e22481d0c1 100644
--- a/src/components/list/list.js
+++ b/src/components/list/list.js
@@ -83,7 +83,7 @@ function mdListDirective($mdTheming) {
* that is inside the list, but does not wrap the contents._
*/
function mdListItemDirective($mdAria, $mdConstant, $mdUtil, $timeout) {
- var proxiedTypes = ['md-checkbox', 'md-switch'];
+ var proxiedTypes = ['md-checkbox', 'md-switch', 'md-menu'];
return {
restrict: 'E',
controller: 'MdListController',
@@ -112,9 +112,13 @@ function mdListItemDirective($mdAria, $mdConstant, $mdUtil, $timeout) {
tEl.addClass('_md-no-proxy');
}
}
+
wrapSecondaryItems();
setupToggleAria();
+ if (hasProxiedElement && proxyElement.nodeName === "MD-MENU") {
+ setupProxiedMenu();
+ }
function setupToggleAria() {
var toggleTypes = ['md-switch', 'md-checkbox'];
@@ -131,6 +135,35 @@ function mdListItemDirective($mdAria, $mdConstant, $mdUtil, $timeout) {
}
}
+ function setupProxiedMenu() {
+ var menuEl = angular.element(proxyElement);
+
+ var isEndAligned = menuEl.parent().hasClass('_md-secondary-container') ||
+ proxyElement.parentNode.firstElementChild !== proxyElement;
+
+ var xAxisPosition = 'left';
+
+ if (isEndAligned) {
+ // When the proxy item is aligned at the end of the list, we have to set the origin to the end.
+ xAxisPosition = 'right';
+ }
+
+ // Set the position mode / origin of the proxied menu.
+ if (!menuEl.attr('md-position-mode')) {
+ menuEl.attr('md-position-mode', xAxisPosition + ' target');
+ }
+
+ // Apply menu open binding to menu button
+ var menuOpenButton = menuEl.children().eq(0);
+ if (!hasClickEvent(menuOpenButton[0])) {
+ menuOpenButton.attr('ng-click', '$mdOpenMenu($event)');
+ }
+
+ if (!menuOpenButton.attr('aria-label')) {
+ menuOpenButton.attr('aria-label', 'Open List Menu');
+ }
+ }
+
function wrapIn(type) {
if (type == 'div') {
itemContainer = angular.element('');
@@ -277,6 +310,7 @@ function mdListItemDirective($mdAria, $mdConstant, $mdUtil, $timeout) {
}
}
+
function computeClickable() {
if (proxies.length == 1 || hasClick) {
$element.addClass('md-clickable');
@@ -313,6 +347,9 @@ function mdListItemDirective($mdAria, $mdConstant, $mdUtil, $timeout) {
if (!parentButton && clickChild.contains(e.target)) {
angular.forEach(proxies, function(proxy) {
if (e.target !== proxy && !proxy.contains(e.target)) {
+ if (proxy.nodeName === 'MD-MENU') {
+ proxy = proxy.children[0];
+ }
angular.element(proxy).triggerHandler('click');
}
});
diff --git a/src/components/list/list.spec.js b/src/components/list/list.spec.js
index 32df25231b9..12337504bf5 100644
--- a/src/components/list/list.spec.js
+++ b/src/components/list/list.spec.js
@@ -301,6 +301,61 @@ describe('mdListItem directive', function() {
expect(button[0].hasAttribute('ng-disabled')).toBeTruthy();
});
+ describe('with a md-menu', function() {
+ it('should forward click events on the md-menu trigger button', function() {
+ var template =
+ '' +
+ '' +
+ '' +
+ '' +
+ '';
+
+ var listItem = setup(template);
+ var cntr = listItem[0].querySelector('div');
+ var openMenu = jasmine.createSpy('openMenu');
+
+ $rootScope.openMenu = openMenu;
+
+ if (cntr && cntr.click) {
+ cntr.click();
+ expect(openMenu).toHaveBeenCalled();
+ }
+
+ });
+
+ it('should detect the menu position mode when md-menu is aligned at right', function() {
+ var template =
+ '' +
+ 'Menu should be aligned right' +
+ '' +
+ '' +
+ '' +
+ '';
+
+ var listItem = setup(template);
+
+ var mdMenu = listItem.find('md-menu');
+
+ expect(mdMenu.attr('md-position-mode')).toBe('right target');
+ });
+
+ it('should detect the menu position mode when md-menu is aligned at left', function() {
+ var template =
+ '' +
+ '' +
+ '' +
+ '' +
+ 'Menu should be aligned left' +
+ '';
+
+ var listItem = setup(template);
+
+ var mdMenu = listItem.find('md-menu');
+
+ expect(mdMenu.attr('md-position-mode')).toBe('left target');
+ });
+ });
+
describe('with a clickable item', function() {
it('should wrap secondary icons in a md-button', function() {
diff --git a/src/components/menu/js/menuServiceProvider.js b/src/components/menu/js/menuServiceProvider.js
index 73fbf2aecbd..97258e6539f 100644
--- a/src/components/menu/js/menuServiceProvider.js
+++ b/src/components/menu/js/menuServiceProvider.js
@@ -461,8 +461,17 @@ function MenuProvider($$interimElementProvider) {
position.left = willFitRight ? originNodeRect.right - originNode.style.left : originNodeRect.left - originNode.style.left - openMenuNodeRect.width;
transformOrigin += willFitRight ? 'left' : 'right';
break;
+ case 'right':
+ if (rtl) {
+ position.left = originNodeRect.right - originNodeRect.width;
+ transformOrigin += 'left';
+ } else {
+ position.left = originNodeRect.right - openMenuNodeRect.width;
+ transformOrigin += 'right';
+ }
+ break;
case 'left':
- if(rtl) {
+ if (rtl) {
position.left = originNodeRect.right - openMenuNodeRect.width;
transformOrigin += 'right';
} else {