+
diff --git a/src/dev-app/mdc-paginator/mdc-paginator-demo.scss b/src/dev-app/mdc-paginator/mdc-paginator-demo.scss
new file mode 100644
index 000000000000..32628c37915e
--- /dev/null
+++ b/src/dev-app/mdc-paginator/mdc-paginator-demo.scss
@@ -0,0 +1,20 @@
+.demo-section {
+ max-width: 600px;
+ margin-bottom: 24px;
+ padding: 16px;
+ background: #efefef !important;
+
+ & > * {
+ margin: 0 0 32px;
+ }
+}
+
+.demo-options {
+ display: flex;
+ flex-direction: column;
+ max-width: 300px;
+
+ .mat-mdc-slide-toggle {
+ margin-bottom: 8px;
+ }
+}
diff --git a/src/dev-app/mdc-paginator/mdc-paginator-demo.ts b/src/dev-app/mdc-paginator/mdc-paginator-demo.ts
new file mode 100644
index 000000000000..1e687b5a6501
--- /dev/null
+++ b/src/dev-app/mdc-paginator/mdc-paginator-demo.ts
@@ -0,0 +1,36 @@
+/**
+ * @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 {Component} from '@angular/core';
+import {PageEvent} from '@angular/material-experimental/mdc-paginator';
+
+@Component({
+ selector: 'mdc-paginator-demo',
+ templateUrl: 'mdc-paginator-demo.html',
+ styleUrls: ['mdc-paginator-demo.css'],
+})
+export class MdcPaginatorDemo {
+ length = 50;
+ pageSize = 10;
+ pageIndex = 0;
+ pageSizeOptions = [5, 10, 25];
+
+ hidePageSize = false;
+ showPageSizeOptions = true;
+ showFirstLastButtons = true;
+ disabled = false;
+
+ pageEvent: PageEvent;
+
+ handlePageEvent(e: PageEvent) {
+ this.pageEvent = e;
+ this.length = e.length;
+ this.pageSize = e.pageSize;
+ this.pageIndex = e.pageIndex;
+ }
+}
diff --git a/src/dev-app/paginator/paginator-demo.scss b/src/dev-app/paginator/paginator-demo.scss
index 01e52aa28fa5..f0804fe3547e 100644
--- a/src/dev-app/paginator/paginator-demo.scss
+++ b/src/dev-app/paginator/paginator-demo.scss
@@ -4,7 +4,7 @@
background: #efefef !important;
& > * {
- margin: 32px 0;
+ margin: 0 0 32px;
}
}
diff --git a/src/dev-app/paginator/paginator-demo.ts b/src/dev-app/paginator/paginator-demo.ts
index ad4e947dc0af..9ab6c0a07774 100644
--- a/src/dev-app/paginator/paginator-demo.ts
+++ b/src/dev-app/paginator/paginator-demo.ts
@@ -6,14 +6,13 @@
* found in the LICENSE file at https://angular.io/license
*/
-import {Component, ViewEncapsulation} from '@angular/core';
+import {Component} from '@angular/core';
import {PageEvent} from '@angular/material/paginator';
@Component({
selector: 'paginator-demo',
templateUrl: 'paginator-demo.html',
styleUrls: ['paginator-demo.css'],
- encapsulation: ViewEncapsulation.None,
})
export class PaginatorDemo {
length = 50;
diff --git a/src/material-experimental/config.bzl b/src/material-experimental/config.bzl
index bd597da02e56..13e2d979ecde 100644
--- a/src/material-experimental/config.bzl
+++ b/src/material-experimental/config.bzl
@@ -21,6 +21,7 @@ entryPoints = [
"mdc-list",
"mdc-menu",
"mdc-menu/testing",
+ "mdc-paginator",
"mdc-progress-bar",
"mdc-progress-bar/testing",
"mdc-progress-spinner",
diff --git a/src/material-experimental/mdc-paginator/BUILD.bazel b/src/material-experimental/mdc-paginator/BUILD.bazel
new file mode 100644
index 000000000000..f8ab24a62576
--- /dev/null
+++ b/src/material-experimental/mdc-paginator/BUILD.bazel
@@ -0,0 +1,79 @@
+load(
+ "//tools:defaults.bzl",
+ "ng_module",
+ "ng_test_library",
+ "ng_web_test_suite",
+ "sass_binary",
+ "sass_library",
+)
+
+package(default_visibility = ["//visibility:public"])
+
+ng_module(
+ name = "mdc-paginator",
+ srcs = glob(
+ ["**/*.ts"],
+ exclude = ["**/*.spec.ts"],
+ ),
+ assets = [":paginator.css"] + glob(["**/*.html"]),
+ module_name = "@angular/material-experimental/mdc-paginator",
+ deps = [
+ "//src/material-experimental/mdc-button",
+ "//src/material-experimental/mdc-select",
+ "//src/material/paginator",
+ "//src/material/tooltip",
+ "@npm//@angular/common",
+ "@npm//@angular/core",
+ "@npm//@angular/forms", # TODO(jelbourn): transitive dep via generated code
+ "@npm//rxjs",
+ ],
+)
+
+sass_library(
+ name = "mdc_paginator_scss_lib",
+ srcs = glob(["**/_*.scss"]),
+ deps = [
+ "//src/material/core:core_scss_lib",
+ ],
+)
+
+sass_binary(
+ name = "mdc_paginator_scss",
+ src = "paginator.scss",
+ include_paths = [
+ "external/npm/node_modules",
+ ],
+ deps = [
+ "//src/material-experimental/mdc-form-field:mdc_form_field_scss_lib",
+ ],
+)
+
+ng_test_library(
+ name = "mdc_paginator_tests_lib",
+ srcs = glob(
+ ["**/*.spec.ts"],
+ exclude = ["**/*.e2e.spec.ts"],
+ ),
+ deps = [
+ ":mdc-paginator",
+ "//src/cdk/testing/private",
+ "//src/material-experimental/mdc-select",
+ "//src/material/core",
+ "@npm//@angular/platform-browser",
+ ],
+)
+
+ng_web_test_suite(
+ name = "unit_tests",
+ static_files = [
+ "@npm//:node_modules/@material/textfield/dist/mdc.textfield.js",
+ "@npm//:node_modules/@material/line-ripple/dist/mdc.lineRipple.js",
+ "@npm//:node_modules/@material/notched-outline/dist/mdc.notchedOutline.js",
+ "@npm//:node_modules/@material/ripple/dist/mdc.ripple.js",
+ "@npm//:node_modules/@material/dom/dist/mdc.dom.js",
+ ],
+ deps = [
+ ":mdc_paginator_tests_lib",
+ "//src/material-experimental:mdc_require_config.js",
+ ],
+)
diff --git a/src/material-experimental/mdc-paginator/README.md b/src/material-experimental/mdc-paginator/README.md
new file mode 100644
index 000000000000..61d95bd14fbc
--- /dev/null
+++ b/src/material-experimental/mdc-paginator/README.md
@@ -0,0 +1,102 @@
+This is prototype of an alternate version of `` built on top of
+[MDC Web](https://github.com/material-components/material-components-web). It demonstrates how
+Angular Material could use MDC Web under the hood while still exposing the same API Angular users as
+the existing ``. This component is experimental and should not be used in production.
+
+## How to use
+Assuming your application is already up and running using Angular Material, you can add this
+component by following these steps:
+
+1. Install Angular Material Experimental & MDC WEB:
+
+ ```bash
+ npm i material-components-web @angular/material-experimental
+ ```
+
+2. In your `angular.json`, make sure `node_modules/` is listed as a Sass include path. This is
+ needed for the Sass compiler to be able to find the MDC Web Sass files.
+
+ ```json
+ ...
+ "styles": [
+ "src/styles.scss"
+ ],
+ "stylePreprocessorOptions": {
+ "includePaths": [
+ "node_modules/"
+ ]
+ },
+ ...
+ ```
+
+3. Import the experimental `MatPaginatorModule` and add it to the module that declares your
+ component:
+
+ ```ts
+ import {MatPaginatorModule} from '@angular/material-experimental/mdc-paginator';
+
+ @NgModule({
+ declarations: [MyComponent],
+ imports: [MatPaginatorModule],
+ })
+ export class MyModule {}
+ ```
+
+4. Use `` in your component's template, just like you would the normal
+ ``:
+
+ ```html
+
+ ```
+
+5. Add the theme and typography mixins to your Sass. (There is currently no pre-built CSS option for
+ the experimental ``):
+
+ ```scss
+ @import '~@angular/material/theming';
+ @import '~@angular/material-experimental/mdc-paginator';
+
+ $my-primary: mat-palette($mat-indigo);
+ $my-accent: mat-palette($mat-pink, A200, A100, A400);
+ $my-theme: mat-light-theme((
+ color: (
+ primary: $my-primary,
+ accent: $my-accent
+ )
+ ));
+
+ @include mat-mdc-paginator-theme($my-theme);
+ @include mat-mdc-paginator-typography();
+ ```
+
+## API differences
+The experimental paginator API closely matches the
+[API of the standard paginator](https://material.angular.io/components/paginator/api).
+`@angular/material-experimental/mdc-paginator` exports symbols with the same name and public
+interface as all of the symbols found under `@angular/material/paginator`, except for the following
+differences:
+
+* The experimental paginator module has a `MatPaginatorDefaultOptions` interface that is identical
+to the one from `@angular/material/paginator`, with the exception of the `formFieldAppearance`
+property whose type is narrower. It allows only the `fill` and `outline` appearances, because these
+are the appearances supported by the MDC-based `MatFormField`.
+
+## Replacing the standard paginator in an existing app
+Because the experimental API mirrors the API for the standard paginator, it can easily be swapped in
+by just changing the import paths. There is currently no schematic for this, but you can run the
+following string replace across your TypeScript files:
+
+```bash
+grep -lr --include="*.ts" --exclude-dir="node_modules" \
+ --exclude="*.d.ts" "['\"]@angular/material/paginator['\"]" | xargs sed -i \
+ "s/['\"]@angular\/material\/paginator['\"]/'@angular\/material-experimental\/mdc-paginator'/g"
+```
+
+CSS styles and tests that depend on implementation details of `mat-paginator` (such as getting
+elements from the template by class name) will need to be manually updated.
+
+There are some small visual differences between this paginator and the standard `mat-paginator`.
+This paginator depends on `MatFormField` and `MatButton` which are also based on MDC, putting them
+closer to the Material Design specification while making them slightly wider. You may have to
+account for the wider paginator in your app's layout. Furthermore, the form field inside the
+paginator only supports the `outline` and `fill` appearances.
diff --git a/src/material-experimental/mdc-paginator/_paginator-theme.scss b/src/material-experimental/mdc-paginator/_paginator-theme.scss
new file mode 100644
index 000000000000..723cc249ad81
--- /dev/null
+++ b/src/material-experimental/mdc-paginator/_paginator-theme.scss
@@ -0,0 +1,84 @@
+@import '@material/theme/variables.import';
+@import '@material/typography/variables.import';
+@import '../../material/core/theming/check-duplicate-styles';
+@import './paginator-variables';
+
+@mixin mat-mdc-paginator-color($config-or-theme) {
+ $config: mat-get-color-config($config-or-theme);
+ @include mat-using-mdc-theme($config) {
+ $icon-color: rgba(mdc-theme-prop-value(on-surface), 0.54);
+ $disabled-color: rgba(mdc-theme-prop-value(on-surface), 0.12);
+
+ .mat-mdc-paginator {
+ background: mdc-theme-prop-value(surface);
+ color: rgba(mdc-theme-prop-value(on-surface), 0.87);
+ }
+
+ .mat-mdc-paginator-icon {
+ fill: $icon-color;
+ }
+
+ .mat-mdc-paginator-decrement,
+ .mat-mdc-paginator-increment {
+ border-top: 2px solid $icon-color;
+ border-right: 2px solid $icon-color;
+ }
+
+ .mat-mdc-paginator-first,
+ .mat-mdc-paginator-last {
+ border-top: 2px solid $icon-color;
+ }
+
+ .mat-mdc-icon-button[disabled] {
+ .mat-mdc-paginator-decrement,
+ .mat-mdc-paginator-increment,
+ .mat-mdc-paginator-first,
+ .mat-mdc-paginator-last {
+ border-color: $disabled-color;
+ }
+
+ .mat-mdc-paginator-icon {
+ fill: $disabled-color;
+ }
+ }
+ }
+}
+
+@mixin mat-mdc-paginator-typography($config-or-theme) {
+ $config: mat-get-typography-config($config-or-theme);
+ .mat-mdc-paginator {
+ @include mat-using-mdc-typography($config) {
+ @include mdc-typography(caption, $query: $mat-typography-styles-query);
+ }
+ }
+}
+
+@mixin _mat-mdc-paginator-density($config-or-theme) {
+ $density-scale: mat-get-density-config($config-or-theme);
+ $height: _mat-density-prop-value($mat-paginator-density-config, $density-scale, height);
+
+ @include _mat-density-legacy-compatibility() {
+ .mat-mdc-paginator-container {
+ min-height: $height;
+ }
+ }
+}
+
+@mixin mat-mdc-paginator-theme($theme-or-color-config) {
+ $theme: _mat-legacy-get-theme($theme-or-color-config);
+ @include _mat-check-duplicate-theme-styles($theme, 'mat-mdc-paginator') {
+ $color: mat-get-color-config($theme);
+ $density: mat-get-density-config($theme);
+ $typography: mat-get-typography-config($theme);
+
+ @if $color != null {
+ @include mat-mdc-paginator-color($color);
+ }
+ @if $density != null {
+ @include _mat-mdc-paginator-density($density);
+ }
+ @if $typography != null {
+ @include mat-mdc-paginator-typography($typography);
+ }
+ }
+}
diff --git a/src/material-experimental/mdc-paginator/_paginator-variables.scss b/src/material-experimental/mdc-paginator/_paginator-variables.scss
new file mode 100644
index 000000000000..1625dcc5eb33
--- /dev/null
+++ b/src/material-experimental/mdc-paginator/_paginator-variables.scss
@@ -0,0 +1,13 @@
+$mat-paginator-height: 56px !default;
+// Minimum height for paginator's in the highest density is determined based on how
+// much the paginator can shrink until the content exceeds (i.e. navigation buttons).
+$mat-paginator-minimum-height: 40px !default;
+$mat-paginator-maximum-height: $mat-paginator-height !default;
+
+$mat-paginator-density-config: (
+ height: (
+ default: $mat-paginator-height,
+ maximum: $mat-paginator-maximum-height,
+ minimum: $mat-paginator-minimum-height,
+ )
+) !default;
diff --git a/src/material-experimental/mdc-paginator/index.ts b/src/material-experimental/mdc-paginator/index.ts
new file mode 100644
index 000000000000..676ca90f1ffa
--- /dev/null
+++ b/src/material-experimental/mdc-paginator/index.ts
@@ -0,0 +1,9 @@
+/**
+ * @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/mdc-paginator/paginator-module.ts b/src/material-experimental/mdc-paginator/paginator-module.ts
new file mode 100644
index 000000000000..6c2e88834a62
--- /dev/null
+++ b/src/material-experimental/mdc-paginator/paginator-module.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 {CommonModule} from '@angular/common';
+import {NgModule} from '@angular/core';
+import {MAT_PAGINATOR_INTL_PROVIDER} from '@angular/material/paginator';
+import {MatButtonModule} from '@angular/material-experimental/mdc-button';
+import {MatSelectModule} from '@angular/material-experimental/mdc-select';
+import {MatTooltipModule} from '@angular/material/tooltip';
+import {MatPaginator} from './paginator';
+
+
+@NgModule({
+ imports: [
+ CommonModule,
+ MatButtonModule,
+ MatSelectModule,
+ MatTooltipModule,
+ ],
+ exports: [MatPaginator],
+ declarations: [MatPaginator],
+ providers: [MAT_PAGINATOR_INTL_PROVIDER],
+})
+export class MatPaginatorModule {}
diff --git a/src/material-experimental/mdc-paginator/paginator.html b/src/material-experimental/mdc-paginator/paginator.html
new file mode 100644
index 000000000000..37cb9e21bc68
--- /dev/null
+++ b/src/material-experimental/mdc-paginator/paginator.html
@@ -0,0 +1,86 @@
+