> ## 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.

# بلوك عناصر السلة

> بلوك Cart items: قائمة عناصر الطلب، وصف Product، والمستضيف للبلوكات الفرعية المتداخلة.

> بلوك **Cart items** هو قائمة عناصر الطلب في السلة، ويعرض كل منتج أضافه المتسوق مع صورته وعنوانه ونسخته وسعره ومنتقي الكمية وزر الإزالة. وهو بلوك إلزامي، وهو الحاوية التي تستضيف البلوكات الفرعية للسلة (صف **Product**، و[**Subscription upgrade**](/ar/aftersell/cart/subscription-upgrade-block)، و[**Custom code**](/ar/aftersell/cart/custom-code-blocks))، موفرًا البنية التي تلتصق بها البلوكات الفرعية لكل سطر.

<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="بلوك عناصر السلة يعرض عناصر الطلب مع صورة المنتج والعنوان والنسخة والسعر ومنتقي الكمية وزر الإزالة" width="1420" height="486" data-path="images/aftersell/cart-items-block-line-product-title-variant.png" />
</Frame>

<div id="the-product-row">
  ## صف Product
</div>

داخل Cart items يوجد البلوك الفرعي **Product**: صف عنصر الطلب الفعلي. وهو مقفل ويُضاف تلقائيًا، لذا فإن كل بلوك Cart items يحتوي دائمًا على صف Product واحد بالضبط لا يمكنك إزالته؛ وإنما تعيد ترتيب البلوكات الفرعية الأخرى حوله. تتحكم إعداداته في كيفية عرض تسعير كل سطر:

| الإعداد                                    | ما الذي يتحكم فيه                                                                                                                                                                                                                                                   | القيمة الافتراضية                               |
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
| **Strike-through price**                   | السعر الذي يُعرض مشطوبًا: **Compare-at or pre-discount, whichever is higher** أو **Compare-at price** أو **Pre-discount price** أو **No strike-through**.                                                                                                           | Compare-at or pre-discount, whichever is higher |
| **Strike-through price for subscriptions** | الخيار نفسه لأسطر الاشتراكات، مع فرقين: خيار إضافي **Subscription compare-at price**، وإعادة تسمية **Compare-at price** إلى **Product compare-at, then subscription compare-at**.                                                                                   | Compare-at or pre-discount, whichever is higher |
| **Savings label**                          | ما إذا كان التوفير يُعرض كـ **Amount** أو **Percentage** أو **Hidden**.                                                                                                                                                                                             | Amount                                          |
| **Bundle price**                           | كيفية حساب السعر المعروض لأسطر الحزم. يعرض **Automatic** إجمالي جميع عناصر الحزمة (أو سعر العنصر الرئيسي عندما تكون العناصر الأخرى مجانية). يعرض **Main item price only** سعر العنصر الرئيسي (المرجعي) فقط. هذا مجرد وسم عرض — إجمالي سلة Shopify هو المرجع دائمًا. | Automatic                                       |
| **Savings text**                           | نص التوفير. يدعم الرمز `{{value}}`.                                                                                                                                                                                                                                 | `Save {{value}}`                                |

يعرض الصف نفسه صورة المنتج (مع رابط إلى صفحة المنتج عند توفرها)، والعنوان، والنسخة، والسعر وأي سعر مقارنة مشطوب، ومنتقي كمية، وزر إزالة. تعرض أسطر الحزم قائمة قابلة للفتح بمكوناتها.

<div id="text-styling">
  ### تنسيق النصوص
</div>

يتضمن صف Product قسم **Text** في إعدادات التصميم الخاصة به. استخدمه للتحكم في طباعة عناصر النص الفردية في كل عنصر طلب. اختر عنصر نص من المنتقي لضبط إعداداته:

| الإعداد            | ما الذي يتحكم فيه                                                                                                      |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------- |
| **Text color**     | لون عنصر النص المحدد.                                                                                                  |
| **Font**           | **Theme font** (يرث خط قالبك) أو **Custom font** (أدخل اسم خط يُحمّله قالبك مسبقًا). متاح لعنصر **Product title** فقط. |
| **Size**           | حجم الخط بالبكسل.                                                                                                      |
| **Weight**         | ثقل الخط: Light أو Regular أو Medium أو Semibold أو Bold.                                                              |
| **Line height**    | ارتفاع السطر كمضاعف لحجم الخط (مثال: `1.4`).                                                                           |
| **Letter spacing** | تباعد الحروف بالبكسل. القيم السالبة تضيّق النص.                                                                        |

