diff --git a/src/components/button/button.js b/src/components/button/button.js index d196e367fcd..5fe2bbc7fc4 100644 --- a/src/components/button/button.js +++ b/src/components/button/button.js @@ -25,6 +25,7 @@ angular * the `md-primary` class. * * @param {boolean=} md-no-ink If present, disable ripple ink effects. + * @param {boolean=} md-no-focus-style If present, disable focus style on button * @param {expression=} ng-disabled En/Disable based on the expression * @param {string=} md-ripple-size Overrides the default ripple size logic. Options: `full`, `partial`, `auto` * @param {string=} aria-label Adds alternative text to button for accessibility, useful for icon buttons. @@ -108,9 +109,10 @@ function MdButtonDirective($mdButtonInkRipple, $mdTheming, $mdAria, $timeout) { } }); - // restrict focus styles to the keyboard - scope.mouseActive = false; - element.on('mousedown', function() { + if (!angular.isDefined(attr.mdNoFocusStyle)) { + // restrict focus styles to the keyboard + scope.mouseActive = false; + element.on('mousedown', function() { scope.mouseActive = true; $timeout(function(){ scope.mouseActive = false; @@ -124,6 +126,7 @@ function MdButtonDirective($mdButtonInkRipple, $mdTheming, $mdAria, $timeout) { .on('blur', function(ev) { element.removeClass('md-focused'); }); + } } } diff --git a/src/components/list/list.js b/src/components/list/list.js index 3b9c6efc825..3ff398421b9 100644 --- a/src/components/list/list.js +++ b/src/components/list/list.js @@ -136,9 +136,19 @@ function mdListItemDirective($mdAria, $mdConstant, $mdUtil, $timeout) { container.append(tEl.contents()); tEl.addClass('md-proxy-focus'); } else { - container = angular.element('
'); - copyAttributes(tEl[0], container[0]); - container.children().eq(0).append(tEl.contents()); + // Element which holds the default list-item content. + container = angular.element('
'); + + // Button which shows ripple and executes primary action. + var buttonWrap = angular.element(''); + buttonWrap[0].setAttribute('aria-label', tEl[0].textContent); + copyAttributes(tEl[0], buttonWrap[0]); + + // Append the button wrap before our list-item content, because it will overlay in relative. + container.prepend(buttonWrap); + container.children().eq(1).append(tEl.contents()); + + tEl.addClass('md-button-wrap'); } tEl[0].setAttribute('tabindex', '-1'); @@ -179,7 +189,11 @@ function mdListItemDirective($mdAria, $mdConstant, $mdUtil, $timeout) { ( tAttrs.ngClick && isProxiedElement(secondaryItem) ) )) { - secondaryItem.classList.remove('md-secondary'); + // When using multiple secondary items we need to remove their secondary class to be + // orderd correctly in the list-item + if (hasSecondaryItemsWrapper) { + secondaryItem.classList.remove('md-secondary'); + } tEl.addClass('md-with-secondary'); container.append(secondaryItem); } diff --git a/src/components/list/list.scss b/src/components/list/list.scss index e9ccea1de0c..4290f34f117 100644 --- a/src/components/list/list.scss +++ b/src/components/list/list.scss @@ -45,6 +45,33 @@ md-list-item { &.md-proxy-focus.md-focused .md-no-style { transition: background-color 0.15s linear; } + + &.md-button-wrap { + position: relative; + + > .md-button:first-child { + padding: 0; + margin: 0; + font-weight: 400; + background-color: inherit; + text-align: left; + border: medium none; + + > .md-button:first-child { + height: 100%; + position: absolute; + margin: 0; + padding: 0; + } + + .md-list-item-inner { + padding: 0 16px; + } + + } + + } + &.md-no-proxy, .md-no-style { position: relative; diff --git a/src/components/list/list.spec.js b/src/components/list/list.spec.js index 5c68d44d336..1d5066555e7 100644 --- a/src/components/list/list.spec.js +++ b/src/components/list/list.spec.js @@ -104,23 +104,24 @@ describe('mdListItem directive', function() { it('creates buttons when used with ng-click', function() { var listItem = setup('

Hello world

'); - var firstChild = listItem.children()[0]; - expect(firstChild.nodeName).toBe('MD-BUTTON'); - expect(firstChild.hasAttribute('ng-disabled')).toBeTruthy(); - expect(firstChild.childNodes[0].nodeName).toBe('DIV'); - expect(firstChild.childNodes[0].childNodes[0].nodeName).toBe('P'); + var buttonChild = listItem.children().children()[0]; + var innerChild = listItem.children().children()[1]; + expect(buttonChild.nodeName).toBe('MD-BUTTON'); + expect(buttonChild.hasAttribute('ng-disabled')).toBeTruthy(); + expect(innerChild.nodeName).toBe('DIV'); + expect(innerChild.childNodes[0].nodeName).toBe('P'); }); it('creates buttons when used with ui-sref', function() { var listItem = setup('

Hello world

'); - var firstChild = listItem.children()[0]; + var firstChild = listItem.children().children()[0]; expect(firstChild.nodeName).toBe('MD-BUTTON'); expect(firstChild.hasAttribute('ui-sref')).toBeTruthy(); }); it('creates buttons when used with href', function() { var listItem = setup('

Hello world

'); - var firstChild = listItem.children()[0]; + var firstChild = listItem.children().children()[0]; expect(firstChild.nodeName).toBe('MD-BUTTON'); expect(firstChild.hasAttribute('href')).toBeTruthy(); }); @@ -128,15 +129,18 @@ describe('mdListItem directive', function() { it('moves aria-label to primary action', function() { var listItem = setup(''); var listItemChildren = listItem.children(); - expect(listItemChildren[0].nodeName).toBe('MD-BUTTON'); - expect(listItemChildren.attr('aria-label')).toBe('Hello'); + expect(listItemChildren[0].nodeName).toBe('DIV'); + expect(listItemChildren).toHaveClass('md-button'); + expect(listItemChildren.children()[0].getAttribute('aria-label')).toBe('Hello'); }); it('moves md-secondary items outside of the button', function() { var listItem = setup('

Hello World

'); + // First child is our button and content holder var firstChild = listItem.children().eq(0); - expect(firstChild[0].nodeName).toBe('MD-BUTTON'); - expect(firstChild.children().length).toBe(1); + expect(firstChild[0].nodeName).toBe('DIV'); + // It should contain two elements, the button overlay and the actual content + expect(firstChild.children().length).toBe(2); var secondChild = listItem.children().eq(1); expect(secondChild[0].nodeName).toBe('MD-BUTTON'); expect(secondChild.hasClass('md-secondary-container')).toBeTruthy(); @@ -144,9 +148,11 @@ describe('mdListItem directive', function() { it('moves multiple md-secondary items outside of the button', function() { var listItem = setup('

Hello World

'); + // First child is our button and content holder var firstChild = listItem.children().eq(0); - expect(firstChild[0].nodeName).toBe('MD-BUTTON'); - expect(firstChild.children().length).toBe(1); + expect(firstChild[0].nodeName).toBe('DIV'); + // It should contain two elements, the button overlay and the actual content + expect(firstChild.children().length).toBe(2); var secondChild = listItem.children().eq(1); expect(secondChild[0].nodeName).toBe('DIV'); expect(secondChild.hasClass('md-secondary-container')).toBeTruthy();