Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: pagination RTL idea #2001

Merged
merged 12 commits into from
Feb 19, 2020
72 changes: 42 additions & 30 deletions libs/core/src/lib/pagination/pagination.component.html
Original file line number Diff line number Diff line change
@@ -1,34 +1,46 @@
<span class="fd-pagination__total" *ngIf="displayTotalItems && totalItems">{{ totalItems }} {{displayText}}</span>
<span class="fd-pagination__total" [ngClass]="customClasses" *ngIf="displayTotalItems && totalItems">
{{ totalItems }} {{ displayText }}
</span>
<nav class="fd-pagination__nav" *ngIf="totalItems && totalItems >= itemsPerPage">
<a class="fd-pagination__link fd-pagination__link--previous"
tabindex="0"
role="button"
[attr.aria-label]="previousLabel"
[attr.aria-disabled]="currentPage === 1 ? true : null"
(keypress)="onKeypressHandler(currentPage - 1, $event)"
(click)="goToPage(currentPage - 1)">
<a
class="fd-pagination__link fd-pagination__link--previous"
tabindex="0"
role="button"
[attr.aria-label]="previousLabel"
[attr.aria-disabled]="currentPage === 1 ? true : null"
(keypress)="onKeypressHandler(currentPage - 1, $event)"
(click)="goToPage(currentPage - 1)">
</a>
<ng-container *ngFor="let page of pages">
<a class="fd-pagination__link"
tabindex="0"
role="button"
(keypress)="onKeypressHandler(page, $event)"
(click)="goToPage(page, $event)"
*ngIf="page !== -1; else more"
[attr.aria-selected]="currentPage === page">{{page}}</a>
<ng-template #more>
<span class="fd-pagination__link fd-pagination__link--more"
aria-hidden="true"
aria-label="..."
role="presentation"></span>
</ng-template>
</ng-container>
<a class="fd-pagination__link fd-pagination__link--next"
[attr.aria-label]="nextLabel"
tabindex="0"
role="button"
[attr.aria-disabled]="isLastPage()"
(keypress)="onKeypressHandler(currentPage + 1, $event)"
(click)="goToPage(currentPage + 1)">
<div dir="ltr" class="fd-pagination-direction-override-display">
<ng-container *ngFor="let page of pages$ | async">
<a
class="fd-pagination__link"
tabindex="0"
role="button"
(keypress)="onKeypressHandler(page, $event)"
(click)="goToPage(page, $event)"
*ngIf="page !== -1; else more"
[attr.aria-selected]="currentPage === page">
{{ page }}
</a>
</ng-container>
</div>
<a
class="fd-pagination__link fd-pagination__link--next"
[attr.aria-label]="nextLabel"
tabindex="0"
role="button"
[attr.aria-disabled]="isLastPage$ | async"
(keypress)="onKeypressHandler(currentPage + 1, $event)"
(click)="goToPage(currentPage + 1)">
</a>
</nav>

<ng-template #more>
<span
class="fd-pagination__link fd-pagination__link--more"
aria-hidden="true"
aria-label="..."
role="presentation"
></span>
</ng-template>
9 changes: 9 additions & 0 deletions libs/core/src/lib/pagination/pagination.component.scss
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
@import "~fundamental-styles/dist/pagination";

.fd-pagination-direction-override-display {
display: inline-block;
}

.fd-pagination__total--rtl {
margin-right: 0;
margin-left: 8px;
}
2 changes: 1 addition & 1 deletion libs/core/src/lib/pagination/pagination.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ describe('Pagination Test', () => {
it('should get the pagination object for the service', () => {
const retVal = component.getPaginationObject();

expect(retVal).toEqual({totalItems: 3, currentPage: 1, itemsPerPage: 2});
expect(retVal).toEqual({ totalItems: 3, currentPage: 1, itemsPerPage: 2 });
});

});
61 changes: 48 additions & 13 deletions libs/core/src/lib/pagination/pagination.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@ import {
EventEmitter,
Input,
OnChanges,
OnInit,
Optional,
Output,
SimpleChanges,
ViewEncapsulation
} from '@angular/core';
import { PaginationService } from './pagination.service';
import { RtlService } from '../utils/services/rtl.service';
import { BehaviorSubject } from 'rxjs';
import { Pagination } from './pagination.model';