عناصر النص التي يمكنك تنسيقها مقسّمة حسب الفئة:

**Product**

* **Product title** — اسم المنتج في كل سطر. يدعم أيضًا عائلة خط مخصصة.
* **Variant** — تسمية النسخة (مثال: *Size: Medium*).
* **Subscription plan** — تسمية الخطة للقراءة فقط المعروضة على أسطر الاشتراكات.

**Pricing**

* **Price** — السعر الحالي للسطر.
* **Compare-at price** — السعر الأصلي المشطوب.
* **Savings** — تسمية التوفير (مثال: *Save \$5.00*). الحجم وارتفاع السطر فقط — أما الخط الغامق واللون فيُضبطان في محرر النص المنسق أعلاه.

**Bundle**

* **Bundle toggle** — رأس القسم القابل للفتح الذي يوسّع قائمة مكوّنات الحزمة.
* **Bundle item title** — عنوان كل مكوّن داخل الحزمة.
* **Bundle item variant** — تسمية النسخة لكل مكوّن حزمة.

ترك أي حقل فارغًا يُبقي القيمة الافتراضية للعنصر.

<Tip>
  النقر على عنصر نص مباشرة في معاينة السلة يبرزه ويفتح عناصر التحكم به في اللوحة تلقائيًا.
</Tip>

<div id="discount-tags-design">
  ### تصميم وسوم الخصم
</div>

يتضمن صف Product قسم **Discount tags** في إعدادات التصميم الخاصة به. استخدمه لتنسيق حبّات وسوم الخصم التي تظهر على كل عنصر:

| الإعداد              | ما الذي يتحكم فيه             | القيمة الافتراضية |
| -------------------- | ----------------------------- | ----------------- |
| **Background color** | لون تعبئة حبّة وسم الخصم.     | `#F1F1F1`         |
| **Text color**       | لون النص داخل حبّة وسم الخصم. | `#585858`         |
| **Border radius**    | استدارة زوايا حبّة وسم الخصم. | `6px`             |

تنطبق هذه الإعدادات فقط على وسوم خصم عناصر الطلب في بلوك Cart items. أما وسوم رموز الخصم في [بلوك Summary](/ar/aftersell/cart/summary-block) فتُنسَّق بشكل منفصل.

<div id="sub-blocks-and-how-they-position">
  ## البلوكات الفرعية وكيفية تموضعها
</div>

Cart items هو البلوك الوحيد الذي يستضيف بلوكات فرعية. **تُعرض البلوكات الفرعية مرة لكل سطر، داخل كل صف منتج**، متموضعة نسبةً إلى صف Product المثبّت:

* البلوكات الفرعية المرتبة **قبل** صف Product تظهر **فوق** محتوى المنتج في كل سطر.
* البلوكات الفرعية المرتبة **بعد** صف Product تظهر **تحت** محتوى المنتج في كل سطر.

لذا فإن [Subscription upgrade](/ar/aftersell/cart/subscription-upgrade-block) الموضوع بعد صف Product يظهر أسفل كل سطر مؤهل، وليس مرة واحدة في أسفل القائمة بأكملها.

<div id="behavior">
  ## السلوك
</div>

