mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
feat(list): add new '<mat-action-list>' (#12415)
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.
This commit is contained in:
committed by
Jeremy Elbourn
parent
8ee5fb66c6
commit
69fa76236a
@@ -104,6 +104,15 @@
|
||||
</mat-nav-list>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2>Action list</h2>
|
||||
<mat-action-list>
|
||||
<button mat-list-item *ngFor="let link of links" (click)="alertItem(link.name)">
|
||||
{{link.name}}
|
||||
</button>
|
||||
</mat-action-list>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2>Selection list</h2>
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
border: 1px solid rgba(0, 0, 0, 0.12);
|
||||
width: 350px;
|
||||
margin: 20px 20px 0 0;
|
||||
|
||||
}
|
||||
h2 {
|
||||
margin-top: 20px;
|
||||
|
||||
@@ -69,4 +69,8 @@ export class ListDemo {
|
||||
this.selectedOptions = values;
|
||||
this.modelChangeEventCount++;
|
||||
}
|
||||
|
||||
alertItem(msg: string) {
|
||||
alert(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,20 @@ element in an `<mat-list-item>`.
|
||||
</mat-nav-list>
|
||||
```
|
||||
|
||||
### Action lists
|
||||
|
||||
Use the `<mat-action-list>` element when each item in the list performs some _action_. Each item
|
||||
in an action list is a `<button>` element.
|
||||
|
||||
Simple action lists can use the `mat-list-item` attribute on button tag elements directly:
|
||||
|
||||
```html
|
||||
<mat-action-list>
|
||||
<button mat-list-item (click)="save()"> Save </button>
|
||||
<button mat-list-item (click)="undo()"> Undo </button>
|
||||
</mat-action-list>
|
||||
```
|
||||
|
||||
### Selection lists
|
||||
A selection list provides an interface for selecting values, where each list item is an option.
|
||||
|
||||
|
||||
@@ -268,6 +268,22 @@ $mat-list-item-inset-divider-offset: 72px;
|
||||
}
|
||||
}
|
||||
|
||||
mat-action-list {
|
||||
//remove the native button look and make it look like a list item
|
||||
button {
|
||||
background: none;
|
||||
color: inherit;
|
||||
border: none;
|
||||
font: inherit;
|
||||
outline: inherit;
|
||||
}
|
||||
|
||||
.mat-list-item {
|
||||
cursor: pointer;
|
||||
outline: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.mat-list-option:not(.mat-list-item-disabled) {
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
|
||||
@@ -20,6 +20,8 @@ describe('MatList', () => {
|
||||
ListWithMultipleItems,
|
||||
ListWithManyLines,
|
||||
NavListWithOneAnchorItem,
|
||||
ActionListWithoutType,
|
||||
ActionListWithType
|
||||
],
|
||||
});
|
||||
|
||||
@@ -144,6 +146,30 @@ describe('MatList', () => {
|
||||
items.forEach(item => expect(item._isRippleDisabled()).toBe(true));
|
||||
});
|
||||
|
||||
it('should create an action list', () => {
|
||||
const fixture = TestBed.createComponent(ActionListWithoutType);
|
||||
fixture.detectChanges();
|
||||
|
||||
const items = fixture.componentInstance.listItems;
|
||||
expect(items.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('should set default type attribute to button for action list', () => {
|
||||
const fixture = TestBed.createComponent(ActionListWithoutType);
|
||||
fixture.detectChanges();
|
||||
|
||||
const listItemEl = fixture.debugElement.query(By.css('.mat-list-item'));
|
||||
expect(listItemEl.nativeElement.getAttribute('type')).toBe('button');
|
||||
});
|
||||
|
||||
it('should not change type attribute if it is already specified', () => {
|
||||
const fixture = TestBed.createComponent(ActionListWithType);
|
||||
fixture.detectChanges();
|
||||
|
||||
const listItemEl = fixture.debugElement.query(By.css('.mat-list-item'));
|
||||
expect(listItemEl.nativeElement.getAttribute('type')).toBe('submit');
|
||||
});
|
||||
|
||||
it('should allow disabling ripples for the whole nav-list', () => {
|
||||
let fixture = TestBed.createComponent(NavListWithOneAnchorItem);
|
||||
fixture.detectChanges();
|
||||
@@ -195,6 +221,26 @@ class NavListWithOneAnchorItem extends BaseTestList {
|
||||
disableListRipple: boolean = false;
|
||||
}
|
||||
|
||||
@Component({template: `
|
||||
<mat-action-list>
|
||||
<button mat-list-item>
|
||||
Paprika
|
||||
</button>
|
||||
</mat-action-list>`})
|
||||
class ActionListWithoutType extends BaseTestList {
|
||||
@ViewChildren(MatListItem) listItems: QueryList<MatListItem>;
|
||||
}
|
||||
|
||||
@Component({template: `
|
||||
<mat-action-list>
|
||||
<button mat-list-item type="submit">
|
||||
Paprika
|
||||
</button>
|
||||
</mat-action-list>`})
|
||||
class ActionListWithType extends BaseTestList {
|
||||
@ViewChildren(MatListItem) listItems: QueryList<MatListItem>;
|
||||
}
|
||||
|
||||
@Component({template: `
|
||||
<mat-list>
|
||||
<mat-list-item>
|
||||
|
||||
+10
-2
@@ -56,7 +56,7 @@ export class MatNavList extends _MatListMixinBase implements CanDisableRipple {}
|
||||
|
||||
@Component({
|
||||
moduleId: module.id,
|
||||
selector: 'mat-list',
|
||||
selector: 'mat-list, mat-action-list',
|
||||
exportAs: 'matList',
|
||||
templateUrl: 'list.html',
|
||||
host: {'class': 'mat-list'},
|
||||
@@ -100,7 +100,7 @@ export class MatListSubheaderCssMatStyler {}
|
||||
/** An item within a Material Design list. */
|
||||
@Component({
|
||||
moduleId: module.id,
|
||||
selector: 'mat-list-item, a[mat-list-item]',
|
||||
selector: 'mat-list-item, a[mat-list-item], button[mat-list-item]',
|
||||
exportAs: 'matListItem',
|
||||
host: {
|
||||
'class': 'mat-list-item',
|
||||
@@ -127,6 +127,14 @@ export class MatListItem extends _MatListItemMixinBase implements AfterContentIn
|
||||
@Optional() private _navList: MatNavList) {
|
||||
super();
|
||||
this._isNavList = !!_navList;
|
||||
|
||||
// If no type attributed is specified for <button>, set it to "button".
|
||||
// If a type attribute is already specified, do nothing.
|
||||
const element = this._getHostElement();
|
||||
if (element.nodeName && element.nodeName.toLowerCase() === 'button'
|
||||
&& !element.hasAttribute('type')) {
|
||||
element.setAttribute('type', 'button');
|
||||
}
|
||||
}
|
||||
|
||||
ngAfterContentInit() {
|
||||
|
||||
Reference in New Issue
Block a user