+
+
+
diff --git a/src/lib/paginator/paginator.md b/src/lib/paginator/paginator.md
new file mode 100644
index 000000000000..394353bdc911
--- /dev/null
+++ b/src/lib/paginator/paginator.md
@@ -0,0 +1,26 @@
+`` is a navigation for pages information, typically used with a data-table.
+
+
+
+### Basic use
+Each paginator instance requires:
+* The number of items per page (default set to 50)
+* The total number of items being paged
+
+The current page index defaults to 0, but can be explicitly set via pageIndex.
+
+When the user interacts with the paginator, a `PageEvent` will be fired that can be used to update
+any associated data view.
+
+### Page size options
+The paginator displays a dropdown of page sizes for the user to choose from. The options for this
+dropdown can be set via `pageSizeOptions`
+
+The current pageSize will always appear in the dropdown, even if it is not included in pageSizeOptions.
+
+### Internationalization
+The labels for the paginator can be customized by providing your own instance of `MdPaginatorIntl`.
+This will allow you to change the following:
+ 1. The label for the length of each page.
+ 2. The range text displayed to the user.
+ 3. The tooltip messages on the navigation buttons.
diff --git a/src/lib/paginator/paginator.scss b/src/lib/paginator/paginator.scss
new file mode 100644
index 000000000000..d547b5144cb5
--- /dev/null
+++ b/src/lib/paginator/paginator.scss
@@ -0,0 +1,81 @@
+$mat-paginator-height: 56px;
+$mat-paginator-padding: 0 8px;
+
+$mat-paginator-items-per-page-label-margin: 0 4px;
+$mat-paginator-selector-margin: 0 4px;
+$mat-paginator-selector-trigger-min-width: 56px;
+
+$mat-paginator-range-label-margin: 0 32px;
+
+$mat-paginator-button-margin: 8px;
+$mat-paginator-button-icon-height: 8px;
+$mat-paginator-button-icon-width: 8px;
+
+$mat-paginator-button-decrement-icon-margin: 12px;
+$mat-paginator-button-increment-icon-margin: 16px;
+
+.mat-paginator {
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+ min-height: $mat-paginator-height;
+ padding: $mat-paginator-padding;
+}
+
+.mat-paginator-page-size {
+ display: flex;
+ align-items: center;
+}
+
+.mat-paginator-page-size-label {
+ margin: $mat-paginator-items-per-page-label-margin;
+}
+
+.mat-paginator-page-size-select {
+ margin: $mat-paginator-selector-margin;
+
+ .mat-select-trigger {
+ min-width: $mat-paginator-selector-trigger-min-width;
+ }
+}
+
+.mat-paginator-range-label {
+ margin: $mat-paginator-range-label-margin;
+}
+
+.mat-paginator-increment-button + .mat-paginator-increment-button {
+ margin: 0 0 0 $mat-paginator-button-margin;
+
+ [dir='rtl'] & {
+ margin: 0 $mat-paginator-button-margin 0 0;
+ }
+}
+
+.mat-paginator-increment,
+.mat-paginator-decrement {
+ width: $mat-paginator-button-icon-width;
+ height: $mat-paginator-button-icon-height;
+}
+
+.mat-paginator-decrement,
+[dir='rtl'] .mat-paginator-increment {
+ transform: rotate(45deg);
+}
+.mat-paginator-increment,
+[dir='rtl'] .mat-paginator-decrement {
+ transform: rotate(225deg);
+}
+
+.mat-paginator-decrement {
+ margin-left: $mat-paginator-button-decrement-icon-margin;
+ [dir='rtl'] & {
+ margin-right: $mat-paginator-button-decrement-icon-margin;
+ }
+}
+
+.mat-paginator-increment {
+ margin-left: $mat-paginator-button-increment-icon-margin;
+ [dir='rtl'] & {
+ margin-right: $mat-paginator-button-increment-icon-margin;
+ }
+}
diff --git a/src/lib/paginator/paginator.spec.ts b/src/lib/paginator/paginator.spec.ts
new file mode 100644
index 000000000000..c00d8ad20ad5
--- /dev/null
+++ b/src/lib/paginator/paginator.spec.ts
@@ -0,0 +1,279 @@
+import {async, ComponentFixture, TestBed} from '@angular/core/testing';
+import {MdPaginatorModule} from './index';
+import {MdPaginator, PageEvent} from './paginator';
+import {Component, ElementRef, ViewChild} from '@angular/core';
+import {MdPaginatorIntl} from './paginator-intl';
+import {NoopAnimationsModule} from '@angular/platform-browser/animations';
+import {customMatchers} from '../core/testing/jasmine-matchers';
+import {dispatchMouseEvent} from '../core/testing/dispatch-events';
+
+
+describe('MdPaginator', () => {
+ let fixture: ComponentFixture;
+ let component: MdPaginatorApp;
+ let paginator: MdPaginator;
+
+ beforeEach(async(() => {
+ jasmine.addMatchers(customMatchers);
+
+ TestBed.configureTestingModule({
+ imports: [
+ MdPaginatorModule,
+ NoopAnimationsModule,
+ ],
+ declarations: [
+ MdPaginatorApp,
+ MdPaginatorWithoutPageSizeApp,
+ MdPaginatorWithoutOptionsApp,
+ ],
+ providers: [MdPaginatorIntl]
+ }).compileComponents();
+
+ fixture = TestBed.createComponent(MdPaginatorApp);
+ component = fixture.componentInstance;
+ paginator = component.mdPaginator;
+
+ fixture.detectChanges();
+ }));
+
+ describe('with the default internationalization provider', () => {
+ it('should show the right range text', () => {
+ const rangeElement = fixture.nativeElement.querySelector('.mat-paginator-range-label');
+
+ // View second page of list of 100, each page contains 10 items.
+ component.length = 100;
+ component.pageSize = 10;
+ component.pageIndex = 1;
+ fixture.detectChanges();
+ expect(rangeElement.innerText).toBe('11 - 20 of 100');
+
+ // View third page of list of 200, each page contains 20 items.
+ component.length = 200;
+ component.pageSize = 20;
+ component.pageIndex = 2;
+ fixture.detectChanges();
+ expect(rangeElement.innerText).toBe('41 - 60 of 200');
+
+ // View first page of list of 0, each page contains 5 items.
+ component.length = 0;
+ component.pageSize = 5;
+ component.pageIndex = 2;
+ fixture.detectChanges();
+ expect(rangeElement.innerText).toBe('0 of 0');
+
+ // View third page of list of 12, each page contains 5 items.
+ component.length = 12;
+ component.pageSize = 5;
+ component.pageIndex = 2;
+ fixture.detectChanges();
+ expect(rangeElement.innerText).toBe('11 - 12 of 12');
+
+ // View third page of list of 10, each page contains 5 items.
+ component.length = 10;
+ component.pageSize = 5;
+ component.pageIndex = 2;
+ fixture.detectChanges();
+ expect(rangeElement.innerText).toBe('11 - 15 of 10');
+
+ // View third page of list of -5, each page contains 5 items.
+ component.length = -5;
+ component.pageSize = 5;
+ component.pageIndex = 2;
+ fixture.detectChanges();
+ expect(rangeElement.innerText).toBe('11 - 15 of 0');
+ });
+
+ it('should show right aria-labels for select and buttons', () => {
+ const select = fixture.nativeElement.querySelector('.mat-select');
+ expect(select.getAttribute('aria-label')).toBe('Items per page:');
+
+ const prevButton = fixture.nativeElement.querySelector('.mat-paginator-navigation-previous');
+ expect(prevButton.getAttribute('aria-label')).toBe('Previous page');
+
+ const nextButton = fixture.nativeElement.querySelector('.mat-paginator-navigation-next');
+ expect(nextButton.getAttribute('aria-label')).toBe('Next page');
+ });
+ });
+
+ describe('when navigating with the navigation buttons', () => {
+ it('should be able to go to the next page', () => {
+ expect(paginator.pageIndex).toBe(0);
+
+ component.clickNextButton();
+
+ expect(paginator.pageIndex).toBe(1);
+ expect(component.latestPageEvent ? component.latestPageEvent.pageIndex : null).toBe(1);
+ });
+
+ it('should be able to go to the previous page', () => {
+ paginator.pageIndex = 1;
+ fixture.detectChanges();
+ expect(paginator.pageIndex).toBe(1);
+
+ component.clickPreviousButton();
+
+ expect(paginator.pageIndex).toBe(0);
+ expect(component.latestPageEvent ? component.latestPageEvent.pageIndex : null).toBe(0);
+ });
+
+ it('should disable navigating to the next page if at first page', () => {
+ component.goToLastPage();
+ fixture.detectChanges();
+ expect(paginator.pageIndex).toBe(10);
+ expect(paginator.hasNextPage()).toBe(false);
+
+ component.latestPageEvent = null;
+ component.clickNextButton();
+
+ expect(component.latestPageEvent).toBe(null);
+ expect(paginator.pageIndex).toBe(10);
+ });
+
+ it('should disable navigating to the previous page if at first page', () => {
+ expect(paginator.pageIndex).toBe(0);
+ expect(paginator.hasPreviousPage()).toBe(false);
+
+ component.latestPageEvent = null;
+ component.clickPreviousButton();
+
+ expect(component.latestPageEvent).toBe(null);
+ expect(paginator.pageIndex).toBe(0);
+ });
+ });
+
+ it('should default the page size options to the page size if no options provided', () => {
+ const withoutOptionsAppFixture = TestBed.createComponent(MdPaginatorWithoutOptionsApp);
+ withoutOptionsAppFixture.detectChanges();
+
+ expect(withoutOptionsAppFixture.componentInstance.mdPaginator._displayedPageSizeOptions)
+ .toEqual([10]);
+ });
+
+ it('should show a sorted list of page size options including the current page size', () => {
+ expect(paginator._displayedPageSizeOptions).toEqual([5, 10, 25, 100]);
+
+ component.pageSize = 30;
+ fixture.detectChanges();
+ expect(paginator.pageSizeOptions).toEqual([5, 10, 25, 100]);
+ expect(paginator._displayedPageSizeOptions).toEqual([5, 10, 25, 30, 100]);
+
+ component.pageSizeOptions = [100, 25, 10, 5];
+ fixture.detectChanges();
+ expect(paginator._displayedPageSizeOptions).toEqual([5, 10, 25, 30, 100]);
+ });
+
+ it('should be able to change the page size while keeping the first item present', () => {
+ // Start on the third page of a list of 100 with a page size of 10.
+ component.pageIndex = 4;
+ component.pageSize = 10;
+ component.length = 100;
+ fixture.detectChanges();
+
+ // The first item of the page should be item with index 40
+ let firstPageItemIndex: number | null = paginator.pageIndex * paginator.pageSize;
+ expect(firstPageItemIndex).toBe(40);
+
+ // The first item on the page is now 25. Change the page size to 25 so that we should now be
+ // on the second page where the top item is index 25.
+ paginator._changePageSize(25);
+ let paginationEvent = component.latestPageEvent;
+ firstPageItemIndex = paginationEvent ?
+ paginationEvent.pageIndex * paginationEvent.pageSize : null;
+ expect(firstPageItemIndex).toBe(25);
+ expect(paginationEvent ? paginationEvent.pageIndex : null).toBe(1);
+
+ // The first item on the page is still 25. Change the page size to 8 so that we should now be
+ // on the fourth page where the top item is index 24.
+ paginator._changePageSize(8);
+ paginationEvent = component.latestPageEvent;
+ firstPageItemIndex = paginationEvent ?
+ paginationEvent.pageIndex * paginationEvent.pageSize : null;
+ expect(firstPageItemIndex).toBe(24);
+ expect(paginationEvent ? paginationEvent.pageIndex : null).toBe(3);
+
+ // The first item on the page is 24. Change the page size to 16 so that we should now be
+ // on the first page where the top item is index 0.
+ paginator._changePageSize(25);
+ paginationEvent = component.latestPageEvent;
+ firstPageItemIndex = paginationEvent ?
+ paginationEvent.pageIndex * paginationEvent.pageSize : null;
+ expect(firstPageItemIndex).toBe(0);
+ expect(paginationEvent ? paginationEvent.pageIndex : null).toBe(0);
+ });
+
+ it('should show a select only if there are multiple options', () => {
+ expect(paginator._displayedPageSizeOptions).toEqual([5, 10, 25, 100]);
+ expect(fixture.nativeElement.querySelector('.mat-select')).not.toBeNull();
+
+ // Remove options so that the paginator only uses the current page size (10) as an option.
+ // Should no longer show the select component since there is only one option.
+ component.pageSizeOptions = [];
+ fixture.detectChanges();
+ expect(fixture.nativeElement.querySelector('.mat-select')).toBeNull();
+ });
+});
+
+@Component({
+ template: `
+
+
+ `,
+})
+class MdPaginatorApp {
+ pageIndex = 0;
+ pageSize = 10;
+ pageSizeOptions = [5, 10, 25, 100];
+ length = 100;
+
+ latestPageEvent: PageEvent | null;
+
+ @ViewChild(MdPaginator) mdPaginator: MdPaginator;
+
+ constructor(private _elementRef: ElementRef) { }
+
+ clickPreviousButton() {
+ const previousButton =
+ this._elementRef.nativeElement.querySelector('.mat-paginator-navigation-previous');
+ dispatchMouseEvent(previousButton, 'click');
+ }
+
+ clickNextButton() {
+ const nextButton =
+ this._elementRef.nativeElement.querySelector('.mat-paginator-navigation-next');
+ dispatchMouseEvent(nextButton, 'click'); }
+
+ goToLastPage() {
+ this.pageIndex = Math.ceil(this.length / this.pageSize);
+ }
+}
+
+@Component({
+ template: `
+
+ `,
+})
+class MdPaginatorWithoutPageSizeOrOptionsApp {
+ @ViewChild(MdPaginator) mdPaginator: MdPaginator;
+}
+
+@Component({
+ template: `
+
+ `,
+})
+class MdPaginatorWithoutPageSizeApp {
+ @ViewChild(MdPaginator) mdPaginator: MdPaginator;
+}
+
+@Component({
+ template: `
+
+ `,
+})
+class MdPaginatorWithoutOptionsApp {
+ @ViewChild(MdPaginator) mdPaginator: MdPaginator;
+}
diff --git a/src/lib/paginator/paginator.ts b/src/lib/paginator/paginator.ts
new file mode 100644
index 000000000000..47a7158b4783
--- /dev/null
+++ b/src/lib/paginator/paginator.ts
@@ -0,0 +1,157 @@
+/**
+ * @license
+ * Copyright Google Inc. 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 {
+ ChangeDetectionStrategy,
+ Component,
+ EventEmitter,
+ Input,
+ OnInit,
+ Output,
+ ViewEncapsulation
+} from '@angular/core';
+import {MdPaginatorIntl} from './paginator-intl';
+import {MATERIAL_COMPATIBILITY_MODE} from '../core';
+
+/**
+ * Change event object that is emitted when the user selects a
+ * different page size or navigates to another page.
+ */
+export class PageEvent {
+ pageIndex: number;
+ pageSize: number;
+ length: number;
+}
+
+/**
+ * Component to provide navigation between paged information. Displays the size of the current
+ * page, user-selectable options to change that size, what items are being shown, and
+ * navigational button to go to the previous or next page.
+ */
+@Component({
+ moduleId: module.id,
+ selector: 'md-paginator, mat-paginator',
+ templateUrl: 'paginator.html',
+ styleUrls: ['paginator.css'],
+ host: {
+ 'class': 'mat-paginator',
+ },
+ providers: [
+ {provide: MATERIAL_COMPATIBILITY_MODE, useValue: false}
+ ],
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ encapsulation: ViewEncapsulation.None,
+})
+export class MdPaginator implements OnInit {
+ private _initialized: boolean;
+
+ /** The zero-based page index of the displayed list of items. Defaulted to 0. */
+ @Input() pageIndex: number = 0;
+
+ /** The length of the total number of items that are being paginated. Defaulted to 0. */
+ @Input() length: number = 0;
+
+ /** Number of items to display on a page. By default set to 50. */
+ @Input()
+ get pageSize(): number { return this._pageSize; }
+ set pageSize(pageSize: number) {
+ this._pageSize = pageSize;
+ this._updateDisplayedPageSizeOptions();
+ }
+ private _pageSize: number = 50;
+
+ /** The set of provided page size options to display to the user. */
+ @Input()
+ get pageSizeOptions(): number[] { return this._pageSizeOptions; }
+ set pageSizeOptions(pageSizeOptions: number[]) {
+ this._pageSizeOptions = pageSizeOptions;
+ this._updateDisplayedPageSizeOptions();
+ }
+ private _pageSizeOptions: number[] = [];
+
+ /** Event emitted when the paginator changes the page size or page index. */
+ @Output() page = new EventEmitter();
+
+ /** Displayed set of page size options. Will be sorted and include current page size. */
+ _displayedPageSizeOptions: number[];
+
+ constructor(public _intl: MdPaginatorIntl) { }
+
+ ngOnInit() {
+ this._initialized = true;
+ this._updateDisplayedPageSizeOptions();
+ }
+
+ /** Increments the page index to the next page index if a next page exists. */
+ nextPage() {
+ if (!this.hasNextPage()) { return; }
+ this.pageIndex++;
+ this._emitPageEvent();
+ }
+
+ /** Decrements the page index to the previous page index if a next page exists. */
+ previousPage() {
+ if (!this.hasPreviousPage()) { return; }
+ this.pageIndex--;
+ this._emitPageEvent();
+ }
+
+ /** Returns true if the user can go to the next page. */
+ hasPreviousPage() {
+ return this.pageIndex >= 1 && this.pageSize != 0;
+ }
+
+ /** Returns true if the user can go to the next page. */
+ hasNextPage() {
+ const numberOfPages = Math.ceil(this.length / this.pageSize) - 1;
+ return this.pageIndex < numberOfPages && this.pageSize != 0;
+ }
+
+ /**
+ * Changes the page size so that the first item displayed on the page will still be
+ * displayed using the new page size.
+ *
+ * For example, if the page size is 10 and on the second page (items indexed 10-19) then
+ * switching so that the page size is 5 will set the third page as the current page so
+ * that the 10th item will still be displayed.
+ */
+ _changePageSize(pageSize: number) {
+ // Current page needs to be updated to reflect the new page size. Navigate to the page
+ // containing the previous page's first item.
+ const startIndex = this.pageIndex * this.pageSize;
+ this.pageIndex = Math.floor(startIndex / pageSize) || 0;
+
+ this.pageSize = pageSize;
+ this._emitPageEvent();
+ }
+
+ /**
+ * Updates the list of page size options to display to the user. Includes making sure that
+ * the page size is an option and that the list is sorted.
+ */
+ private _updateDisplayedPageSizeOptions() {
+ if (!this._initialized) { return; }
+
+ this._displayedPageSizeOptions = this.pageSizeOptions.slice();
+ if (this._displayedPageSizeOptions.indexOf(this.pageSize) == -1) {
+ this._displayedPageSizeOptions.push(this.pageSize);
+ }
+
+ // Sort the numbers using a number-specific sort function.
+ this._displayedPageSizeOptions.sort((a, b) => a - b);
+ }
+
+ /** Emits an event notifying that a change of the paginator's properties has been triggered. */
+ private _emitPageEvent() {
+ this.page.next({
+ pageIndex: this.pageIndex,
+ pageSize: this.pageSize,
+ length: this.length
+ });
+ }
+}
diff --git a/src/lib/public_api.ts b/src/lib/public_api.ts
index e28998467e46..bf44dbe51ea0 100644
--- a/src/lib/public_api.ts
+++ b/src/lib/public_api.ts
@@ -30,6 +30,7 @@ export * from './icon/index';
export * from './input/index';
export * from './list/index';
export * from './menu/index';
+export * from './paginator/index';
export * from './progress-bar/index';
export * from './progress-spinner/index';
export * from './radio/index';
diff --git a/src/material-examples/example-module.ts b/src/material-examples/example-module.ts
index e086284f382e..582aa274be58 100644
--- a/src/material-examples/example-module.ts
+++ b/src/material-examples/example-module.ts
@@ -15,8 +15,8 @@ import {
ProgressBarConfigurableExample
} from './progress-bar-configurable/progress-bar-configurable-example';
import {
- DialogOverviewExampleDialog,
- DialogOverviewExample
+ DialogOverviewExample,
+ DialogOverviewExampleDialog
} from './dialog-overview/dialog-overview-example';
import {RadioNgModelExample} from './radio-ng-model/radio-ng-model-example';
import {CardFancyExample} from './card-fancy/card-fancy-example';
@@ -36,12 +36,12 @@ import {
import {ListSectionsExample} from './list-sections/list-sections-example';
import {SnackBarOverviewExample} from './snack-bar-overview/snack-bar-overview-example';
import {
- DialogResultExampleDialog,
- DialogResultExample
+ DialogResultExample,
+ DialogResultExampleDialog
} from './dialog-result/dialog-result-example';
import {
- DialogElementsExampleDialog,
- DialogElementsExample
+ DialogElementsExample,
+ DialogElementsExampleDialog
} from './dialog-elements/dialog-elements-example';
import {TooltipOverviewExample} from './tooltip-overview/tooltip-overview-example';
import {ButtonToggleOverviewExample} from './button-toggle-overview/button-toggle-overview-example';
@@ -68,20 +68,22 @@ import {SelectOverviewExample} from './select-overview/select-overview-example';
import {ChipsOverviewExample} from './chips-overview/chips-overview-example';
import {ChipsStackedExample} from './chips-stacked/chips-stacked-example';
import {SelectFormExample} from './select-form/select-form-example';
+import {PaginatorOverviewExample} from './paginator-overview/paginator-overview-example';
import {DatepickerOverviewExample} from './datepicker-overview/datepicker-overview-example';
+import {
+ PaginatorConfigurableExample
+} from './paginator-configurable/paginator-configurable-example';
import {InputOverviewExample} from './input-overview/input-overview-example';
import {InputErrorsExample} from './input-errors/input-errors-example';
import {InputFormExample} from './input-form/input-form-example';
import {InputPrefixSuffixExample} from './input-prefix-suffix/input-prefix-suffix-example';
import {InputHintExample} from './input-hint/input-hint-example';
-
import {
MdAutocompleteModule, MdButtonModule, MdButtonToggleModule, MdCardModule, MdCheckboxModule,
MdChipsModule, MdDatepickerModule, MdDialogModule, MdGridListModule, MdIconModule, MdInputModule,
- MdListModule, MdMenuModule, MdProgressBarModule, MdProgressSpinnerModule, MdRadioModule,
- MdSelectModule, MdSidenavModule, MdSliderModule, MdSlideToggleModule, MdSnackBarModule,
- MdTabsModule,
- MdToolbarModule, MdTooltipModule
+ MdListModule, MdMenuModule, MdPaginatorModule, MdProgressBarModule, MdProgressSpinnerModule,
+ MdRadioModule, MdSelectModule, MdSidenavModule, MdSliderModule, MdSlideToggleModule,
+ MdSnackBarModule, MdTabsModule, MdToolbarModule, MdTooltipModule
} from '@angular/material';
export interface LiveExample {
@@ -143,6 +145,11 @@ export const EXAMPLE_COMPONENTS = {
'list-sections': {title: 'List with sections', component: ListSectionsExample},
'menu-icons': {title: 'Menu with icons', component: MenuIconsExample},
'menu-overview': {title: 'Basic menu', component: MenuOverviewExample},
+ 'paginator-overview': {title: 'Paginator', component: PaginatorOverviewExample},
+ 'paginator-configurable': {
+ title: 'Configurable paginator',
+ component: PaginatorConfigurableExample
+ },
'progress-bar-configurable': {
title: 'Configurable progress-bar',
component: ProgressBarConfigurableExample
@@ -201,6 +208,7 @@ export const EXAMPLE_COMPONENTS = {
MdInputModule,
MdListModule,
MdMenuModule,
+ MdPaginatorModule,
MdProgressBarModule,
MdProgressSpinnerModule,
MdRadioModule,
@@ -252,6 +260,7 @@ export const EXAMPLE_LIST = [
ListSectionsExample,
MenuIconsExample,
MenuOverviewExample,
+ PaginatorOverviewExample,
ProgressBarConfigurableExample,
ProgressBarOverviewExample,
ProgressSpinnerConfigurableExample,
diff --git a/src/material-examples/paginator-configurable/paginator-configurable-example.css b/src/material-examples/paginator-configurable/paginator-configurable-example.css
new file mode 100644
index 000000000000..7432308753e6
--- /dev/null
+++ b/src/material-examples/paginator-configurable/paginator-configurable-example.css
@@ -0,0 +1 @@
+/** No CSS for this example */
diff --git a/src/material-examples/paginator-configurable/paginator-configurable-example.html b/src/material-examples/paginator-configurable/paginator-configurable-example.html
new file mode 100644
index 000000000000..b3bda8043b0e
--- /dev/null
+++ b/src/material-examples/paginator-configurable/paginator-configurable-example.html
@@ -0,0 +1,28 @@
+
+ List length:
+
+
+
+
+ Page size:
+
+
+
+ Page size options:
+
+
+
+
+
+
+
+
Page Change Event Properties
+
List length: {{pageEvent.length}}
+
Page size: {{pageEvent.pageSize}}
+
Page index: {{pageEvent.pageIndex}}
+
\ No newline at end of file
diff --git a/src/material-examples/paginator-configurable/paginator-configurable-example.ts b/src/material-examples/paginator-configurable/paginator-configurable-example.ts
new file mode 100644
index 000000000000..0e432eb6c8eb
--- /dev/null
+++ b/src/material-examples/paginator-configurable/paginator-configurable-example.ts
@@ -0,0 +1,20 @@
+import {Component} from '@angular/core';
+import {PageEvent} from '@angular/material';
+
+@Component({
+ selector: 'paginator-configurable-example',
+ templateUrl: 'paginator-configurable-example.html',
+})
+export class PaginatorConfigurableExample {
+ // MdPaginator Inputs
+ length = 100;
+ pageSize = 10;
+ pageSizeOptions = [5, 10, 25, 100];
+
+ // MdPaginator Output
+ pageEvent: PageEvent;
+
+ setPageSizeOptions(setPageSizeOptionsInput: string) {
+ this.pageSizeOptions = setPageSizeOptionsInput.split(',').map(str => +str);
+ }
+}
diff --git a/src/material-examples/paginator-overview/paginator-overview-example.css b/src/material-examples/paginator-overview/paginator-overview-example.css
new file mode 100644
index 000000000000..7432308753e6
--- /dev/null
+++ b/src/material-examples/paginator-overview/paginator-overview-example.css
@@ -0,0 +1 @@
+/** No CSS for this example */
diff --git a/src/material-examples/paginator-overview/paginator-overview-example.html b/src/material-examples/paginator-overview/paginator-overview-example.html
new file mode 100644
index 000000000000..b80ef9183c97
--- /dev/null
+++ b/src/material-examples/paginator-overview/paginator-overview-example.html
@@ -0,0 +1,4 @@
+
+
diff --git a/src/material-examples/paginator-overview/paginator-overview-example.ts b/src/material-examples/paginator-overview/paginator-overview-example.ts
new file mode 100644
index 000000000000..d563732d6233
--- /dev/null
+++ b/src/material-examples/paginator-overview/paginator-overview-example.ts
@@ -0,0 +1,8 @@
+import {Component} from '@angular/core';
+
+
+@Component({
+ selector: 'paginator-overview-example',
+ templateUrl: 'paginator-overview-example.html',
+})
+export class PaginatorOverviewExample {}
diff --git a/tools/dgeni/index.js b/tools/dgeni/index.js
index d22b2c792b9f..a4fa70894c6b 100644
--- a/tools/dgeni/index.js
+++ b/tools/dgeni/index.js
@@ -97,6 +97,7 @@ let apiDocsPackage = new DgeniPackage('material2-api-docs', dgeniPackageDeps)
'input/index.ts',
'list/index.ts',
'menu/index.ts',
+ 'paginator/index.ts',
'progress-bar/index.ts',
'progress-spinner/index.ts',
'radio/index.ts',