* عندما لا تحتوي السلة على عناصر، يتحول الدرج إلى الحالة الفارغة ولا يُعرض هذا البلوك.
* **تغيير واحد للسلة يعمل في كل مرة.** أثناء تنفيذ تحديث كمية أو إزالة، تُعطَّل عناصر تحكم الصف للحفاظ على اتساق السلة، ثم يُعاد تفعيلها بمجرد استقرار التغيير.
* خفض كمية سطر إلى أقل من 1 يزيله. الكمية التي يرفضها المتجر (مثلًا، تجاوز المخزون المتاح) تُعاد مزامنتها إلى آخر قيمة صالحة.
* **الحزم تتغير كوحدة واحدة.** تعديل الكمية على السطر المرجعي للحزمة يوسّع الحزمة بأكملها في عملية واحدة — إذا كان عنصر تابع مُضمّنًا بمعدل 3 لكل عنصر مرجعي، فإن رفع العنصر المرجعي من 1 إلى 2 يرفع ذلك التابع إلى 6. إزالة العنصر المرجعي تزيل جميع أعضاء الحزمة دفعة واحدة.
* **بعض الحزم لا يمكن تغيير كميتها.** إذا كان أي من عناصر الحزمة التابعة مُضمّنًا بمعدل كسري (1.5 لكل عنصر مرجعي مثلًا)، فإن منتقي الكمية على تلك الحزمة يُقفل: يُعطَّل زرا +/− وحقل الكمية معًا، ولا تُقبل الكميات المكتوبة. لا يزال بالإمكان إزالة الحزمة.
* **أسطر الاشتراكات تعرض خطتها.** عندما يحمل سطر خطة بيع ويكون البلوك الفرعي [Subscription upgrade](/ar/aftersell/cart/subscription-upgrade-block) معطلًا أو غير مضاف، يعرض صف Product تسمية خطة للقراءة فقط أسفل النسخة — مثل *Delivers every month (save 30%)*. وعند تفعيل ذلك البلوك الفرعي يعرض الخطة في منتقيه الخاص، فتُحجب التسمية للقراءة فقط بدلًا من تكرارها.

<div id="placement-and-limits">
  ## الموضع والحدود
</div>

* **المنطقة:** الوسط (body).
* **الحد الأقصى:** 1 لكل حالة سلة.
* **الحالة:** السلة الممتلئة فقط.
* **مقفل ومضاف افتراضيًا.** لا يمكن إزالة Cart items أو إخفاؤه، بل فقط إعادة تموضعه.

<div id="custom-template">
  ## القالب المخصص
</div>

يدعم [قالبًا مخصصًا](/ar/aftersell/cart/custom-templates) من علامة تبويب Code الخاصة به، والذي يستبدل ترميز هذا البلوك المدمج بكود JSX الخاص بك. هذه هي الخصائص (props) التي يستقبلها.

حاوية **Cart items** لا قالب مخصص لها. أما صف **Product** داخلها فله واحد، وهو أغنى واجهة في السلة: يُعرض قالبك مرة لكل سطر.

<div id="line-content">
  ### محتوى السطر
</div>