/**
* The component that is used to provide navigation between paged information.
Expand Down Expand Up @@ -36,7 +41,7 @@ import { PaginationService } from './pagination.service';
styleUrls: ['./pagination.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class PaginationComponent implements OnChanges {
export class PaginationComponent implements OnChanges, OnInit {
/** Represents the total number of items. */
@Input()
totalItems: number;
Expand Down Expand Up @@ -73,30 +78,47 @@ export class PaginationComponent implements OnChanges {
pageChangeStart = new EventEmitter<number>();

/** @hidden */
pages: number[];
rtl: boolean = false;

/** @hidden */
constructor(private paginationService: PaginationService) {}
get customClasses(): string {
return this.rtl ? 'fd-pagination__total--rtl' : '';
}

/** @hidden */
pages$: BehaviorSubject<number[]> = new BehaviorSubject([]);

isLastPage$: BehaviorSubject<boolean> = new BehaviorSubject(this._isLastPage);

/** @hidden */
constructor(private paginationService: PaginationService, @Optional() private rtlService: RtlService) { }

/** @hidden */
ngOnChanges(changes: SimpleChanges) {
if (changes && changes.currentPage) {
this.currentPage = changes.currentPage.currentValue;
}
this.pages = this.paginationService.getPages(this.getPaginationObject());

this._refreshPages();

const totalPages = this.paginationService.getTotalPages(this.getPaginationObject());
if (!this.currentPage || this.currentPage < 1) {
this.currentPage = 1;
} else if (this.currentPage > totalPages) {
this.currentPage = totalPages;
}

this.isLastPage$.next(this._isLastPage);
}

/**
* Checks if the current page is the last page.
*/
isLastPage(): boolean {
return this.currentPage === this.paginationService.getTotalPages(this.getPaginationObject());
/** @hidden */
ngOnInit(): void {
if (this.rtlService) {
this.rtlService.rtl.subscribe(value => {
this.rtl = value;
this._refreshPages();
})
}
}

/**
Expand All @@ -123,20 +145,33 @@ export class PaginationComponent implements OnChanges {
if (page > this.paginationService.getTotalPages(this.getPaginationObject()) || page < 1) {
return;
}
this.pages = this.paginationService.getPages(this.getPaginationObject());

this._refreshPages();

this.pageChangeStart.emit(page);
}

/**
* Retrieves an object that represents
* the total number of items, the current page, and the number of items per page.
*/
getPaginationObject() {
const retVal = {
getPaginationObject(): Pagination {
return {
totalItems: this.totalItems,
currentPage: this.currentPage,
itemsPerPage: this.itemsPerPage
};
return retVal;
}

/** @hidden */
private _refreshPages(): void {
let pages = this.paginationService.getPages(this.getPaginationObject());
pages = this.rtl ? pages.slice().reverse() : pages;
this.pages$.next(pages);
}

/** @hidden */
private get _isLastPage(): boolean {
return this.currentPage === this.paginationService.getTotalPages(this.getPaginationObject());
}
}
2 changes: 1 addition & 1 deletion libs/core/src/lib/pagination/pagination.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ import { PaginationService } from './pagination.service';
providers: [PaginationService],
exports: [PaginationComponent]
})
export class PaginationModule {}
export class PaginationModule { }
36 changes: 36 additions & 0 deletions src/stories/pagination/fd-pagination.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { moduleMetadata } from '@storybook/angular';
import { withKnobs, number } from '@storybook/addon-knobs';
import { withA11y } from '@storybook/addon-a11y';

import { PaginationComponent, PaginationModule } from 'libs/core/src/lib/pagination/public_api';

export default {
title: 'Fd pagination',
component: PaginationComponent,
moduleMetadata: moduleMetadata,
decorators: [
withKnobs,
withA11y,
moduleMetadata({
imports: [PaginationModule],
declarations: []
})
]
};

export const Pagination = () => ({
template:
`
<fd-pagination [totalItems]="totalItems" (pageChangeStart)="newPageClicked($event)"
[itemsPerPage]="itemsPerPage"
[currentPage]="currentPage"></fd-pagination>
`,
props: {
totalItems: number('totalItems', 50),
itemsPerPage: number('itemsPerPage', 10),
currentPage: number('currentPage', 3),
newPageClicked: (event: number) => {
alert('Page ' + event + ' clicked!');
}
}
});