> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aftersell.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Bloc Cart items

> Le bloc Cart items : la liste des lignes d'articles, la ligne Product et l'hôte des sous-blocs imbriqués.

> Le bloc **Cart items** est la liste des lignes d'articles du panier, affichant chaque produit ajouté par l'acheteur avec son image, son titre, sa variante, son prix, son sélecteur de quantité et son contrôle de suppression. C'est un bloc obligatoire, et c'est le conteneur qui héberge les sous-blocs du panier (la ligne **Product**, [**Subscription upgrade**](/fr/aftersell/cart/subscription-upgrade-block) et [**Custom code**](/fr/aftersell/cart/custom-code-blocks)), fournissant la structure à laquelle les sous-blocs par ligne s'attachent.

<Frame>
  <img src="https://mintcdn.com/aftersell/1Y3gBpUfxv16VGSW/images/aftersell/cart-items-block-line-product-title-variant.png?fit=max&auto=format&n=1Y3gBpUfxv16VGSW&q=85&s=3c9f088b55cfd8450dcb8670dfe0728a" alt="Bloc Cart items affichant les lignes d'articles avec image produit, titre, variante, prix, sélecteur de quantité et contrôle de suppression" width="1420" height="486" data-path="images/aftersell/cart-items-block-line-product-title-variant.png" />
</Frame>

<div id="the-product-row">
  ## La ligne Product
</div>

À l'intérieur de Cart items se trouve le sous-bloc **Product** : la véritable ligne d'article. Il est verrouillé et ajouté automatiquement, de sorte que chaque bloc Cart items contient toujours exactement une ligne Product que vous ne pouvez pas supprimer ; vous repositionnez les autres sous-blocs autour d'elle. Ses paramètres contrôlent la façon dont le prix de chaque ligne est affiché :

| Paramètre                                  | Ce qu'il contrôle                                                                                                                                                                                                                                                                                                                                                                               | Par défaut                                      |
| ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
| **Strike-through price**                   | Quel prix est affiché barré : **Compare-at or pre-discount, whichever is higher**, **Compare-at price**, **Pre-discount price** ou **No strike-through**.                                                                                                                                                                                                                                       | Compare-at or pre-discount, whichever is higher |
| **Strike-through price for subscriptions** | Le même choix pour les lignes d'abonnement, avec deux différences : une option supplémentaire **Subscription compare-at price**, et **Compare-at price** renommée **Product compare-at, then subscription compare-at**.                                                                                                                                                                         | Compare-at or pre-discount, whichever is higher |
| **Savings label**                          | Si les économies s'affichent en **Amount**, en **Percentage**, ou sont **Hidden**.                                                                                                                                                                                                                                                                                                              | Amount                                          |
| **Bundle price**                           | Comment le prix affiché est calculé pour les lignes de bundle. **Automatic** affiche le total de tous les articles du bundle (ou le prix de l'article principal lorsque les autres articles sont gratuits). **Main item price only** n'affiche que le prix de l'article principal (d'ancrage). Il s'agit uniquement d'un libellé d'affichage — le total du panier de Shopify fait toujours foi. | Automatic                                       |
| **Savings text**                           | Le libellé des économies. Prend en charge le jeton `{{value}}`.                                                                                                                                                                                                                                                                                                                                 | `Save {{value}}`                                |

La ligne elle-même affiche l'image du produit (avec un lien vers la page produit lorsqu'elle est disponible), le titre, la variante, le prix et tout prix comparé barré, un sélecteur de quantité et un bouton de suppression. Les lignes de bundle affichent une liste dépliable de leurs composants.

<div id="text-styling">
  ### Style du texte
</div>

La ligne Product comprend une section **Text** dans ses paramètres Design. Utilisez-la pour contrôler la typographie de chaque élément de texte dans chaque ligne d'article. Sélectionnez un élément de texte dans le sélecteur pour ajuster ses paramètres :

