From 326f2d9bcd20eb798279f46cfe87140a9eef9d63 Mon Sep 17 00:00:00 2001 From: ncoronel Date: Thu, 23 Jul 2026 11:49:34 -0300 Subject: [PATCH] feat(carousel): add viewport adjustment test and refine gap handling in layout calculations --- .../carousel/carousel.component.spec.ts | 24 +++++++++++++++++++ .../components/carousel/carousel.component.ts | 9 ++----- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/app/shared/components/carousel/carousel.component.spec.ts b/src/app/shared/components/carousel/carousel.component.spec.ts index c30c844..7e6bef7 100644 --- a/src/app/shared/components/carousel/carousel.component.spec.ts +++ b/src/app/shared/components/carousel/carousel.component.spec.ts @@ -19,6 +19,7 @@ interface TestItem { [items]="items" [itemTemplate]="itemTemplate" [scrollStep]="120" + [gap]="16" ariaLabel="Productos destacados" /> `, @@ -92,4 +93,27 @@ describe('CarouselComponent', () => { expect(scrollBy).toHaveBeenCalledTimes(2); }); + + it('ajusta y centra el viewport para mostrar únicamente elementos completos', () => { + const host = fixture.nativeElement.querySelector('app-carousel') as HTMLElement; + const firstItem = fixture.nativeElement.querySelector('.carousel__item') as HTMLElement; + + Object.defineProperty(host, 'clientWidth', { + configurable: true, + value: 650, + }); + firstItem.getBoundingClientRect = vi.fn( + () => + ({ + width: 200, + }) as DOMRect, + ); + + fixture.componentInstance.carousel().ngAfterViewInit(); + fixture.detectChanges(); + + const frame = fixture.nativeElement.querySelector('.carousel__frame') as HTMLElement; + + expect(frame.style.width).toBe('632px'); + }); }); diff --git a/src/app/shared/components/carousel/carousel.component.ts b/src/app/shared/components/carousel/carousel.component.ts index 4c7e7dd..c1540c3 100644 --- a/src/app/shared/components/carousel/carousel.component.ts +++ b/src/app/shared/components/carousel/carousel.component.ts @@ -58,9 +58,7 @@ export class CarouselComponent implements AfterViewInit { this.refreshLayout(); const resizeObserver = - typeof ResizeObserver === 'undefined' - ? null - : new ResizeObserver(() => this.refreshLayout()); + typeof ResizeObserver === 'undefined' ? null : new ResizeObserver(() => this.refreshLayout()); resizeObserver?.observe(this.host.nativeElement); const mutationObserver = @@ -152,10 +150,7 @@ export class CarouselComponent implements AfterViewInit { } const gap = this.resolvedGap(); - const fittingItems = Math.max( - 1, - Math.floor((availableWidth + gap) / (itemWidth + gap)), - ); + const fittingItems = Math.max(1, Math.floor((availableWidth + gap) / (itemWidth + gap))); const visibleItems = Math.min(fittingItems, viewport.children.length); const fittedWidth = visibleItems * itemWidth + Math.max(visibleItems - 1, 0) * gap;