From 6271d585ef499137321df0ecb79ca4fe6d996e22 Mon Sep 17 00:00:00 2001 From: chintankavathia Date: Mon, 24 Jun 2024 14:43:35 +0530 Subject: [PATCH] fix(scroll): extra gap with frozenRight column (#58) Fixes extra gap which appears when using frozenRight and having horizontal scroll enabled along with vertical scroll. --- .../lib/components/body/body-row.component.ts | 13 +++++++++-- .../src/lib/components/body/body.component.ts | 4 ++++ .../lib/components/datatable.component.html | 2 ++ .../src/lib/components/datatable.component.ts | 17 ++++++++++---- .../lib/components/header/header.component.ts | 22 +++++++++++++++---- 5 files changed, 48 insertions(+), 10 deletions(-) diff --git a/projects/ngx-datatable/src/lib/components/body/body-row.component.ts b/projects/ngx-datatable/src/lib/components/body/body-row.component.ts index db0201ad6..e133b91d6 100644 --- a/projects/ngx-datatable/src/lib/components/body/body-row.component.ts +++ b/projects/ngx-datatable/src/lib/components/body/body-row.component.ts @@ -10,7 +10,9 @@ import { Input, KeyValueDiffer, KeyValueDiffers, + OnChanges, Output, + SimpleChanges, SkipSelf } from '@angular/core'; @@ -54,7 +56,7 @@ import { DataTableRowWrapperComponent } from './body-row-wrapper.component'; ` }) -export class DataTableBodyRowComponent implements DoCheck { +export class DataTableBodyRowComponent implements DoCheck, OnChanges { @Input() set columns(val: any[]) { this._columns = val; this.recalculateColumns(val); @@ -89,6 +91,7 @@ export class DataTableBodyRowComponent implements DoCheck { @Input() displayCheck: any; @Input() treeStatus: TreeStatus = 'collapsed'; @Input() ghostLoadingIndicator = false; + @Input() verticalScrollVisible = false; @Input() disable$: BehaviorSubject; @Input() @@ -169,6 +172,12 @@ export class DataTableBodyRowComponent implements DoCheck { this._rowDiffer = differs.find({}).create(); } + ngOnChanges(changes: SimpleChanges): void { + if (changes.verticalScrollVisible) { + this.buildStylesByGroup(); + } + } + ngDoCheck(): void { if (this._rowDiffer.diff(this.row)) { this.cd.markForCheck(); @@ -204,7 +213,7 @@ export class DataTableBodyRowComponent implements DoCheck { const bodyWidth = this.innerWidth; const totalDiff = widths.total - bodyWidth; const offsetDiff = totalDiff - offsetX; - const offset = (offsetDiff + this.scrollbarHelper.width) * -1; + const offset = (offsetDiff + (this.verticalScrollVisible ? this.scrollbarHelper.width : 0)) * -1; translateXY(styles, offset, 0); } diff --git a/projects/ngx-datatable/src/lib/components/body/body.component.ts b/projects/ngx-datatable/src/lib/components/body/body.component.ts index 7bc024c86..adc971257 100644 --- a/projects/ngx-datatable/src/lib/components/body/body.component.ts +++ b/projects/ngx-datatable/src/lib/components/body/body.component.ts @@ -101,6 +101,7 @@ import { DragEventData } from '../../types/drag-events.type'; [treeStatus]="group && group.treeStatus" [ghostLoadingIndicator]="ghostLoadingIndicator" [draggable]="rowDraggable" + [verticalScrollVisible]="verticalScrollVisible" (treeAction)="onTreeAction(group)" (activate)="selector.onActivate($event, indexes.first + i)" (drop)="drop($event, group, rowElement)" @@ -130,6 +131,7 @@ import { DragEventData } from '../../types/drag-events.type'; [rowClass]="rowClass" [ghostLoadingIndicator]="ghostLoadingIndicator" [draggable]="rowDraggable" + [verticalScrollVisible]="verticalScrollVisible" (activate)="selector.onActivate($event, i)" (drop)="drop($event, row, rowElement)" (dragover)="dragOver($event, row)" @@ -310,6 +312,8 @@ export class DataTableBodyComponent implements OnInit, OnDestroy { return this._bodyHeight; } + @Input() verticalScrollVisible = false; + @Output() scroll: EventEmitter = new EventEmitter(); @Output() page: EventEmitter = new EventEmitter(); @Output() activate: EventEmitter = new EventEmitter(); diff --git a/projects/ngx-datatable/src/lib/components/datatable.component.html b/projects/ngx-datatable/src/lib/components/datatable.component.html index f770641a9..d5b274d9f 100644 --- a/projects/ngx-datatable/src/lib/components/datatable.component.html +++ b/projects/ngx-datatable/src/lib/components/datatable.component.html @@ -18,6 +18,7 @@ [sortUnsetIcon]="cssClasses.sortUnset" [allRowsSelected]="allRowsSelected" [selectionType]="selectionType" + [verticalScrollVisible]="verticalScrollVisible" (sort)="onColumnSort($event)" (resize)="onColumnResize($event)" (resizing)="onColumnResizing($event)" @@ -60,6 +61,7 @@ [summaryRow]="summaryRow" [summaryHeight]="summaryHeight" [summaryPosition]="summaryPosition" + [verticalScrollVisible]="verticalScrollVisible" (page)="onBodyPage($event)" (activate)="activate.emit($event)" (rowContextmenu)="onRowContextmenu($event)" diff --git a/projects/ngx-datatable/src/lib/components/datatable.component.ts b/projects/ngx-datatable/src/lib/components/datatable.component.ts index dba9df09d..5ccd8b2b5 100644 --- a/projects/ngx-datatable/src/lib/components/datatable.component.ts +++ b/projects/ngx-datatable/src/lib/components/datatable.component.ts @@ -652,6 +652,9 @@ export class DatatableComponent implements OnInit, DoCheck, AfterViewInit, After @ViewChild(DataTableHeaderComponent) headerComponent: DataTableHeaderComponent; + @ViewChild(DataTableBodyComponent, { read: ElementRef }) + private bodyElement: ElementRef; + /** * Returns if all rows are selected. */ @@ -686,6 +689,7 @@ export class DatatableComponent implements OnInit, DoCheck, AfterViewInit, After _columnTemplates: QueryList; _subscriptions: Subscription[] = []; _ghostLoadingIndicator = false; + protected verticalScrollVisible = false; constructor( @SkipSelf() private scrollbarHelper: ScrollbarHelper, @@ -843,6 +847,10 @@ export class DatatableComponent implements OnInit, DoCheck, AfterViewInit, After optionalGetterForProp(this.treeToRelation) ); + queueMicrotask(() => { + this.recalculate(); + this.cd.markForCheck(); + }); this.recalculatePages(); this.cd.markForCheck(); } @@ -886,14 +894,15 @@ export class DatatableComponent implements OnInit, DoCheck, AfterViewInit, After if (!columns) {return undefined;} let width = this._innerWidth; + const bodyElement = this.bodyElement?.nativeElement; + this.verticalScrollVisible = bodyElement?.scrollHeight > bodyElement?.clientHeight; if (this.scrollbarV && !this.scrollbarVDynamic) { - width = width - this.scrollbarHelper.width; - + width = width - (this.verticalScrollVisible ? this.scrollbarHelper.width : 0); } else if (this.scrollbarVDynamic){ const scrollerHeight = this.bodyComponent?.scroller?.element.offsetHeight; if (scrollerHeight && this.bodyHeight < scrollerHeight) { - width = width - this.scrollbarHelper.width; - } + width = width - (this.verticalScrollVisible ? this.scrollbarHelper.width : 0); + } if (this.headerComponent && this.headerComponent.innerWidth !== width){ this.headerComponent.innerWidth = width; diff --git a/projects/ngx-datatable/src/lib/components/header/header.component.ts b/projects/ngx-datatable/src/lib/components/header/header.component.ts index 73f3f7766..9380013d9 100644 --- a/projects/ngx-datatable/src/lib/components/header/header.component.ts +++ b/projects/ngx-datatable/src/lib/components/header/header.component.ts @@ -6,13 +6,16 @@ import { HostBinding, Input, OnDestroy, - Output + Output, + SimpleChanges, + SkipSelf } from '@angular/core'; import { columnGroupWidths, columnsByPin, columnsByPinArr } from '../../utils/column'; import { SortType } from '../../types/sort.type'; import { SelectionType } from '../../types/selection.type'; import { DataTableColumnDirective } from '../columns/column.directive'; import { translateXY } from '../../utils/translate'; +import { ScrollbarHelper } from '../../services/scrollbar-helper.service'; @Component({ selector: 'datatable-header', @@ -102,6 +105,7 @@ export class DataTableHeaderComponent implements OnDestroy { @Input() allRowsSelected: boolean; @Input() selectionType: SelectionType; @Input() reorderable: boolean; + @Input() verticalScrollVisible = false; dragEventTarget: any; @@ -166,7 +170,16 @@ export class DataTableHeaderComponent implements OnDestroy { private destroyed = false; - constructor(private cd: ChangeDetectorRef) {} + constructor(private cd: ChangeDetectorRef, @SkipSelf() private scrollbarHelper: ScrollbarHelper) {} + + ngOnChanges(changes: SimpleChanges): void { + if (changes.verticalScrollVisible) { + this._styleByGroup.right = this.calcStylesByGroup('right'); + if (!this.destroyed) { + this.cd.detectChanges(); + } + } + } ngOnDestroy(): void { this.destroyed = true; @@ -195,7 +208,8 @@ export class DataTableHeaderComponent implements OnDestroy { @HostBinding('style.width') get headerWidth(): string { if (this.scrollbarH) { - return this.innerWidth + 'px'; + const width = this.verticalScrollVisible ? (this.innerWidth - this.scrollbarHelper.width) : this.innerWidth; + return width + 'px'; } return '100%'; @@ -339,7 +353,7 @@ export class DataTableHeaderComponent implements OnDestroy { translateXY(styles, offsetX * -1, 0); } else if (group === 'right') { const totalDiff = widths.total - this.innerWidth; - const offset = totalDiff * -1; + const offset = (totalDiff + (this.verticalScrollVisible ? this.scrollbarHelper.width : 0)) * -1; translateXY(styles, offset, 0); }