diff --git a/npm/ng-packs/packages/theme-shared/src/lib/constants/styles.ts b/npm/ng-packs/packages/theme-shared/src/lib/constants/styles.ts index a3698f2164..a54aecf581 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/constants/styles.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/constants/styles.ts @@ -32,6 +32,11 @@ export default ` min-width: 215px; } +.datatable-scroll { + margin-bottom: 5px !important; + width: unset !important; +} + .ui-table-scrollable-body::-webkit-scrollbar { height: 5px !important; width: 5px !important; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/directives/ngx-datatable-default.directive.ts b/npm/ng-packs/packages/theme-shared/src/lib/directives/ngx-datatable-default.directive.ts index ec6710474f..e8b9ffac85 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/directives/ngx-datatable-default.directive.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/directives/ngx-datatable-default.directive.ts @@ -1,12 +1,19 @@ -import { Directive, HostBinding, Input } from '@angular/core'; -import { ColumnMode, DatatableComponent } from '@swimlane/ngx-datatable'; +import { DOCUMENT } from '@angular/common'; +import { AfterViewInit, Directive, HostBinding, Inject, Input, OnDestroy } from '@angular/core'; +import { ColumnMode, DatatableComponent, ScrollerComponent } from '@swimlane/ngx-datatable'; +import { fromEvent, Subscription } from 'rxjs'; +import { debounceTime } from 'rxjs/operators'; @Directive({ // tslint:disable-next-line selector: 'ngx-datatable[default]', exportAs: 'ngxDatatableDefault', }) -export class NgxDatatableDefaultDirective { +export class NgxDatatableDefaultDirective implements AfterViewInit, OnDestroy { + private subscription = new Subscription(); + + private resizeDiff = 0; + @Input() class = 'material bordered'; @HostBinding('class') @@ -14,7 +21,7 @@ export class NgxDatatableDefaultDirective { return `ngx-datatable ${this.class}`; } - constructor(private table: DatatableComponent) { + constructor(private table: DatatableComponent, @Inject(DOCUMENT) private document: MockDocument) { this.table.columnMode = ColumnMode.force; this.table.footerHeight = 50; this.table.headerHeight = 50; @@ -22,4 +29,56 @@ export class NgxDatatableDefaultDirective { this.table.scrollbarH = true; this.table.virtualization = false; } + + private fixHorizontalGap(scroller: ScrollerComponent) { + const { body, documentElement } = this.document; + + if (documentElement.scrollHeight !== documentElement.clientHeight) { + if (this.resizeDiff === 0) { + this.resizeDiff = window.innerWidth - body.offsetWidth; + scroller.scrollWidth -= this.resizeDiff; + } + } else { + scroller.scrollWidth += this.resizeDiff; + this.resizeDiff = 0; + } + } + + private fixStyleOnWindowResize() { + // avoided @HostListener('window:resize') in favor of performance + const subscription = fromEvent(window, 'resize') + .pipe(debounceTime(500)) + .subscribe(() => { + const { scroller } = this.table.bodyComponent; + + if (!scroller) return; + + this.fixHorizontalGap(scroller); + }); + + this.subscription.add(subscription); + } + + ngAfterViewInit() { + this.fixStyleOnWindowResize(); + } + + ngOnDestroy() { + this.subscription.unsubscribe(); + } +} + +// fix: https://github.com/angular/angular/issues/20351 +interface MockDocument { + body: MockBody; + documentElement: MockDocumentElement; +} + +interface MockBody { + offsetWidth: number; +} + +interface MockDocumentElement { + clientHeight: number; + scrollHeight: number; }