From a2fd6a6aee8e8a82ef5564c6e49068b1dda95d6f Mon Sep 17 00:00:00 2001 From: Chintan Kavathia Date: Tue, 15 Oct 2024 12:24:47 +0530 Subject: [PATCH] fix: horizontal scroll horizontal scroll shouldn't appear on load if there is enough space available to render columns. --- .../src/lib/components/datatable.component.ts | 36 +++++++++---------- projects/ngx-datatable/src/lib/utils/math.ts | 7 ++-- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/projects/ngx-datatable/src/lib/components/datatable.component.ts b/projects/ngx-datatable/src/lib/components/datatable.component.ts index 0cfa41160..adf2735c5 100644 --- a/projects/ngx-datatable/src/lib/components/datatable.component.ts +++ b/projects/ngx-datatable/src/lib/components/datatable.component.ts @@ -19,6 +19,7 @@ import { OnInit, Output, QueryList, + signal, TemplateRef, ViewChild, ViewEncapsulation @@ -701,6 +702,11 @@ export class DatatableComponent _subscriptions: Subscription[] = []; _ghostLoadingIndicator = false; protected verticalScrollVisible = false; + // In case horizontal scroll is enabled + // the column widths are initially calculated without vertical scroll offset + // this makes horizontal scroll to appear on load even if columns can fit in view + // this will be set to true once rows are available and rendered on UI + private _rowInitDone = signal(false); constructor() { // apply global settings from Module.forRoot @@ -853,6 +859,7 @@ export class DatatableComponent } if (rowDiffers) { queueMicrotask(() => { + this._rowInitDone.set(true); this.recalculate(); this.cd.markForCheck(); }); @@ -904,34 +911,27 @@ export class DatatableComponent } const bodyElement = this.bodyElement?.nativeElement; this.verticalScrollVisible = bodyElement?.scrollHeight > bodyElement?.clientHeight; - if (this.scrollbarV && !this.scrollbarVDynamic) { - 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.verticalScrollVisible ? this.scrollbarHelper.width : 0); - } - - if (this.headerComponent && this.headerComponent.innerWidth !== width) { - this.headerComponent.innerWidth = width; - } - if (this.bodyComponent && this.bodyComponent.innerWidth !== width) { - this.bodyComponent.innerWidth = width; - this.bodyComponent.cd.markForCheck(); - } + if (this.scrollbarV || this.scrollbarVDynamic) { + width = + width - + (this.verticalScrollVisible || !this._rowInitDone() ? this.scrollbarHelper.width : 0); } if (this.columnMode === ColumnMode.force) { - forceFillColumnWidths(columns, width, forceIdx, allowBleed); + forceFillColumnWidths(columns, width, forceIdx, allowBleed, 300, this.scrollbarHelper.width); } else if (this.columnMode === ColumnMode.flex) { adjustColumnWidths(columns, width); } - if (this.bodyComponent) { - this.bodyComponent.updateColumnGroupWidths(); + if (this.bodyComponent && this.bodyComponent.columnGroupWidths.total !== width) { + this.bodyComponent.columns = [...this._internalColumns]; this.bodyComponent.cd.markForCheck(); } + if (this.headerComponent && this.headerComponent._columnGroupWidths.total !== width) { + this.headerComponent.columns = [...this._internalColumns]; + } + return columns; } diff --git a/projects/ngx-datatable/src/lib/utils/math.ts b/projects/ngx-datatable/src/lib/utils/math.ts index 583b27546..c26946a85 100644 --- a/projects/ngx-datatable/src/lib/utils/math.ts +++ b/projects/ngx-datatable/src/lib/utils/math.ts @@ -126,7 +126,8 @@ export function forceFillColumnWidths( expectedWidth: number, startIdx: number, allowBleed: boolean, - defaultColWidth: number = 300 + defaultColWidth: number = 300, + verticalScrollWidth = 0 ) { const columnsToResize = allColumns .slice(startIdx + 1, allColumns.length) @@ -142,6 +143,7 @@ export function forceFillColumnWidths( let exceedsWindow = false; let contentWidth = getContentWidth(allColumns, defaultColWidth); let remainingWidth = expectedWidth - contentWidth; + const initialRemainingWidth = remainingWidth; const columnsProcessed: any[] = []; const remainingWidthLimit = 1; // when to stop @@ -151,7 +153,8 @@ export function forceFillColumnWidths( exceedsWindow = contentWidth >= expectedWidth; for (const column of columnsToResize) { - if (exceedsWindow && allowBleed) { + // don't bleed if the initialRemainingWidth is same as verticalScrollWidth + if (exceedsWindow && allowBleed && initialRemainingWidth !== -1 * verticalScrollWidth) { column.width = column.$$oldWidth || column.width || defaultColWidth; } else { const newSize = (column.width || defaultColWidth) + additionWidthPerColumn;