# CartLines

> Renders cart line items with quantity controls and remove buttons. Subscribes to global cart state.

Canonical URL: https://fa7e86e3d553:3005/islands/cart/cart-lines

> Renders cart line items with quantity controls and remove buttons. Subscribes to global cart state.

The effective Cart V2 profile creates this module. Do not embed it in page
source.

## Preview

**Category**: Commerce (Cart Profiles)

## Props

| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| layout | "compact" \| "full" | No | "compact" | Line item display density |
| size | `"sm" \| "md" \| "lg"` | No | Profile setting | Line-item scale |
| imageAspect | `"square" \| "portrait"` | No | Profile setting | Product-image shape |
| dividers | boolean | No | Profile setting | Show separators between lines |
| showQuantity | boolean | No | true | Show qty +/- controls |
| showRemove | boolean | No | true | Show remove button |
| showImage | boolean | No | true | Show product thumbnail |
| emptyMessage | string | No | "Your cart is empty" | Empty state text |
| emptyCtaText | string | No | "Continue Shopping" | Empty state CTA label |
| emptyCtaUrl | string | No | "/" | Empty state CTA link |
| spacing | `"compact" \| "comfortable" \| "spacious"` | No | Profile setting | Vertical rhythm |
| quantityAnimation | `"none" \| "slide" \| "crossfade" \| "roll"` | No | Profile setting | Quantity feedback |
| buttonFeedback | `"none" \| "press" \| "highlight"` | No | Profile setting | Quantity-button response |
| itemRemovalAnimation | `"none" \| "slide" \| "fade" \| "collapse"` | No | Profile setting | Removal transition |
| showPurchaseOptions | boolean | No | Profile setting | Show selling-plan controls when Shopify provides them |
| purchaseOptionStyle | `"cards" \| "select"` | No | Profile setting | Selling-plan control style |
| quantityStyle | `"stepper" \| "split_buttons" \| "select"` | No | `"stepper"` | Quantity-control presentation |
| removeStyle | `"icon" \| "text"` | No | `"icon"` | Remove-action presentation |
| salePriceStyle | `"inline" \| "stacked"` | No | `"inline"` | Compare-at and sale-price layout |
| showDiscountPercent | boolean | No | false | Show the calculated discount percentage |
| freeGift | object | No | Profile setting | Gift-line variant, badge, icon, original-price visibility, and quantity locking |

## Profile module example

```json
{
  "layout": "compact",
  "size": "md",
  "imageAspect": "square",
  "spacing": "comfortable",
  "showQuantity": true,
  "showRemove": true,
  "quantityAnimation": "roll",
  "buttonFeedback": "press",
  "showPurchaseOptions": true,
  "purchaseOptionStyle": "cards",
  "quantityStyle": "stepper",
  "removeStyle": "text",
  "salePriceStyle": "stacked",
  "showDiscountPercent": true,
  "freeGift": {
    "variant": "gift_card",
    "badgeText": "A gift for you",
    "showOriginalPrice": true,
    "lockQuantity": true
  }
}
```

## Events

| Event | Direction | Payload |
|-------|-----------|---------|
| cart:updated | Emits | `{lines: [{id, quantity, variantId}]}` on quantity change or remove |

## Tips

- Must be inside [DrawerShell](/islands/cart/drawer-shell) (or a future CartPage island)
- Optimistic updates -- items reflect changes immediately, server confirms async
- Remove animates the item out with a 200ms fade transition
- `layout:"compact"` shows small thumbnails + single-line info; `"full"` shows larger images and variant details
- Empty state renders when cart has zero items; customize with `emptyMessage` and `emptyCtaText`

## Stylable Parts

| Part | Description |
|------|-------------|
| `root` | Outermost container |
| `item` | Individual line item row |
| `item-image` | Product thumbnail |
| `item-image-wrap` | Product thumbnail container |
| `item-info` | Title + variant text |
| `item-title`, `item-variant` | Product and selected variant labels |
| `item-price` | Line item price |
| `qty-controls` | Quantity +/- wrapper |
| `qty-decrease`, `qty-value`, `qty-increase` | Quantity controls |
| `remove-btn` | Remove button |
| `empty`, `empty-message`, `empty-cta` | Empty-cart state |
| `fallback` | Runtime fallback message |
| `free-gift-label` | Gift-line badge |
| `purchase-option` | Selling-plan selector |
| `reward-badge`, `reward-qty` | Reward-line state |

```css
/* Example: bordered line items with spacing */
[data-lx-cart-profile] [data-part='item'] {
  border-bottom: 1px solid #e5e7eb;
  padding: 1rem 0;
}
```

## Related Islands

- [DrawerShell](/islands/cart/drawer-shell) -- Required parent container
- [CartSummary](/islands/cart/cart-summary) -- Displays totals based on same cart state
- [CartCheckoutButton](/islands/cart/cart-checkout-button) -- Checkout CTA
- [CartProgressBar](/islands/cart/cart-progress-bar) -- Updates as items are added/removed
