Skip to content

Commit

Permalink
feat(list): option to disable ripples for all items (#4159)
Browse files Browse the repository at this point in the history
Fixes #4149.
  • Loading branch information
devversion authored and kara committed Apr 21, 2017
1 parent b846a27 commit 7f0f473
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 41 deletions.
3 changes: 0 additions & 3 deletions src/lib/list/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
MdNavListCssMatStyler,
MdDividerCssMatStyler,
MdListSubheaderCssMatStyler,
MdNavListTokenSetter,
} from './list';


Expand All @@ -28,7 +27,6 @@ import {
MdNavListCssMatStyler,
MdDividerCssMatStyler,
MdListSubheaderCssMatStyler,
MdNavListTokenSetter,
],
declarations: [
MdList,
Expand All @@ -40,7 +38,6 @@ import {
MdNavListCssMatStyler,
MdDividerCssMatStyler,
MdListSubheaderCssMatStyler,
MdNavListTokenSetter,
],
})
export class MdListModule {
Expand Down
31 changes: 25 additions & 6 deletions src/lib/list/list.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,17 +125,35 @@ describe('MdList', () => {
items.forEach(item => expect(item.isRippleEnabled()).toBe(false));
});

it('should maybe show ripples for nav lists', () => {
it('should allow disabling ripples for specific nav-list items', () => {
let fixture = TestBed.createComponent(NavListWithOneAnchorItem);
fixture.detectChanges();

const items: QueryList<MdListItem> = fixture.debugElement.componentInstance.listItems;
const items = fixture.componentInstance.listItems;
expect(items.length).toBeGreaterThan(0);

// Ripples should be enabled by default, and can be disabled with a binding.
items.forEach(item => expect(item.isRippleEnabled()).toBe(true));

fixture.componentInstance.disableItemRipple = true;
fixture.detectChanges();

items.forEach(item => expect(item.isRippleEnabled()).toBe(false));
});

it('should allow disabling ripples for the whole nav-list', () => {
let fixture = TestBed.createComponent(NavListWithOneAnchorItem);
fixture.detectChanges();

const items = fixture.componentInstance.listItems;
expect(items.length).toBeGreaterThan(0);

// Ripples should be enabled by default, and can be disabled with a binding.
items.forEach(item => expect(item.isRippleEnabled()).toBe(true));

fixture.debugElement.componentInstance.disableRipple = true;
fixture.componentInstance.disableListRipple = true;
fixture.detectChanges();

items.forEach(item => expect(item.isRippleEnabled()).toBe(false));
});
});
Expand Down Expand Up @@ -163,14 +181,15 @@ class ListWithOneAnchorItem extends BaseTestList {
}

@Component({template: `
<md-nav-list>
<a md-list-item [disableRipple]="disableRipple">
<md-nav-list [disableRipple]="disableListRipple">
<a md-list-item [disableRipple]="disableItemRipple">
Paprika
</a>
</md-nav-list>`})
class NavListWithOneAnchorItem extends BaseTestList {
@ViewChildren(MdListItem) listItems: QueryList<MdListItem>;
disableRipple: boolean = false;
disableItemRipple: boolean = false;
disableListRipple: boolean = false;
}

@Component({template: `
Expand Down
62 changes: 30 additions & 32 deletions src/lib/list/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,38 @@ import {
QueryList,
Directive,
ElementRef,
Inject,
Input,
OpaqueToken,
Optional,
Renderer,
AfterContentInit,
} from '@angular/core';
import {MdLine, MdLineSetter} from '../core';
import {MdLine, MdLineSetter, coerceBooleanProperty} from '../core';

@Directive({
selector: 'md-divider, mat-divider'
})
export class MdListDivider {}

/**
* Token used to inject the list type into child MdListItem components so they can know whether
* they're in a nav list (and thus should use an MdRipple).
*/
export const LIST_TYPE_TOKEN = new OpaqueToken('list_type');

const NORMAL_LIST_TYPE = 'normal_list_type';
const NAV_LIST_TYPE = 'nav_list_type';

@Component({
moduleId: module.id,
selector: 'md-list, mat-list, md-nav-list, mat-nav-list',
host: {
'role': 'list'},
template: '<ng-content></ng-content>',
styleUrls: ['list.css'],
providers: [{ provide: LIST_TYPE_TOKEN, useValue: NORMAL_LIST_TYPE }],
encapsulation: ViewEncapsulation.None
})
export class MdList {}
export class MdList {
private _disableRipple: boolean = false;

/**
* Whether the ripple effect should be disabled on the list-items or not.
* This flag only has an effect for `md-nav-list` components.
*/
@Input()
get disableRipple() { return this._disableRipple; }
set disableRipple(value: boolean) { this._disableRipple = coerceBooleanProperty(value); }
}

/**
* Directive whose purpose is to add the mat- CSS styling to this selector.
Expand All @@ -65,15 +63,6 @@ export class MdListCssMatStyler {}
})
export class MdNavListCssMatStyler {}

/**
* Directive to set the ListType token to NAV_LIST_TYPE.
*/
@Directive({
selector: 'md-nav-list, mat-nav-list',
providers: [{ provide: LIST_TYPE_TOKEN, useValue: NAV_LIST_TYPE }],
})
export class MdNavListTokenSetter {}

/**
* Directive whose purpose is to add the mat- CSS styling to this selector.
* @docs-private
Expand Down Expand Up @@ -135,14 +124,19 @@ export class MdListSubheaderCssMatStyler {}
encapsulation: ViewEncapsulation.None
})
export class MdListItem implements AfterContentInit {
/**
* Whether the ripple effect on click should be disabled. This applies only to list items that
* are children of an md-nav-list; md-list items never have ripples.
*/
@Input() disableRipple: boolean = false;
private _lineSetter: MdLineSetter;
private _disableRipple: boolean = false;
private _isNavList: boolean = false;

_hasFocus: boolean = false;

private _lineSetter: MdLineSetter;
/**
* Whether the ripple effect on click should be disabled. This applies only to list items that are
* part of a nav list. The value of `disableRipple` on the `md-nav-list` overrides this flag.
*/
@Input()
get disableRipple() { return this._disableRipple; }
set disableRipple(value: boolean) { this._disableRipple = coerceBooleanProperty(value); }

@ContentChildren(MdLine) _lines: QueryList<MdLine>;

Expand All @@ -152,16 +146,20 @@ export class MdListItem implements AfterContentInit {
this._element.nativeElement, 'mat-list-item-avatar', avatar != null);
}

constructor(private _renderer: Renderer, private _element: ElementRef,
@Optional() @Inject(LIST_TYPE_TOKEN) private _listType: string) {}
constructor(private _renderer: Renderer,
private _element: ElementRef,
@Optional() private _list: MdList,
@Optional() navList: MdNavListCssMatStyler) {
this._isNavList = !!navList;
}

ngAfterContentInit() {
this._lineSetter = new MdLineSetter(this._lines, this._renderer, this._element);
}

/** Whether this list item should show a ripple effect when clicked. */
isRippleEnabled() {
return !this.disableRipple && (this._listType === NAV_LIST_TYPE);
return !this.disableRipple && this._isNavList && !this._list.disableRipple;
}

_handleFocus() {
Expand Down

0 comments on commit 7f0f473

Please sign in to comment.