diff --git a/src/lib/pagination/pagination.component.html b/src/lib/pagination/pagination.component.html
new file mode 100644
index 0000000..8a0db3f
--- /dev/null
+++ b/src/lib/pagination/pagination.component.html
@@ -0,0 +1,26 @@
+
+|
+
+ {{ displayValue(page) }}
+
+|
+
diff --git a/src/lib/pagination/pagination.component.scss b/src/lib/pagination/pagination.component.scss
new file mode 100644
index 0000000..fae36a8
--- /dev/null
+++ b/src/lib/pagination/pagination.component.scss
@@ -0,0 +1,27 @@
+:host {
+ display: flex;
+
+ > *:not(:last-child) {
+ margin-right: 12px;
+ }
+
+ .disabled,
+ span {
+ opacity: 0.5;
+ pointer-events: none;
+ }
+
+ .page {
+ cursor: pointer;
+
+ &.disabled,
+ &.dots {
+ cursor: default;
+ }
+
+ &.active {
+ color: var(--iqser-primary);
+ font-weight: bold;
+ }
+ }
+}
diff --git a/src/lib/pagination/pagination.component.ts b/src/lib/pagination/pagination.component.ts
new file mode 100644
index 0000000..82ac382
--- /dev/null
+++ b/src/lib/pagination/pagination.component.ts
@@ -0,0 +1,65 @@
+import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
+import { NgForOf } from '@angular/common';
+import { TranslateModule } from '@ngx-translate/core';
+
+@Component({
+ selector: 'iqser-pagination',
+ templateUrl: './pagination.component.html',
+ styleUrls: ['./pagination.component.scss'],
+ standalone: true,
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ imports: [NgForOf, TranslateModule],
+})
+export class PaginationComponent {
+ displayedPages: (number | string)[] = [];
+ @Output() pageChanged = new EventEmitter();
+
+ private _currentPage: number = 0;
+
+ get currentPage() {
+ return this._currentPage;
+ }
+
+ private _totalPages: number = 0;
+
+ get totalPages() {
+ return this._totalPages;
+ }
+
+ @Input()
+ set settings(value: { currentPage: number; totalPages: number }) {
+ this._currentPage = value.currentPage;
+ this._totalPages = value.totalPages;
+ this._updatePagesArray();
+ }
+
+ selectPage(page: number | string) {
+ if (page !== '...') {
+ this.pageChanged.emit(page as number);
+ }
+ }
+
+ displayValue(page: number | string) {
+ return page === '...' ? page : (page as number) + 1;
+ }
+
+ isNumber(page: number | string) {
+ return Number.isInteger(page);
+ }
+
+ private _updatePagesArray() {
+ this.displayedPages = [0];
+ if (Math.max(1, this.currentPage - 1) > 1) {
+ this.displayedPages.push('...');
+ }
+ for (let page = Math.max(1, this.currentPage - 1); page <= Math.min(this.currentPage + 1, this.totalPages - 1); ++page) {
+ this.displayedPages.push(page);
+ }
+ if (Math.min(this.currentPage + 1, this.totalPages - 1) !== this.totalPages - 1) {
+ if (this.currentPage + 1 < this.totalPages - 2) {
+ this.displayedPages.push('...');
+ }
+ this.displayedPages.push(this.totalPages - 1);
+ }
+ }
+}