CDK selection column and CDK row selection with CDK table
+
+
Mat selection with a list
+
+
+
Mat selection column and Mat row selection with Mat table
+
`,
})
export class SelectionDemo {
diff --git a/src/material-experimental/config.bzl b/src/material-experimental/config.bzl
index 8467738ff3c3..cf57e63518cc 100644
--- a/src/material-experimental/config.bzl
+++ b/src/material-experimental/config.bzl
@@ -27,6 +27,7 @@ entryPoints = [
"mdc-table",
"mdc-tabs",
"popover-edit",
+ "selection",
]
# List of all non-testing entry-points of the Angular material-experimental package.
diff --git a/src/material-experimental/selection/BUILD.bazel b/src/material-experimental/selection/BUILD.bazel
new file mode 100644
index 000000000000..2289e9776998
--- /dev/null
+++ b/src/material-experimental/selection/BUILD.bazel
@@ -0,0 +1,35 @@
+package(default_visibility = ["//visibility:public"])
+
+load("//tools:defaults.bzl", "ng_module", "sass_binary", "sass_library")
+
+ng_module(
+ name = "selection",
+ srcs = glob(
+ ["**/*.ts"],
+ exclude = ["**/*.spec.ts"],
+ ),
+ assets = [":selection_column_scss"],
+ module_name = "@angular/material-experimental/selection",
+ deps = [
+ "//src/cdk-experimental/selection",
+ "//src/material/checkbox",
+ "//src/material/table",
+ "@npm//@angular/core",
+ ],
+)
+
+sass_library(
+ name = "selection_scss_lib",
+ srcs = glob(["**/_*.scss"]),
+ deps = [],
+)
+
+sass_binary(
+ name = "selection_column_scss",
+ src = "selection-column.scss",
+ include_paths = [
+ "external/npm/node_modules",
+ ],
+ deps = [
+ ],
+)
diff --git a/src/material-experimental/selection/_selection.scss b/src/material-experimental/selection/_selection.scss
new file mode 100644
index 000000000000..14f7219a909f
--- /dev/null
+++ b/src/material-experimental/selection/_selection.scss
@@ -0,0 +1,3 @@
+@mixin mat-selection-theme($theme) {}
+
+@mixin mat-selection-typography($config) {}
diff --git a/src/material-experimental/selection/index.ts b/src/material-experimental/selection/index.ts
new file mode 100644
index 000000000000..e1fc5bfc0361
--- /dev/null
+++ b/src/material-experimental/selection/index.ts
@@ -0,0 +1,10 @@
+/**
+ * @license
+ * Copyright Google LLC All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+
+export * from './public-api';
+
diff --git a/src/material-experimental/selection/public-api.ts b/src/material-experimental/selection/public-api.ts
new file mode 100644
index 000000000000..8cae343cd78d
--- /dev/null
+++ b/src/material-experimental/selection/public-api.ts
@@ -0,0 +1,14 @@
+/**
+ * @license
+ * Copyright Google LLC All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+
+export * from './selection';
+export * from './select-all';
+export * from './selection-toggle';
+export * from './selection-column';
+export * from './row-selection';
+export * from './selection-module';
diff --git a/src/material-experimental/selection/row-selection.ts b/src/material-experimental/selection/row-selection.ts
new file mode 100644
index 000000000000..518fb70e899c
--- /dev/null
+++ b/src/material-experimental/selection/row-selection.ts
@@ -0,0 +1,34 @@
+/**
+ * @license
+ * Copyright Google LLC All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+
+import {CdkRowSelection} from '@angular/cdk-experimental/selection';
+import {Input, Directive} from '@angular/core';
+
+
+/**
+ * Applies `mat-selected` class and `aria-selected` to an element.
+ *
+ * Must be used within a parent `MatSelection` directive.
+ * Must be provided with the value. The index is required if `trackBy` is used on the `CdkSelection`
+ * directive.
+ */
+@Directive({
+ selector: '[matRowSelection]',
+ host: {
+ '[class.mat-selected]': '_selection.isSelected(this.value, this.index)',
+ '[attr.aria-selected]': '_selection.isSelected(this.value, this.index)',
+ },
+ providers: [{provide: CdkRowSelection, useExisting: MatRowSelection}]
+})
+export class MatRowSelection extends CdkRowSelection {
+ /** The value that is associated with the row */
+ @Input('matRowSelectionValue') value: T;
+
+ /** The index of the value in the list. Required when used with `trackBy` */
+ @Input('matRowSelectionIndex') index: number|undefined;
+}
diff --git a/src/material-experimental/selection/select-all.ts b/src/material-experimental/selection/select-all.ts
new file mode 100644
index 000000000000..2501bb9dfce4
--- /dev/null
+++ b/src/material-experimental/selection/select-all.ts
@@ -0,0 +1,29 @@
+/**
+ * @license
+ * Copyright Google LLC All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+
+import {CdkSelectAll} from '@angular/cdk-experimental/selection';
+import {Directive} from '@angular/core';
+
+
+/**
+ * Makes the element a select-all toggle.
+ *
+ * Must be used within a parent `MatSelection` directive. It toggles the selection states
+ * of all the selection toggles connected with the `MatSelection` directive.
+ * If the element implements `ControlValueAccessor`, e.g. `MatCheckbox`, the directive
+ * automatically connects it with the select-all state provided by the `MatSelection` directive. If
+ * not, use `checked` to get the checked state, `indeterminate` to get the indeterminate state,
+ * and `toggle()` to change the selection state.
+ */
+@Directive({
+ selector: '[matSelectAll]',
+ exportAs: 'matSelectAll',
+ providers: [{provide: CdkSelectAll, useExisting: MatSelectAll}]
+})
+export class MatSelectAll extends CdkSelectAll {
+}
diff --git a/src/material-experimental/selection/selection-column.scss b/src/material-experimental/selection/selection-column.scss
new file mode 100644
index 000000000000..81d4f297d7a7
--- /dev/null
+++ b/src/material-experimental/selection/selection-column.scss
@@ -0,0 +1,5 @@
+th.mat-selection-column-header,
+td.mat-selection-column-cell {
+ text-align: center;
+ width: 48px;
+}
diff --git a/src/material-experimental/selection/selection-column.ts b/src/material-experimental/selection/selection-column.ts
new file mode 100644
index 000000000000..074f0b091180
--- /dev/null
+++ b/src/material-experimental/selection/selection-column.ts
@@ -0,0 +1,101 @@
+/**
+ * @license
+ * Copyright Google LLC All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+
+import {MatCellDef, MatColumnDef, MatHeaderCellDef, MatTable} from '@angular/material/table';
+import {
+ Component,
+ Input,
+ isDevMode,
+ OnDestroy,
+ OnInit,
+ Optional,
+ ViewChild,
+ ChangeDetectionStrategy,
+ ViewEncapsulation,
+} from '@angular/core';
+
+import {MatSelection} from './selection';
+
+/**
+ * Column that adds row selecting checkboxes and a select-all checkbox if `matSelectionMultiple` is
+ * `true`.
+ *
+ * Must be used within a parent `MatSelection` directive.
+ */
+@Component({
+ selector: 'mat-selection-column',
+ template: `
+
+
+
+
+
+
+
+
+ `,
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ styleUrls: ['selection-column.css'],
+ encapsulation: ViewEncapsulation.None,
+})
+export class MatSelectionColumn implements OnInit, OnDestroy {
+ /** Column name that should be used to reference this column. */
+ @Input()
+ get name(): string {
+ return this._name;
+ }
+ set name(name: string) {
+ this._name = name;
+
+ this._syncColumnDefName();
+ }
+ private _name: string;
+
+ @ViewChild(MatColumnDef, {static: true}) private readonly _columnDef: MatColumnDef;
+ @ViewChild(MatCellDef, {static: true}) private readonly _cell: MatCellDef;
+ @ViewChild(MatHeaderCellDef, {static: true}) private readonly _headerCell: MatHeaderCellDef;
+
+ constructor(
+ @Optional() private _table: MatTable,
+ @Optional() readonly selection: MatSelection,
+ ) {}
+
+ ngOnInit() {
+ if (!this.selection && isDevMode()) {
+ throw Error('MatSelectionColumn: missing MatSelection in the parent');
+ }
+
+ this._syncColumnDefName();
+
+ if (this._table) {
+ this._columnDef.cell = this._cell;
+ this._columnDef.headerCell = this._headerCell;
+ this._table.addColumnDef(this._columnDef);
+ } else if (isDevMode()) {
+ throw Error('MatSelectionColumn: missing parent table');
+ }
+ }
+
+ ngOnDestroy() {
+ if (this._table) {
+ this._table.removeColumnDef(this._columnDef);
+ }
+ }
+
+ private _syncColumnDefName() {
+ if (this._columnDef) {
+ this._columnDef.name = this._name;
+ }
+ }
+}
diff --git a/src/material-experimental/selection/selection-module.ts b/src/material-experimental/selection/selection-module.ts
new file mode 100644
index 000000000000..f8e90a2d0466
--- /dev/null
+++ b/src/material-experimental/selection/selection-module.ts
@@ -0,0 +1,43 @@
+/**
+ * @license
+ * Copyright Google LLC All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+
+// TODO(yifange): Move the table-specific code to a separate module from the other selection
+// behaviors once we move it out of experiemental.
+import {CommonModule} from '@angular/common';
+import {NgModule} from '@angular/core';
+import {MatTableModule} from '@angular/material/table';
+import {MatCheckboxModule} from '@angular/material/checkbox';
+import {MatSelectAll} from './select-all';
+import {MatSelection} from './selection';
+import {MatSelectionToggle} from './selection-toggle';
+import {MatSelectionColumn} from './selection-column';
+import {MatRowSelection} from './row-selection';
+
+@NgModule({
+ imports: [
+ CommonModule,
+ MatTableModule,
+ MatCheckboxModule,
+ ],
+ exports: [
+ MatSelectAll,
+ MatSelection,
+ MatSelectionToggle,
+ MatSelectionColumn,
+ MatRowSelection,
+ ],
+ declarations: [
+ MatSelectAll,
+ MatSelection,
+ MatSelectionToggle,
+ MatSelectionColumn,
+ MatRowSelection,
+ ],
+})
+export class MatSelectionModule {
+}
diff --git a/src/material-experimental/selection/selection-toggle.ts b/src/material-experimental/selection/selection-toggle.ts
new file mode 100644
index 000000000000..32e36dd11d48
--- /dev/null
+++ b/src/material-experimental/selection/selection-toggle.ts
@@ -0,0 +1,33 @@
+/**
+ * @license
+ * Copyright Google LLC All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+
+import {CdkSelectionToggle} from '@angular/cdk-experimental/selection';
+import {Directive, Input} from '@angular/core';
+
+/**
+ * Makes the element a selection toggle.
+ *
+ * Must be used within a parent `MatSelection` directive.
+ * Must be provided with the value. If `trackBy` is used on `MatSelection`, the index of the value
+ * is required. If the element implements `ControlValueAccessor`, e.g. `MatCheckbox`, the directive
+ * automatically connects it with the selection state provided by the `MatSelection` directive. If
+ * not, use `checked$` to get the checked state of the value, and `toggle()` to change the selection
+ * state.
+ */
+@Directive({
+ selector: '[matSelectionToggle]',
+ exportAs: 'matSelectionToggle',
+ providers: [{provide: CdkSelectionToggle, useExisting: MatSelectionToggle}]
+})
+export class MatSelectionToggle extends CdkSelectionToggle {
+ /** The value that is associated with the toggle */
+ @Input('matSelectionToggleValue') value: T;
+
+ /** The index of the value in the list. Required when used with `trackBy` */
+ @Input('matSelectionToggleIndex') index: number|undefined;
+}
diff --git a/src/material-experimental/selection/selection.ts b/src/material-experimental/selection/selection.ts
new file mode 100644
index 000000000000..62ab56468ec3
--- /dev/null
+++ b/src/material-experimental/selection/selection.ts
@@ -0,0 +1,35 @@
+/**
+ * @license
+ * Copyright Google LLC All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+
+import {CdkSelection, SelectionChange} from '@angular/cdk-experimental/selection';
+import {Directive, Input, Output, EventEmitter} from '@angular/core';
+
+
+/**
+ * Manages the selection states of the items and provides methods to check and update the selection
+ * states.
+ * It must be applied to the parent element if `matSelectionToggle`, `matSelectAll`,
+ * `matRowSelection` and `matSelectionColumn` are applied.
+ */
+@Directive({
+ selector: '[matSelection]',
+ exportAs: 'matSelection',
+ providers: [{provide: CdkSelection, useExisting: MatSelection}]
+})
+export class MatSelection extends CdkSelection {
+ /** Whether to support multiple selection */
+ @Input('matSelectionMultiple') multiple: boolean;
+
+ /** Emits when selection changes. */
+ @Output('matSelectionChange') change = new EventEmitter>();
+}
+
+/**
+ * Represents the change in the selection set.
+ */
+export {SelectionChange} from '@angular/cdk-experimental/selection';