Akash AR
Akash AR

Reputation: 39

How can i style mat paginator angular as shown

I have a figma design for angular mat paginator.how can i style mat paginator angular as it is shown in figma?

click here for figma design

Upvotes: 1

Views: 3362

Answers (2)

Eliseo
Eliseo

Reputation: 57909

To create a pagination button with ellipsis we can look for in internet the necessary algoritm. I did'nt want re-invent the wheel, but, sadly I can not find one "paginator" I like (the most of then add ellipsis and I can not get always the same number of elements (buttons and ellipsis). So, if we has "getNumberOfPages (the total pages)", "countPages" (the number of buttons), "pageIndex" (the actual page -0 is the first, 1 the second one...) we can return an array of strings using the function:

createButtonsPage() {
    const last = this.getNumberOfPages() - 1;
    const b = new Array(
      last < this.countPages ? last + 1 : this.countPages
    ).fill('.');

    if (last < this.countPages) return b.map((_x, i) => '' + i);

    const links0_5 = (this.countPages - 1) / 2;
    let start = this.pageIndex - links0_5 < 0 ? 0 : 
                this.pageIndex - links0_5;
    let end =start == 0? this.countPages - 1:
             this.pageIndex + links0_5 > last ? last:
             this.pageIndex + links0_5;

    if (end == last) start = end - this.countPages + 1;

    return b.map((_x, i) => {
      return i == 0 ? '0':
             i == this.countPages - 1? '' + last:
             (i == 1 && start) || (i == this.countPages - 2 && end != last)? '...':
             '' + (i + start);
    });
  }

We can choose show buttons depending the size of the screen using fromEvent in the way

   fromEvent(window, 'resize')
        .pipe(
          startWith({ target: { innerWidth: window.innerWidth } }),
          debounceTime(200),
          distinctUntilChanged(),
          takeUntil(this.active),
          map((e: any) => {
            const countPage =
              e.target.innerWidth > 620 ? (e.target.innerWidth > 750 ? 9 : 7) : 5;
            return this.countPage
              ? countPage < this.countPage
                ? countPage
                : this.countPage
              : countPage;
          })
        )
        .subscribe((x: number) => {
          this.countPages = this.countPagesOld = x;
          this._buttons = this.createButtonsPage();
        });

And in our paginator, we can use a getter to the buttons. As we don't want "recalculate the buttons" we can store in variables the old values, some like

  get buttons() {
    if (
      !this._buttons ||
      this.pageIndexOld != this.pageIndex ||
      this.countPagesOld != this.countPages ||
      this.pageSizeOld != this.pageSize ||
      this.lengthOld != this.length
    ) {
      this._buttons = this.createButtonsPage();
      this.pageIndexOld = this.pageIndex;
      this.countPagesOld = this.countPages;
      this.pageSizeOld = this.pageSize;
      const last = this.getNumberOfPages();
      if (last && +this.control.value > last)
        this.control.setValue(last, { emitEvent: false });
    }
    return this._buttons;
  }

Well, I made a new stackblitz. In the stackblitz you can also

  1. Give value to the buttons "prev" and "next"
  2. Choose the justify-content -the paginator is wrapper in a div with flex-
  3. Change the color of the buttons -for this I use a css variable like show Netanet basal in this article (see the table-filtering-example.css)

Upvotes: 1

Eliseo
Eliseo

Reputation: 57909

You can create a custom-paginator component that extends from _MatPaginatorBase

  export class CustomPaginatorComponent extends
                  _MatPaginatorBase<MatPaginatorDefaultOptions>  {

  constructor(
    intl: MatPaginatorIntl,
    changeDetectorRef: ChangeDetectorRef,
    @Optional() @Inject(MAT_PAGINATOR_DEFAULT_OPTIONS) defaults?:
                                  MatPaginatorDefaultOptions,
  ) {
    super(intl, changeDetectorRef, defaults);
    }

To next/prev page simply call to previousPage()and nextPage()

  <button (click)="previousPage()">prev</button>
    custom-paginator works!
  <button (click)="nextPage()">next</button>

To go to a page you need create a function

  emitPageEvent(nextPage:any)
  {
    this.pageIndex=+nextPage
    this.page.emit({
      pageIndex: this.pageIndex,
      pageSize: this.pageSize,
      length: this.length,
    });  
  }
}

You can use a simple input

<input [ngModel]="pageIndex" 
       (ngModelChange)="emitPageEvent($event)">

See that you has all the properties and methods of MatPaginatorBase, the most important:

Properties:
  pageIndex      : {{pageIndex}}
  length         : {{length}}
  pageSize       : {{pageSize}}
  pageSizeOptions: [{{pageSizeOptions}}]

Functions:
  hasPreviousPage() :{{ hasPreviousPage()}}
  hasNextPage()     :{{hasNextPage()}}

  previousPage()
  nextPage()
  firstPage()
  lastPage()

See a stackblitz

Upvotes: 2

Related Questions