Cart Item
CommerceShopping cart line item with quantity controls.
Preview
1
$0.00
1
$0.00
Usage
example.jsx
import { CartItem } from "@/components/ui/cart-item";
export default function Example() {
return <CartItem />;
}Source Code
Copy this file into components/ui/cart-item.jsx in your project.
cart-item.jsx
import { forwardRef } from "react";
import { cn } from "@/lib/utils";
const CartItem = forwardRef(({ className, item = {}, onUpdateQty, onRemove, ...props }, ref) => (
<div ref={ref} className={cn("flex items-center gap-4 border-b py-4", className)} {...props}>
<div className="h-16 w-16 shrink-0 overflow-hidden rounded-md bg-muted">
{item.image && <img src={item.image} alt={item.name} className="h-full w-full object-cover" />}
</div>
<div className="flex-1 min-w-0">
<h4 className="truncate font-medium">{item.name}</h4>
{item.variant && <p className="text-xs text-muted-foreground">{item.variant}</p>}
<div className="mt-1 flex items-center gap-2">
<button onClick={() => onUpdateQty?.(item, Math.max(0, (item.qty || 1) - 1))} className="flex h-6 w-6 items-center justify-center rounded border text-xs hover:bg-accent">−</button>
<span className="text-sm font-medium">{item.qty || 1}</span>
<button onClick={() => onUpdateQty?.(item, (item.qty || 1) + 1)} className="flex h-6 w-6 items-center justify-center rounded border text-xs hover:bg-accent">+</button>
</div>
</div>
<div className="text-right">
<div className="font-semibold">${((item.price || 0) * (item.qty || 1)).toFixed(2)}</div>
{onRemove && <button onClick={() => onRemove(item)} className="mt-1 text-xs text-destructive hover:underline">Remove</button>}
</div>
</div>
));
CartItem.displayName = "CartItem";
export { CartItem };
Quick Install
Make sure you have the cn() utility set up. It requires clsx and tailwind-merge.
npm install clsx tailwind-merge