# Cart Item

> Shopping cart item and full cart validation with currency and quantity constraints.

- Name: `cart-item`
- Categories: ecommerce
- Depends on: `@open-types/product`
- Detail page: https://open-types.dev/types/cart-item

## Install

```bash
# Types only
npx shadcn add @open-types/cart-item

# Types + Zod v4 validators
npx shadcn add @open-types/cart-item-zod

# Types + real-world examples
npx shadcn add @open-types/cart-item-examples
```

## Types

```typescript
import type { CurrencyCode } from "./product";

export interface CartItem {
  productId: string;
  name: string;
  quantity: number;
  unitPrice: number;
  currency?: CurrencyCode;
  variant?: string;
  imageUrl?: string;
}

export interface Cart {
  items: CartItem[];
  currency?: CurrencyCode;
}
```

## Zod validator

```typescript
import * as z from "zod";
import type { CartItem, Cart } from "../types/cart-item";
import { currencyCodeSchema } from "./product";

export const cartItemSchema = z.object({
  productId: z.uuid({ error: "Invalid product ID" }),
  name: z.string().min(1, { error: "Item name is required" }),
  quantity: z
    .number()
    .int({ error: "Quantity must be a whole number" })
    .min(1, { error: "Quantity must be at least 1" })
    .max(999, { error: "Quantity must be at most 999" }),
  unitPrice: z
    .number()
    .positive({ error: "Unit price must be positive" })
    .multipleOf(0.01, { error: "Unit price must have at most 2 decimal places" }),
  currency: currencyCodeSchema,
  variant: z.string().optional(),
  imageUrl: z.url({ error: "Image URL must be a valid URL" }).optional(),
}) satisfies z.ZodType<CartItem>;

export const cartSchema = z.object({
  items: z
    .array(cartItemSchema)
    .min(1, { error: "Cart must have at least one item" }),
  currency: currencyCodeSchema,
}) satisfies z.ZodType<Cart>;

export type { CartItem, Cart } from "../types/cart-item";
```

## Examples

```typescript
// Source: hand-crafted
import type { CartItem, Cart } from "../types/cart-item";

const widget = {
  productId: "11111111-2222-4333-8444-555555555551",
  name: "Premium Widget",
  quantity: 2,
  unitPrice: 29.99,
  currency: "USD",
} as const satisfies CartItem;

const ebook = {
  productId: "44444444-4444-4333-8444-555555555554",
  name: "E-Book Bundle",
  quantity: 1,
  unitPrice: 19.99,
  currency: "USD",
  imageUrl: "https://cdn.example.com/products/ebook.png",
} as const satisfies CartItem;

const tShirt = {
  productId: "55555555-5555-4333-8444-555555555555",
  name: "Logo T-Shirt",
  quantity: 3,
  unitPrice: 24.0,
  currency: "USD",
  variant: "size:L,color:black",
  imageUrl: "https://cdn.example.com/products/tshirt-black-l.jpg",
} as const satisfies CartItem;

export const cartItemExamples = {
  basic: widget,
  withVariant: tShirt,
  digital: ebook,
  largeQuantity: { ...widget, quantity: 100 } satisfies CartItem,
} as const;

export const cartExamples = {
  multi: { items: [widget, tShirt, ebook], currency: "USD" } satisfies Cart,
  single: { items: [widget] } satisfies Cart,
  digitalOnly: { items: [ebook], currency: "USD" } satisfies Cart,
} as const;
```
