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;
};