import { useMemo } from 'react'; import { RefObject } from 'react'; import { Helpers } from '../services/helpers'; import { ARROW_DIMENSIONS } from '../components/consts'; import { ArrowSize } from '../types'; export interface CarouselDimensions { containerWidth: number; arrowSize: ArrowSize; arrowSpace: number; contentWidth: number; itemWidth: number; } interface UseCarouselDimensionsProps { widgetWidth: number; slideRef: RefObject; hideArrows: boolean; hasItems: boolean; nbElems: number; itemCount: number; isMobile?: boolean; partialItemWidth?: number; alwaysPartial?: boolean; forcedArrowSize?: ArrowSize; } export const useCarouselDimensions = ({ widgetWidth, slideRef, hideArrows, hasItems, nbElems, itemCount, isMobile = false, partialItemWidth = 0, alwaysPartial = false, forcedArrowSize, }: UseCarouselDimensionsProps): CarouselDimensions => { const carouselDimensions = useMemo((): CarouselDimensions => { const containerWidth = widgetWidth > 0 ? widgetWidth : slideRef.current?.clientWidth || 600; const configuredVisibleItems = nbElems > 0 ? nbElems : Math.max(itemCount, 1); const showArrows = !isMobile && hasItems && !hideArrows; const arrowSize: ArrowSize = showArrows ? forcedArrowSize ?? Helpers.calculateArrowSize(containerWidth) : 'medium'; // Calculate actual arrow space based on size const arrowSpace = showArrows ? (ARROW_DIMENSIONS[arrowSize].width + ARROW_DIMENSIONS[arrowSize].padding * 2) * 2 // left + right arrows : 0; const contentWidth = containerWidth - arrowSpace; let itemWidth: number; if (isMobile) { if (configuredVisibleItems <= 1) { itemWidth = contentWidth * 0.8; // 80% of content width for main item with partials } else { itemWidth = contentWidth / configuredVisibleItems; } } else { // Calculate item width - accounting for visible items and partial items const visibleItems = configuredVisibleItems; // By default, only apply the partial-item peek for even item counts // (e.g. 4 items + 0.4 partial) so odd layouts fill the track cleanly. // When alwaysPartial is set the rule is bypassed (Buy box carousel). const isEven = visibleItems % 2 === 0; const partialWidth = alwaysPartial || isEven ? partialItemWidth : 0; itemWidth = Math.floor(contentWidth / (visibleItems + partialWidth)); } return { containerWidth, arrowSize, arrowSpace, contentWidth, itemWidth, }; }, [ widgetWidth, hideArrows, hasItems, nbElems, itemCount, isMobile, partialItemWidth, alwaysPartial, forcedArrowSize, slideRef.current?.clientWidth, ]); return carouselDimensions; }; export default useCarouselDimensions;