| Paramètre          | Ce qu'il contrôle                                                                                                                                                                  |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Text color**     | Couleur de l'élément de texte sélectionné.                                                                                                                                         |
| **Font**           | **Theme font** (hérite de la police de votre thème) ou **Custom font** (saisissez le nom d'une police déjà chargée par votre thème). Disponible pour **Product title** uniquement. |
| **Size**           | Taille de la police en pixels.                                                                                                                                                     |
| **Weight**         | Graisse de la police : Light, Regular, Medium, Semibold ou Bold.                                                                                                                   |
| **Line height**    | Interligne exprimé en multiplicateur de la taille de la police (par exemple, `1.4`).                                                                                               |
| **Letter spacing** | Espacement des lettres en pixels. Les valeurs négatives resserrent le texte.                                                                                                       |

Les éléments de texte que vous pouvez styliser sont regroupés par catégorie :

**Product**

* **Product title** — le nom du produit sur chaque ligne. Prend également en charge une famille de police personnalisée.
* **Variant** — le libellé de la variante (par exemple, *Size: Medium*).
* **Subscription plan** — le libellé de plan en lecture seule affiché sur les lignes d'abonnement.

**Pricing**

* **Price** — le prix actuel de la ligne.
* **Compare-at price** — le prix d'origine barré.
* **Savings** — le libellé des économies (par exemple, *Save \$5.00*). Uniquement la taille et l'interligne — le gras et la couleur sont définis dans l'éditeur de texte enrichi ci-dessus.

**Bundle**

* **Bundle toggle** — l'en-tête dépliable qui déploie la liste des composants d'un bundle.
* **Bundle item title** — le titre de chaque composant à l'intérieur d'un bundle.
* **Bundle item variant** — le libellé de variante pour chaque composant de bundle.

Laisser un champ vide conserve la valeur par défaut de l'élément.

<Tip>
  Cliquer directement sur un élément de texte dans l'aperçu du panier le met en surbrillance et ouvre automatiquement ses contrôles dans le panneau.
</Tip>

<div id="discount-tags-design">
  ### Design des étiquettes de remise
</div>

La ligne Product comprend une section **Discount tags** dans ses paramètres Design. Utilisez-la pour styliser les pastilles d'étiquettes de remise qui apparaissent sur chaque ligne d'article :

| Paramètre            | Ce qu'il contrôle                                                    | Par défaut |
| -------------------- | -------------------------------------------------------------------- | ---------- |
| **Background color** | Couleur de remplissage de la pastille d'étiquette de remise.         | `#F1F1F1`  |
| **Text color**       | Couleur du texte à l'intérieur de la pastille d'étiquette de remise. | `#585858`  |
| **Border radius**    | Arrondi des coins de la pastille d'étiquette de remise.              | `6px`      |

Ces paramètres s'appliquent uniquement aux étiquettes de remise des lignes d'articles dans le bloc Cart items. Les étiquettes de codes de réduction du [bloc Summary](/fr/aftersell/cart/summary-block) sont stylisées séparément.

<div id="sub-blocks-and-how-they-position">
  ## Les sous-blocs et leur positionnement
</div>

Cart items est le seul bloc qui héberge des sous-blocs. **Les sous-blocs s'affichent une fois par ligne, à l'intérieur de chaque ligne de produit**, positionnés par rapport à la ligne Product épinglée :

* Les sous-blocs ordonnés **avant** la ligne Product apparaissent **au-dessus** du contenu produit dans chaque ligne.
* Les sous-blocs ordonnés **après** la ligne Product apparaissent **en dessous** du contenu produit dans chaque ligne.

Ainsi, un [Subscription upgrade](/fr/aftersell/cart/subscription-upgrade-block) placé après la ligne Product s'affiche sous chaque ligne éligible, et non une seule fois en bas de toute la liste.

<div id="behavior">
  ## Comportement
</div>

* Lorsque le panier ne contient aucun article, le tiroir bascule vers l'état vide et ce bloc n'est pas affiché.
* **Une seule modification du panier s'exécute à la fois.** Pendant qu'une mise à jour de quantité ou une suppression est en cours, les contrôles de la ligne sont désactivés pour garder le panier cohérent, puis réactivés une fois la modification effectuée.
* Faire passer la quantité d'une ligne sous 1 la supprime. Une quantité rejetée par la boutique (par exemple, au-delà du stock disponible) se resynchronise sur la dernière valeur valide.
* **Les bundles changent d'un bloc.** Ajuster la quantité sur la ligne d'ancrage d'un bundle met à l'échelle tout le bundle en une seule opération — si un composant est inclus à raison de 3 par ancre, faire passer l'ancre de 1 à 2 fait passer ce composant à 6. Supprimer l'ancre supprime tous les membres du bundle en une fois.
* **Certains bundles ne peuvent pas être requantifiés.** Si l'un des composants d'un bundle est inclus à un taux fractionnaire (1,5 par ancre, par exemple), le sélecteur de quantité de ce bundle est verrouillé : les boutons +/− et le champ de quantité sont tous deux désactivés, et les quantités saisies ne sont pas acceptées. Le bundle peut toujours être supprimé.
* **Les lignes d'abonnement affichent leur plan.** Lorsqu'une ligne a un plan de vente et que le sous-bloc [Subscription upgrade](/fr/aftersell/cart/subscription-upgrade-block) est désactivé ou non ajouté, la ligne Product affiche un libellé de plan en lecture seule sous la variante — par exemple, *Delivers every month (save 30%)*. Lorsque ce sous-bloc est activé, il présente le plan dans son propre sélecteur, de sorte que le libellé en lecture seule est supprimé plutôt que dupliqué.

<div id="placement-and-limits">
  ## Placement et limites
</div>

* **Région :** corps.
* **Maximum :** 1 par état de panier.
* **État :** panier rempli uniquement.
* **Verrouillé et ajouté par défaut.** Cart items ne peut être ni supprimé ni masqué, seulement repositionné.

<div id="custom-template">
  ## Modèle personnalisé
</div>

Prend en charge un [modèle personnalisé](/fr/aftersell/cart/custom-templates) depuis son onglet Code, qui remplace le rendu intégré de ce bloc par votre JSX. Voici les props qu'il reçoit.

Le conteneur **Cart items** n'a pas de modèle personnalisé. La ligne **Product** à l'intérieur en a un, et c'est la surface la plus riche du panier : votre modèle s'affiche une fois par ligne.

<div id="line-content">
  ### Contenu de la ligne
</div>

| Prop               | Type                        | À quoi elle sert                                                                                                                                                                                                                                     |
| ------------------ | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `title`            | `string`                    | Titre du produit, en texte brut.                                                                                                                                                                                                                     |
| `variantTitle`     | `string \| null`            | Libellé de la variante. `null` pour les produits à variante unique et les bundles natifs.                                                                                                                                                            |
| `url`              | `string \| null`            | URL de la page produit. `null` lorsque la ligne ne doit pas comporter de lien.                                                                                                                                                                       |
| `imageUrl`         | `string \| null`            | Image de la ligne. `null` lorsque le produit n'en a pas.                                                                                                                                                                                             |
| `quantity`         | `number`                    | Quantité actuelle sur la ligne.                                                                                                                                                                                                                      |
| `price`            | `string`                    | Prix de la ligne, **déjà formaté**.                                                                                                                                                                                                                  |
| `compareAtPrice`   | `string \| null`            | Le prix « avant » barré, déjà formaté. `null` lorsqu'il n'y a rien à barrer.                                                                                                                                                                         |
| `savingsHtml`      | `string \| null`            | Libellé des économies en HTML assaini. `null` lorsqu'il est masqué ou qu'il n'y a pas d'économie.                                                                                                                                                    |
| `discountTags`     | `string[]`                  | Titres des remises sur cette ligne, par ex. `['Spring Sale']`. `[]` lorsqu'il n'y en a aucune.                                                                                                                                                       |
| `sellingPlanLabel` | `string \| null`            | Nom du plan d'abonnement en lecture seule. `null` lorsqu'il s'agit d'une ligne d'achat unique, ou lorsque le sous-bloc [Subscription upgrade](/fr/aftersell/cart/subscription-upgrade-block#custom-template) affiche l'interface du plan à la place. |
| `bundle`           | `object \| null`            | Modèle de vue de [bundle](/fr/aftersell/cart/sdk-cart-object#bundles) sur une ligne d'ancrage. `null` sinon.                                                                                                                                         |
| `productId`        | `number`                    | ID produit Shopify.                                                                                                                                                                                                                                  |
| `variantId`        | `number`                    | ID de variante Shopify.                                                                                                                                                                                                                              |
| `line`             | `AftersellCartLine`         | La [ligne de panier](/fr/aftersell/cart/sdk-cart-object#cart-lines) complète, pour tout ce que les props ci-dessus ne couvrent pas.                                                                                                                  |
| `formatMoney`      | `(cents: number) => string` | Formate un montant en unité mineure. Utilisez-le pour les prix que vous lisez sur `line`.                                                                                                                                                            |

<Warning>
  **`price` et `compareAtPrice` sont des chaînes formatées ; tout sur `line` est en centimes.** Ne faites pas de calculs sur `price`. Calculez à partir de `line.finalLinePrice` et compagnie, puis passez le résultat dans `formatMoney`.
</Warning>

<div id="quantity-and-removal">
  ### Quantité et suppression
</div>

| Prop                | Type                                             | À quoi elle sert                                                                                                                                                                                                                                                              |
| ------------------- | ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `increment`         | `() => void`                                     | Ajoute un à la ligne.                                                                                                                                                                                                                                                         |
| `decrement`         | `() => void`                                     | Retire un de la ligne.                                                                                                                                                                                                                                                        |
| `remove`            | `() => void`                                     | Supprime entièrement la ligne.                                                                                                                                                                                                                                                |
| `quantityInput`     | `string`                                         | Valeur actuelle pour un `<input>` de quantité contrôlé. Une chaîne, afin que les états de saisie en cours survivent.                                                                                                                                                          |
| `onQuantityInput`   | `(event: Event) => void`                         | Gestionnaire `onInput` pour ce champ.                                                                                                                                                                                                                                         |
| `commitQuantity`    | `() => void`                                     | Applique la quantité saisie. À relier à `onBlur`.                                                                                                                                                                                                                             |
| `onQuantityKeyDown` | `(event: KeyboardEvent) => void`                 | Gestionnaire `onKeyDown`, afin qu'Entrée valide.                                                                                                                                                                                                                              |
| `busy`              | `boolean`                                        | `true` pendant qu'une mutation du panier est en cours. Désactivez vos contrôles en fonction de cela.                                                                                                                                                                          |
| `pending`           | `'increment' \| 'decrement' \| 'remove' \| null` | L'action actuellement en cours, pour un indicateur de chargement ciblé.                                                                                                                                                                                                       |
| `stepperLocked`     | `boolean`                                        | `true` lorsque la quantité ne peut pas être modifiée, car la ligne est une ancre de bundle avec un composant inclus à un taux fractionnaire par ancre. Masquez ou désactivez le sélecteur — les gestionnaires intégrés rejettent déjà les modifications tant qu'il est actif. |

```jsx theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
function CustomTemplate(props) {
  return (
    <div className="cart-external-cart-items__row" style={{ display: 'flex', gap: '12px', opacity: props.busy ? 0.6 : 1 }}>
      {props.imageUrl && <img src={props.imageUrl} alt="" width={64} height={64} />}

      <div style={{ flex: 1 }}>
        {props.url ? <a href={props.url}>{props.title}</a> : <span>{props.title}</span>}
        {props.variantTitle && <div style={{ opacity: 0.6 }}>{props.variantTitle}</div>}
        {props.sellingPlanLabel && <div style={{ opacity: 0.6 }}>{props.sellingPlanLabel}</div>}

        {props.discountTags.map((tag) => (
          <span key={tag} style={{ fontSize: '11px', border: '1px solid', borderRadius: '4px', padding: '1px 5px' }}>
            {tag}
          </span>
        ))}

        {!props.stepperLocked && (
          <div style={{ display: 'flex', alignItems: 'center', gap: '6px', marginTop: '6px' }}>
            <button type="button" onClick={props.decrement} disabled={props.busy}>&minus;</button>
            <input
              value={props.quantityInput}
              onInput={props.onQuantityInput}
              onBlur={props.commitQuantity}
              onKeyDown={props.onQuantityKeyDown}
              size={2}
            />
            <button type="button" onClick={props.increment} disabled={props.busy}>+</button>
            <button type="button" onClick={props.remove} disabled={props.busy}>
              {props.pending === 'remove' ? 'Removing…' : 'Remove'}
            </button>
          </div>
        )}
      </div>

      <div style={{ textAlign: 'right' }}>
        <div>{props.price}</div>
        {props.compareAtPrice && <s style={{ opacity: 0.5 }}>{props.compareAtPrice}</s>}
        {props.savingsHtml && <div dangerouslySetInnerHTML={{ __html: props.savingsHtml }} />}
      </div>
    </div>
  );
}
```

<div id="rendering-a-bundle">
  ### Afficher un bundle
</div>

Sur la ligne d'ancrage d'un bundle, `bundle.children` contient son contenu. Les composants n'apparaissent jamais comme des lignes à part entière, donc si vous ne les affichez pas, l'acheteur ne verra pas ce que contient le bundle :

```jsx theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
function CustomTemplate(props) {
  return (
    <div>
      <div>{props.title} {props.price}</div>

      {props.bundle && (
        <ul style={{ margin: '4px 0 0 12px', fontSize: '12px', opacity: 0.7 }}>
          {props.bundle.children.map((child, i) => (
            <li key={child.key ?? i}>{child.quantity} × {child.title}</li>
          ))}
        </ul>
      )}
    </div>
  );
}
```

La `key` d'un composant est `null` pour un composant de bundle natif Shopify, alors utilisez l'index en repli comme ci-dessus.

<div id="design">
  ## Design
</div>

Stylisez ce bloc avec sa section **Design** dans le panneau de paramètres. Il s'agit de remplacements par bloc qui se superposent à votre design global et y reviennent lorsqu'ils sont vides.

Que sont les paramètres de design ? En savoir plus ici : [Paramètres de design](/fr/aftersell/cart/design-settings).
