From 8c29bc69b8542f7052b252bee2ba635e025e74e6 Mon Sep 17 00:00:00 2001 From: crisbeto Date: Sun, 10 Sep 2017 19:06:46 +0200 Subject: [PATCH] feat(selection-list): add selectAll and deselectAll functions * Adds the ability to select and deselect all options at once. * Adds a demo of the selection list to the demo app. * Fixes an issue that caused the checkbox inside the selection list to collapse. * Sets the proper cursor on the list items. Fixes #6969. --- src/demo-app/list/list-demo.html | 18 +++++++++++++++ src/demo-app/list/list-demo.scss | 2 +- .../pseudo-checkbox/pseudo-checkbox.scss | 1 + src/lib/list/list.scss | 6 +++++ src/lib/list/selection-list.spec.ts | 23 +++++++++++++++++++ src/lib/list/selection-list.ts | 18 +++++++++++++++ 6 files changed, 67 insertions(+), 1 deletion(-) diff --git a/src/demo-app/list/list-demo.html b/src/demo-app/list/list-demo.html index 5cb977fb51e9..5109f4cd2647 100644 --- a/src/demo-app/list/list-demo.html +++ b/src/demo-app/list/list-demo.html @@ -101,4 +101,22 @@

Nav lists

+ +
+

Selection list

+ + +

Groceries

+ + + {{item}} + +
+ +

Selected: {{groceries.selectedOptions.selected.length}}

+

+ + +

+
diff --git a/src/demo-app/list/list-demo.scss b/src/demo-app/list/list-demo.scss index bcf8a770c381..ed71dbf909d3 100644 --- a/src/demo-app/list/list-demo.scss +++ b/src/demo-app/list/list-demo.scss @@ -3,7 +3,7 @@ display: flex; flex-flow: row wrap; - .mat-list, .mat-nav-list { + .mat-list, .mat-nav-list, .mat-selection-list { border: 1px solid rgba(0, 0, 0, 0.12); width: 350px; margin: 20px 20px 0 0; diff --git a/src/lib/core/selection/pseudo-checkbox/pseudo-checkbox.scss b/src/lib/core/selection/pseudo-checkbox/pseudo-checkbox.scss index 4bf82038dde2..bd7dcc5481c3 100644 --- a/src/lib/core/selection/pseudo-checkbox/pseudo-checkbox.scss +++ b/src/lib/core/selection/pseudo-checkbox/pseudo-checkbox.scss @@ -17,6 +17,7 @@ $_mat-pseudo-checkmark-size: $mat-checkbox-size - (2 * $_mat-pseudo-checkbox-pad vertical-align: middle; box-sizing: border-box; position: relative; + flex-shrink: 0; transition: border-color $mat-checkbox-transition-duration $mat-linear-out-slow-in-timing-function, background-color $mat-checkbox-transition-duration $mat-linear-out-slow-in-timing-function; diff --git a/src/lib/list/list.scss b/src/lib/list/list.scss index 22db02fa92ee..bda2a254af52 100644 --- a/src/lib/list/list.scss +++ b/src/lib/list/list.scss @@ -216,3 +216,9 @@ $mat-dense-list-icon-size: 20px; } } } + +.mat-list-option { + &:not([disabled]) { + cursor: pointer; + } +} diff --git a/src/lib/list/selection-list.spec.ts b/src/lib/list/selection-list.spec.ts index 6b87ea7d4504..d95f3e68efbf 100644 --- a/src/lib/list/selection-list.spec.ts +++ b/src/lib/list/selection-list.spec.ts @@ -181,6 +181,29 @@ describe('MdSelectionList', () => { expect(manager.activeItemIndex).toEqual(3); }); + + it('should be able to select all options', () => { + const list: MdSelectionList = selectionList.componentInstance; + + expect(list.options.toArray().every(option => option.selected)).toBe(false); + + list.selectAll(); + fixture.detectChanges(); + + expect(list.options.toArray().every(option => option.selected)).toBe(true); + }); + + it('should be able to deselect all options', () => { + const list: MdSelectionList = selectionList.componentInstance; + + list.options.forEach(option => option.toggle()); + expect(list.options.toArray().every(option => option.selected)).toBe(true); + + list.deselectAll(); + fixture.detectChanges(); + + expect(list.options.toArray().every(option => option.selected)).toBe(false); + }); }); describe('with single option', () => { diff --git a/src/lib/list/selection-list.ts b/src/lib/list/selection-list.ts index a239b0e81d90..3d30a58c3e28 100644 --- a/src/lib/list/selection-list.ts +++ b/src/lib/list/selection-list.ts @@ -244,6 +244,24 @@ export class MdSelectionList extends _MdSelectionListMixinBase this._element.nativeElement.focus(); } + /** Selects all of the options. */ + selectAll() { + this.options.forEach(option => { + if (!option.selected) { + option.toggle(); + } + }); + } + + /** Deselects all of the options. */ + deselectAll() { + this.options.forEach(option => { + if (option.selected) { + option.toggle(); + } + }); + } + /** Map all the options' destroy event subscriptions and merge them into one stream. */ private _onDestroySubscription(): Subscription { return RxChain.from(this.options.changes)