Skip to content

Commit

Permalink
feat(material/paginator): add input for configuring the underlying se…
Browse files Browse the repository at this point in the history
…lect (angular#13705)

Since we hide the underlying `MatSelect` inside the `MatPaginator`, the user doesn't have the ability to configure some of the inputs. These changes introduce an input that proxy some of the supported properties to the select.

Fixes angular#13646.
  • Loading branch information
crisbeto authored Feb 26, 2022
1 parent 7d0bca7 commit 5fc655b
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 5 deletions.
2 changes: 2 additions & 0 deletions src/material-experimental/mdc-paginator/paginator.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
[value]="pageSize"
[disabled]="disabled"
[aria-labelledby]="_pageSizeLabelId"
[panelClass]="selectConfig.panelClass || ''"
[disableOptionCentering]="selectConfig.disableOptionCentering"
(selectionChange)="_changePageSize($event.value)">
<mat-option *ngFor="let pageSizeOption of _displayedPageSizeOptions" [value]="pageSizeOption">
{{pageSizeOption}}
Expand Down
27 changes: 26 additions & 1 deletion src/material-experimental/mdc-paginator/paginator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ import {dispatchMouseEvent} from '../../cdk/testing/private';
import {ThemePalette} from '@angular/material/core';
import {MatSelect} from '@angular/material-experimental/mdc-select';
import {By} from '@angular/platform-browser';
import {MatPaginatorModule, MatPaginator, MatPaginatorIntl} from './index';
import {
MatPaginatorModule,
MatPaginator,
MatPaginatorIntl,
MatPaginatorSelectConfig,
} from './index';
import {MAT_PAGINATOR_DEFAULT_OPTIONS, MatPaginatorDefaultOptions} from './paginator';

describe('MDC-based MatPaginator', () => {
Expand Down Expand Up @@ -215,6 +220,24 @@ describe('MDC-based MatPaginator', () => {
expect(formField.classList).not.toContain('mat-accent');
});

it('should be able to pass options to the underlying mat-select', () => {
const fixture = createComponent(MatPaginatorApp);
fixture.detectChanges();
const select: MatSelect = fixture.debugElement.query(By.directive(MatSelect)).componentInstance;

expect(select.disableOptionCentering).toBe(false);
expect(select.panelClass).toBeFalsy();

fixture.componentInstance.selectConfig = {
disableOptionCentering: true,
panelClass: 'custom-class',
};
fixture.detectChanges();

expect(select.disableOptionCentering).toBe(true);
expect(select.panelClass).toBe('custom-class');
});

describe('when showing the first and last button', () => {
let fixture: ComponentFixture<MatPaginatorApp>;
let component: MatPaginatorApp;
Expand Down Expand Up @@ -542,6 +565,7 @@ function getLastButton(fixture: ComponentFixture<any>) {
[pageSize]="pageSize"
[pageSizeOptions]="pageSizeOptions"
[hidePageSize]="hidePageSize"
[selectConfig]="selectConfig"
[showFirstLastButtons]="showFirstLastButtons"
[length]="length"
[color]="color"
Expand All @@ -560,6 +584,7 @@ class MatPaginatorApp {
disabled: boolean;
pageEvent = jasmine.createSpy('page event');
color: ThemePalette;
selectConfig: MatPaginatorSelectConfig = {};

@ViewChild(MatPaginator) paginator: MatPaginator;

Expand Down
1 change: 1 addition & 0 deletions src/material-experimental/mdc-paginator/public-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ export {
MAT_PAGINATOR_INTL_PROVIDER_FACTORY,
MAT_PAGINATOR_INTL_PROVIDER,
PageEvent,
MatPaginatorSelectConfig,
} from '@angular/material/paginator';
2 changes: 2 additions & 0 deletions src/material/paginator/paginator.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
<mat-select
[value]="pageSize"
[disabled]="disabled"
[panelClass]="selectConfig.panelClass || ''"
[disableOptionCentering]="selectConfig.disableOptionCentering"
[aria-label]="_intl.itemsPerPageLabel"
(selectionChange)="_changePageSize($event.value)">
<mat-option *ngFor="let pageSizeOption of _displayedPageSizeOptions" [value]="pageSizeOption">
Expand Down
8 changes: 6 additions & 2 deletions src/material/paginator/paginator.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ any associated data view.
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.
The current pageSize will always appear in the dropdown, even if it is not included in
pageSizeOptions.

If you want to customize some of the optional of the `mat-select` inside the `mat-paginator`, you
can use the `selectConfig` input.

### Internationalization
The labels for the paginator can be customized by providing your own instance of `MatPaginatorIntl`.
Expand All @@ -30,5 +34,5 @@ The paginator uses `role="group"` to semantically group its child controls. You
`aria-label` or `aria-labelledby` attribute to `<mat-paginator>` with a label that describes
the content controlled by the pagination control.

You can set the `aria-label` attributes for the button and select controls within the paginator in
You can set the `aria-label` attributes for the button and select controls within the paginator in
`MatPaginatorIntl`.
26 changes: 25 additions & 1 deletion src/material/paginator/paginator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import {ThemePalette} from '@angular/material/core';
import {MatSelect} from '@angular/material/select';
import {By} from '@angular/platform-browser';
import {MatPaginator, MatPaginatorIntl, MatPaginatorModule} from './index';
import {MAT_PAGINATOR_DEFAULT_OPTIONS, MatPaginatorDefaultOptions} from './paginator';
import {
MAT_PAGINATOR_DEFAULT_OPTIONS,
MatPaginatorDefaultOptions,
MatPaginatorSelectConfig,
} from './paginator';

describe('MatPaginator', () => {
function createComponent<T>(type: Type<T>, providers: Provider[] = []): ComponentFixture<T> {
Expand Down Expand Up @@ -210,6 +214,24 @@ describe('MatPaginator', () => {
expect(formField.classList).not.toContain('mat-accent');
});

it('should be able to pass options to the underlying mat-select', () => {
const fixture = createComponent(MatPaginatorApp);
fixture.detectChanges();
const select: MatSelect = fixture.debugElement.query(By.directive(MatSelect)).componentInstance;

expect(select.disableOptionCentering).toBe(false);
expect(select.panelClass).toBeFalsy();

fixture.componentInstance.selectConfig = {
disableOptionCentering: true,
panelClass: 'custom-class',
};
fixture.detectChanges();

expect(select.disableOptionCentering).toBe(true);
expect(select.panelClass).toBe('custom-class');
});

describe('when showing the first and last button', () => {
let fixture: ComponentFixture<MatPaginatorApp>;
let component: MatPaginatorApp;
Expand Down Expand Up @@ -537,6 +559,7 @@ function getLastButton(fixture: ComponentFixture<any>) {
[pageSize]="pageSize"
[pageSizeOptions]="pageSizeOptions"
[hidePageSize]="hidePageSize"
[selectConfig]="selectConfig"
[showFirstLastButtons]="showFirstLastButtons"
[length]="length"
[color]="color"
Expand All @@ -555,6 +578,7 @@ class MatPaginatorApp {
disabled: boolean;
pageEvent = jasmine.createSpy('page event');
color: ThemePalette;
selectConfig: MatPaginatorSelectConfig = {};

@ViewChild(MatPaginator) paginator: MatPaginator;

Expand Down
12 changes: 12 additions & 0 deletions src/material/paginator/paginator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,15 @@ export const MAT_PAGINATOR_DEFAULT_OPTIONS = new InjectionToken<MatPaginatorDefa
/** @docs-private */
const _MatPaginatorMixinBase = mixinDisabled(mixinInitialized(class {}));

/** Object that can used to configure the underlying `MatSelect` inside a `MatPaginator`. */
export interface MatPaginatorSelectConfig {
/** Whether to center the active option over the trigger. */
disableOptionCentering?: boolean;

/** Classes to be passed to the select panel. */
panelClass?: string | string[] | Set<string> | {[key: string]: any};
}

/**
* Base class with all of the `MatPaginator` functionality.
* @docs-private
Expand Down Expand Up @@ -175,6 +184,9 @@ export abstract class _MatPaginatorBase<
}
private _showFirstLastButtons = false;

/** Used to configure the underlying `MatSelect` inside the paginator. */
@Input() selectConfig: MatPaginatorSelectConfig = {};

/** Event emitted when the paginator changes the page size or page index. */
@Output() readonly page: EventEmitter<PageEvent> = new EventEmitter<PageEvent>();

Expand Down
11 changes: 10 additions & 1 deletion tools/public_api_guard/material/paginator.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,11 @@ export abstract class _MatPaginatorBase<O extends {
set pageSizeOptions(value: number[] | readonly number[]);
_previousButtonsDisabled(): boolean;
previousPage(): void;
selectConfig: MatPaginatorSelectConfig;
get showFirstLastButtons(): boolean;
set showFirstLastButtons(value: BooleanInput);
// (undocumented)
static ɵdir: i0.ɵɵDirectiveDeclaration<_MatPaginatorBase<any>, never, never, { "color": "color"; "pageIndex": "pageIndex"; "length": "length"; "pageSize": "pageSize"; "pageSizeOptions": "pageSizeOptions"; "hidePageSize": "hidePageSize"; "showFirstLastButtons": "showFirstLastButtons"; }, { "page": "page"; }, never>;
static ɵdir: i0.ɵɵDirectiveDeclaration<_MatPaginatorBase<any>, never, never, { "color": "color"; "pageIndex": "pageIndex"; "length": "length"; "pageSize": "pageSize"; "pageSizeOptions": "pageSizeOptions"; "hidePageSize": "hidePageSize"; "showFirstLastButtons": "showFirstLastButtons"; "selectConfig": "selectConfig"; }, { "page": "page"; }, never>;
// (undocumented)
static ɵfac: i0.ɵɵFactoryDeclaration<_MatPaginatorBase<any>, never>;
}
Expand Down Expand Up @@ -128,6 +129,14 @@ export class MatPaginatorModule {
static ɵmod: i0.ɵɵNgModuleDeclaration<MatPaginatorModule, [typeof i1.MatPaginator], [typeof i2.CommonModule, typeof i3.MatButtonModule, typeof i4.MatSelectModule, typeof i5.MatTooltipModule, typeof i6.MatCommonModule], [typeof i1.MatPaginator]>;
}

// @public
export interface MatPaginatorSelectConfig {
disableOptionCentering?: boolean;
panelClass?: string | string[] | Set<string> | {
[key: string]: any;
};
}

// @public
export class PageEvent {
length: number;
Expand Down

0 comments on commit 5fc655b

Please sign in to comment.