feat(carousel): add viewport adjustment test and refine gap handling in layout calculations

This commit is contained in:
2026-07-23 11:49:34 -03:00
parent 8268e58547
commit 326f2d9bcd
2 changed files with 26 additions and 7 deletions

View File

@@ -19,6 +19,7 @@ interface TestItem {
[items]="items" [items]="items"
[itemTemplate]="itemTemplate" [itemTemplate]="itemTemplate"
[scrollStep]="120" [scrollStep]="120"
[gap]="16"
ariaLabel="Productos destacados" ariaLabel="Productos destacados"
/> />
`, `,
@@ -92,4 +93,27 @@ describe('CarouselComponent', () => {
expect(scrollBy).toHaveBeenCalledTimes(2); 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');
});
}); });

View File

@@ -58,9 +58,7 @@ export class CarouselComponent<T> implements AfterViewInit {
this.refreshLayout(); this.refreshLayout();
const resizeObserver = const resizeObserver =
typeof ResizeObserver === 'undefined' typeof ResizeObserver === 'undefined' ? null : new ResizeObserver(() => this.refreshLayout());
? null
: new ResizeObserver(() => this.refreshLayout());
resizeObserver?.observe(this.host.nativeElement); resizeObserver?.observe(this.host.nativeElement);
const mutationObserver = const mutationObserver =
@@ -152,10 +150,7 @@ export class CarouselComponent<T> implements AfterViewInit {
} }
const gap = this.resolvedGap(); const gap = this.resolvedGap();
const fittingItems = Math.max( const fittingItems = Math.max(1, Math.floor((availableWidth + gap) / (itemWidth + gap)));
1,
Math.floor((availableWidth + gap) / (itemWidth + gap)),
);
const visibleItems = Math.min(fittingItems, viewport.children.length); const visibleItems = Math.min(fittingItems, viewport.children.length);
const fittedWidth = visibleItems * itemWidth + Math.max(visibleItems - 1, 0) * gap; const fittedWidth = visibleItems * itemWidth + Math.max(visibleItems - 1, 0) * gap;