diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/index.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/index.ts
index c812fc601e..13fe3365d3 100644
--- a/npm/ng-packs/packages/theme-shared/src/lib/components/index.ts
+++ b/npm/ng-packs/packages/theme-shared/src/lib/components/index.ts
@@ -4,6 +4,8 @@ export * from './chart/chart.component';
export * from './confirmation/confirmation.component';
export * from './loader-bar/loader-bar.component';
export * from './modal/modal.component';
+export * from './paginator/paginator.component';
+export * from './sort-order-icon/sort-order-icon.component';
export * from './table-empty-message/table-empty-message.component';
+export * from './table/table.component';
export * from './toast/toast.component';
-export * from './sort-order-icon/sort-order-icon.component';
diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/table/table.component.html b/npm/ng-packs/packages/theme-shared/src/lib/components/table/table.component.html
new file mode 100644
index 0000000000..6f0d080e9d
--- /dev/null
+++ b/npm/ng-packs/packages/theme-shared/src/lib/components/table/table.component.html
@@ -0,0 +1,26 @@
+
diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/table/table.component.scss b/npm/ng-packs/packages/theme-shared/src/lib/components/table/table.component.scss
new file mode 100644
index 0000000000..4881816a52
--- /dev/null
+++ b/npm/ng-packs/packages/theme-shared/src/lib/components/table/table.component.scss
@@ -0,0 +1,3 @@
+.ui-table-scrollable-wrapper {
+ overflow: auto;
+}
diff --git a/npm/ng-packs/packages/theme-shared/src/lib/components/table/table.component.ts b/npm/ng-packs/packages/theme-shared/src/lib/components/table/table.component.ts
new file mode 100644
index 0000000000..f9811c219c
--- /dev/null
+++ b/npm/ng-packs/packages/theme-shared/src/lib/components/table/table.component.ts
@@ -0,0 +1,64 @@
+import { Component, OnInit, Input, TemplateRef, Output, EventEmitter } from '@angular/core';
+
+@Component({
+ selector: 'abp-table',
+ templateUrl: 'table.component.html',
+ styleUrls: ['table.component.scss'],
+})
+export class TableComponent implements OnInit {
+ private _totalRecords: number;
+
+ @Input()
+ value: any[];
+
+ @Input()
+ headerTemplate: TemplateRef;
+
+ @Input()
+ bodyTemplate: TemplateRef;
+
+ @Input()
+ colgroupTemplate: TemplateRef;
+
+ @Input()
+ maxHeight: number;
+
+ @Input()
+ rows: number;
+
+ @Output()
+ readonly pageChange = new EventEmitter();
+
+ page = 1;
+
+ @Input()
+ get totalRecords(): number {
+ return this._totalRecords || this.value.length;
+ }
+ set totalRecords(newValue: number) {
+ if (newValue < 0) this._totalRecords = 0;
+
+ this._totalRecords = newValue;
+ }
+
+ get totalPages(): number {
+ if (!this.rows) {
+ return;
+ }
+
+ return Math.ceil(this.totalRecords / this.rows);
+ }
+
+ get slicedValue(): any[] {
+ if (!this.rows || this.rows > this.value.length) {
+ return this.value;
+ }
+
+ const start = (this.page - 1) * this.rows;
+ return this.value.slice(start, start + this.rows);
+ }
+
+ constructor() {}
+
+ ngOnInit() {}
+}
diff --git a/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts b/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts
index b40a4ea05a..370262be97 100644
--- a/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts
+++ b/npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts
@@ -1,9 +1,10 @@
import { CoreModule, LazyLoadService } from '@abp/ng.core';
+import { DatePipe } from '@angular/common';
import { APP_INITIALIZER, Injector, ModuleWithProviders, NgModule } from '@angular/core';
+import { NgbDateParserFormatter } from '@ng-bootstrap/ng-bootstrap';
import { NgxValidateCoreModule } from '@ngx-validate/core';
import { MessageService } from 'primeng/components/common/messageservice';
import { ToastModule } from 'primeng/toast';
-import { forkJoin } from 'rxjs';
import { BreadcrumbComponent } from './components/breadcrumb/breadcrumb.component';
import { ButtonComponent } from './components/button/button.component';
import { ChartComponent } from './components/chart/chart.component';
@@ -13,16 +14,16 @@ import { LoaderBarComponent } from './components/loader-bar/loader-bar.component
import { ModalComponent } from './components/modal/modal.component';
import { SortOrderIconComponent } from './components/sort-order-icon/sort-order-icon.component';
import { TableEmptyMessageComponent } from './components/table-empty-message/table-empty-message.component';
+import { TableComponent } from './components/table/table.component';
import { ToastComponent } from './components/toast/toast.component';
import styles from './constants/styles';
import { TableSortDirective } from './directives/table-sort.directive';
import { ErrorHandler } from './handlers/error.handler';
-import { chartJsLoaded$ } from './utils/widget-utils';
import { RootParams } from './models/common';
-import { HTTP_ERROR_CONFIG, httpErrorConfigFactory } from './tokens/http-error.token';
-import { NgbDateParserFormatter } from '@ng-bootstrap/ng-bootstrap';
+import { httpErrorConfigFactory, HTTP_ERROR_CONFIG } from './tokens/http-error.token';
import { DateParserFormatter } from './utils/date-parser-formatter';
-import { DatePipe } from '@angular/common';
+import { chartJsLoaded$ } from './utils/widget-utils';
+import { PaginatorComponent } from './components/paginator/paginator.component';
export function appendScript(injector: Injector) {
const fn = () => {
@@ -45,6 +46,8 @@ export function appendScript(injector: Injector) {
HttpErrorWrapperComponent,
LoaderBarComponent,
ModalComponent,
+ PaginatorComponent,
+ TableComponent,
TableEmptyMessageComponent,
ToastComponent,
SortOrderIconComponent,
@@ -57,6 +60,8 @@ export function appendScript(injector: Injector) {
ConfirmationComponent,
LoaderBarComponent,
ModalComponent,
+ PaginatorComponent,
+ TableComponent,
TableEmptyMessageComponent,
ToastComponent,
SortOrderIconComponent,