angularangular-materialangular15mdc-componentsangular-material-paginator

Apply 'formFieldAppearance' property to Angular Material MDC Paginator


I have a design system based in Angular Material. I'm working on migrating to MDC components. I'm now on Paginator and cannot figure out how to set the formFieldAppearance on <mat-paginator>
We want to use fill appearance. I've tried applying a formFieldAppearance or even just a appearance property on the <mat-paginator>, but it doesn't seem to do anything.

I can see that there's a formFieldAppearance property under MatPaginatorDefaultOptions, but I don't understand how we're supposed to apply that to the component. (https://v15.material.angular.io/components/paginator/api#MatPaginatorDefaultOptions)

Here's a stackblitz that I forked from the Material example. It's on Angular 15 right now: https://stackblitz.com/edit/52mppf?file=src%2Fapp%2Fpaginator-overview-example.html


Solution

  • How does it work?

    formFieldAppearance is part of MatPaginatorDefaultOptions which is provided via Angular's dependency injection system under the MAT_PAGINATOR_DEFAULT_OPTIONS token.

    The paginator instance sets its _formFieldAppearance property on line 229 in the constructor:

    constructor(
        public _intl: MatPaginatorIntl,
        private _changeDetectorRef: ChangeDetectorRef,
        @Optional() @Inject(MAT_PAGINATOR_DEFAULT_OPTIONS) defaults?: MatPaginatorDefaultOptions,
    ) {
        // Other initialization...
    
        // Read injected options or fall back.
        this._formFieldAppearance = defaults?.formFieldAppearance || 'outline';
    }
    

    How can it be set?

    To set a different value, you just need to provide a value for the MAT_PAGINATOR_DEFAULT_OPTIONS token at some level above the <mat-paginator> instance. The one you choose depends on the scope you want to target. The higher in the DI tree you provide the value, the more paginators you will change... keeping in mind that you can provide an override value further down the tree.

    1. At the level of the (standalone) component containing the paginator. Impacts only paginators in this component or its descendents.
    import { Component } from '@angular/core';
    import { MatPaginator, MAT_PAGINATOR_DEFAULT_OPTIONS } from '@angular/material/paginator';
    
    @Component({
      standalone: true,
      template: `
        <mat-paginator></mat-paginator>
      `,
      providers: [
        {
          provide: MAT_PAGINATOR_DEFAULT_OPTIONS,
          useValue: {
            formFieldAppearance: 'fill',
          },
        },
      ]
    })
    export class SomeComponent {}
    
    1. At the level of the module defining the component containing the paginator. Impacts only paginators in components/modules under this module.
    import { NgModule } from '@angular/core';
    import { MAT_PAGINATOR_DEFAULT_OPTIONS } from '@angular/material/paginator';
    import { SomeComponent } from './some.component.ts';
    
    @NgModule({
      declarations: [SomeComponent],
      providers: [
        {
          provide: MAT_PAGINATOR_DEFAULT_OPTIONS,
          useValue: {
            formFieldAppearance: 'fill',
          },
        },
      ],
    })
    export class SomeModule {}
    
    1. At the level of a route targeting the component containing the paginator (or one of it's parent components/modules). Impacts only paginators in components/modules under this route.
    import { Routes } from '@angular/router';
    import { MAT_PAGINATOR_DEFAULT_OPTIONS } from '@angular/material/paginator';
    
    export const appRoutes: Routes = [
      {
        path: 'foo',
        loadComponent: () => import('./some.component.ts').then(c => c.SomeComponent),
        providers: [
          {
            provide: MAT_PAGINATOR_DEFAULT_OPTIONS,
            useValue: {
              formFieldAppearance: 'fill',
            },
          },
        ],
      },
    ];
    
    1. At the level of the application. Impacts all paginators in the application.
    import { bootstrapApplication } from '@angular/core';
    import { MAT_PAGINATOR_DEFAULT_OPTIONS } from '@angular/material/paginator';
    import { App } from './app.component.ts';
    
    bootstrapApplication(App, { 
      providers: [
        {
          provide: MAT_PAGINATOR_DEFAULT_OPTIONS,
          useValue: {
            formFieldAppearance: 'fill',
          },
        },
      ],
    });