| الخاصية            | النوع                       | الغرض منها                                                                                                                                                                                                       |
| ------------------ | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `title`            | `string`                    | عنوان المنتج، كنص عادي.                                                                                                                                                                                          |
| `variantTitle`     | `string \| null`            | تسمية النسخة. `null` للمنتجات أحادية النسخة والحزم الأصلية.                                                                                                                                                      |
| `url`              | `string \| null`            | رابط صفحة المنتج. `null` عندما لا ينبغي للسطر أن يرتبط بصفحة خارجية.                                                                                                                                             |
| `imageUrl`         | `string \| null`            | صورة السطر. `null` عندما لا توجد للمنتج صورة.                                                                                                                                                                    |
| `quantity`         | `number`                    | الكمية الحالية في السطر.                                                                                                                                                                                         |
| `price`            | `string`                    | سعر السطر، **منسّق مسبقًا**.                                                                                                                                                                                     |
| `compareAtPrice`   | `string \| null`            | السعر "السابق" المشطوب، منسّق مسبقًا. `null` عندما لا يوجد ما يُشطب.                                                                                                                                             |
| `savingsHtml`      | `string \| null`            | نص التوفير بصيغة HTML منقّاة. `null` عند إخفائه أو عدم وجود توفير.                                                                                                                                               |
| `discountTags`     | `string[]`                  | عناوين الخصومات على هذا السطر، مثل `['Spring Sale']`. `[]` عند عدم وجودها.                                                                                                                                       |
| `sellingPlanLabel` | `string \| null`            | اسم خطة الاشتراك للقراءة فقط. `null` عندما يكون السطر شراءً لمرة واحدة، أو عندما يعرض البلوك الفرعي [Subscription upgrade](/ar/aftersell/cart/subscription-upgrade-block#custom-template) واجهة الخطة بدلًا منه. |
| `bundle`           | `object \| null`            | نموذج عرض [الحزمة](/ar/aftersell/cart/sdk-cart-object#bundles) على السطر المرجعي. `null` في ما عدا ذلك.                                                                                                          |
| `productId`        | `number`                    | معرّف منتج Shopify.                                                                                                                                                                                              |
| `variantId`        | `number`                    | معرّف نسخة Shopify.                                                                                                                                                                                              |
| `line`             | `AftersellCartLine`         | [سطر السلة](/ar/aftersell/cart/sdk-cart-object#cart-lines) الكامل، لكل ما لا تغطيه الخصائص أعلاه.                                                                                                                |
| `formatMoney`      | `(cents: number) => string` | ينسّق مبلغًا بالوحدة الصغرى. استخدمه للأسعار التي تقرأها من `line`.                                                                                                                                              |

<Warning>
  **`price` و`compareAtPrice` سلسلتان نصيتان منسّقتان؛ وكل شيء في `line` بالسنتات.** لا تُجرِ حسابات على `price`. احسب من `line.finalLinePrice` وأشباهه، ثم مرّر الناتج عبر `formatMoney`.
</Warning>

<div id="quantity-and-removal">
  ### الكمية والإزالة
</div>

| الخاصية             | النوع                                            | الغرض منها                                                                                                                                                                  |
| ------------------- | ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `increment`         | `() => void`                                     | يضيف واحدًا إلى السطر.                                                                                                                                                      |
| `decrement`         | `() => void`                                     | يزيل واحدًا من السطر.                                                                                                                                                       |
| `remove`            | `() => void`                                     | يزيل السطر بالكامل.                                                                                                                                                         |
| `quantityInput`     | `string`                                         | القيمة الحالية لحقل كمية `<input>` مُتحكَّم به. سلسلة نصية، لتبقى حالات الكتابة الجزئية سليمة.                                                                              |
| `onQuantityInput`   | `(event: Event) => void`                         | معالج `onInput` لذلك الحقل.                                                                                                                                                 |
| `commitQuantity`    | `() => void`                                     | يطبّق الكمية المكتوبة. اربطه بـ `onBlur`.                                                                                                                                   |
| `onQuantityKeyDown` | `(event: KeyboardEvent) => void`                 | معالج `onKeyDown`، ليطبّق Enter القيمة.                                                                                                                                     |
| `busy`              | `boolean`                                        | تكون `true` أثناء تنفيذ أي تعديل على السلة. عطّل عناصر التحكم لديك بناءً عليها.                                                                                             |
| `pending`           | `'increment' \| 'decrement' \| 'remove' \| null` | الإجراء الجاري تنفيذه حاليًا، لعرض مؤشر تحميل موجّه.                                                                                                                        |
| `stepperLocked`     | `boolean`                                        | تكون `true` عندما لا يمكن تغيير الكمية، لأن السطر مرجع حزمة فيها عنصر تابع مُضمّن بمعدل كسري. أخفِ المنتقي أو عطّله — المعالجات المدمجة ترفض التغييرات أصلًا أثناء تفعيلها. |

```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">
  ### عرض حزمة
</div>

على السطر المرجعي للحزمة، تحمل `bundle.children` محتوياتها. لا تظهر العناصر التابعة أبدًا كصفوف خاصة بها، لذا إذا لم تعرضها فلن يرى المتسوق ما بداخل الحزمة:

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

قيمة `key` للعنصر التابع تكون `null` لمكوّن حزمة Shopify الأصلية، لذا استخدم الفهرس بديلًا كما في المثال أعلاه.

<div id="design">
  ## التصميم
</div>

نسّق هذا البلوك من قسم **Design** الخاص به في لوحة الإعدادات. هذه تجاوزات على مستوى البلوك تُطبَّق فوق تصميمك العام وتعود إليه عند تركها فارغة.

ما هي إعدادات التصميم؟ اعرف المزيد هنا: [إعدادات التصميم](/ar/aftersell/cart/design-settings).
