Skip to content

Commit 2cfed42

Browse files
author
Vivian Hu
committed
feat(list): add new '<mat-action-list>'
An action-list is a list where each list item is a native '<button>' element, meant to be used in cases where each list item has a single action with no sub-action, navigation or selection.
1 parent a71ce7a commit 2cfed42

File tree

3 files changed

+42
-5
lines changed

3 files changed

+42
-5
lines changed

src/lib/list/list.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,15 @@ element in an `<mat-list-item>`.
4444

4545
### Action lists
4646

47-
Use `mat-action-list` tags for action lists (i.e. lists that have button tags).
47+
Use the `<mat-action-list>` element when each item in the list performs some _action_. Each item
48+
in an action list is a `<button>` element.
4849

4950
Simple action lists can use the `mat-list-item` attribute on button tag elements directly:
5051

5152
```html
5253
<mat-action-list>
53-
<button mat-list-item *ngFor="let link of links"> {{link.name}} </button>
54+
<button mat-list-item (click)="save()"> Save </button>
55+
<button mat-list-item (click)="undo()"> Undo </button>
5456
</mat-action-list>
5557
```
5658

src/lib/list/list.spec.ts

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ describe('MatList', () => {
2020
ListWithMultipleItems,
2121
ListWithManyLines,
2222
NavListWithOneAnchorItem,
23-
ActionListWithOneItem
23+
ActionListWithoutType,
24+
ActionListWithType
2425
],
2526
});
2627

@@ -146,13 +147,29 @@ describe('MatList', () => {
146147
});
147148

148149
it('should create an action list', () => {
149-
let fixture = TestBed.createComponent(ActionListWithOneItem);
150+
const fixture = TestBed.createComponent(ActionListWithoutType);
150151
fixture.detectChanges();
151152

152153
const items = fixture.componentInstance.listItems;
153154
expect(items.length).toBeGreaterThan(0);
154155
});
155156

157+
it('should set default type attribute to button for action list', () => {
158+
const fixture = TestBed.createComponent(ActionListWithoutType);
159+
fixture.detectChanges();
160+
161+
const listItemEl = fixture.debugElement.query(By.css('.mat-list-item'));
162+
expect(listItemEl.nativeElement.getAttribute('type')).toBe('button');
163+
});
164+
165+
it('should not change type attribute if it is already specified', () => {
166+
const fixture = TestBed.createComponent(ActionListWithType);
167+
fixture.detectChanges();
168+
169+
const listItemEl = fixture.debugElement.query(By.css('.mat-list-item'));
170+
expect(listItemEl.nativeElement.getAttribute('type')).toBe('submit');
171+
});
172+
156173
it('should allow disabling ripples for the whole nav-list', () => {
157174
let fixture = TestBed.createComponent(NavListWithOneAnchorItem);
158175
fixture.detectChanges();
@@ -210,7 +227,17 @@ class NavListWithOneAnchorItem extends BaseTestList {
210227
Paprika
211228
</button>
212229
</mat-action-list>`})
213-
class ActionListWithOneItem extends BaseTestList {
230+
class ActionListWithoutType extends BaseTestList {
231+
@ViewChildren(MatListItem) listItems: QueryList<MatListItem>;
232+
}
233+
234+
@Component({template: `
235+
<mat-action-list>
236+
<button mat-list-item type="submit">
237+
Paprika
238+
</button>
239+
</mat-action-list>`})
240+
class ActionListWithType extends BaseTestList {
214241
@ViewChildren(MatListItem) listItems: QueryList<MatListItem>;
215242
}
216243

src/lib/list/list.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,14 @@ export class MatListItem extends _MatListItemMixinBase implements AfterContentIn
119119
@Optional() private _navList: MatNavList) {
120120
super();
121121
this._isNavList = !!_navList;
122+
123+
// If no type attributed is specified for <button>, set it to "button".
124+
// If a type attribute is already specified, do nothing.
125+
const element = this._getHostElement();
126+
if (element.nodeName && element.nodeName.toLowerCase() === 'button'
127+
&& !element.hasAttribute('type')) {
128+
element.setAttribute('type', 'button');
129+
}
122130
}
123131

124132
ngAfterContentInit() {

0 commit comments

Comments
 (0)