diff --git a/spec/components/Carousel/Carousel.test.tsx b/spec/components/Carousel/Carousel.test.tsx index e29a134..87a0729 100644 --- a/spec/components/Carousel/Carousel.test.tsx +++ b/spec/components/Carousel/Carousel.test.tsx @@ -596,4 +596,43 @@ describe('Carousel component', () => { expect(carousel).toBeInTheDocument(); }); }); + + describe('itemCallbacks', () => { + test('calls onProductClick when product card is clicked', () => { + const onProductClick = vi.fn(); + render(); + + const productCard = screen.getByText('Product 1').closest('.cio-product-card')!; + fireEvent.click(productCard); + expect(onProductClick).toHaveBeenCalledWith(mockProducts[0], 0); + }); + + test('calls onAddToCart when add to cart button is clicked', () => { + const onAddToCart = vi.fn(); + render(); + + const buttons = screen.getAllByText('Add to Cart'); + fireEvent.click(buttons[0]); + expect(onAddToCart).toHaveBeenCalledWith(expect.any(Object), mockProducts[0], 0); + }); + + test('calls onAddToWishlist when wishlist button is clicked', () => { + const onAddToWishlist = vi.fn(); + render(); + + const wishlistButtons = screen.getAllByLabelText(/add to wishlist/i); + fireEvent.click(wishlistButtons[0]); + expect(onAddToWishlist).toHaveBeenCalledWith(expect.any(Object), mockProducts[0], 0); + }); + + test('does not throw when itemCallbacks is not provided', () => { + expect(() => { + render(); + + // Without callbacks, clicking should not throw (buttons won't exist) + const productCard = screen.getByText('Product 1').closest('.cio-product-card')!; + fireEvent.click(productCard); + }).not.toThrow(); + }); + }); }); diff --git a/src/components/carousel.tsx b/src/components/carousel.tsx index cc57c6f..8e4d9b5 100644 --- a/src/components/carousel.tsx +++ b/src/components/carousel.tsx @@ -181,7 +181,8 @@ function CarouselBase({ } function Carousel(props: CarouselOpts) { - const { children, items, componentOverrides, ...rest } = props; + const { children, items, componentOverrides, itemCallbacks, ...rest } = props; + const { onProductClick, onAddToCart, onAddToWishlist } = itemCallbacks || {}; const { autoPlay, slidesToScroll, orientation, loop, responsive } = rest; const renderProps: CarouselRenderProps = { @@ -225,6 +226,11 @@ function Carousel(props: CarouselOpts) { onProductClick(item, index) : undefined} + onAddToCart={onAddToCart ? (e) => onAddToCart(e, item, index) : undefined} + onAddToWishlist={ + onAddToWishlist ? (e) => onAddToWishlist(e, item, index) : undefined + } componentOverrides={componentOverrides?.item?.productCard} /> diff --git a/src/types/carouselTypes.ts b/src/types/carouselTypes.ts index db2a0a0..1473f3c 100644 --- a/src/types/carouselTypes.ts +++ b/src/types/carouselTypes.ts @@ -73,8 +73,15 @@ export type CarouselOverrides = ComponentOverrideProps>; }; +export type CarouselItemCallbacks = { + onProductClick?: (item: T, index: number) => void; + onAddToCart?: (e: React.MouseEvent, item: T, index: number) => void; + onAddToWishlist?: (e: React.MouseEvent, item: T, index: number) => void; +}; + export type CarouselOpts = CarouselRenderProps & IncludeComponentOverrides> & Omit, 'children'> & { children?: RenderPropsChildren>; + itemCallbacks?: CarouselItemCallbacks; };