> ## 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 SDK с line transforms и компараторами для скрытия строк, добавленных приложениями, их переименования и управления порядком отображения.

Скрывайте строки, которые покупатель не должен видеть, переименовывайте строки с неудачными названиями и управляйте порядком отображения — всё это не затрагивая фактическое содержимое корзины.

Это заменяет старый приём скрытия элементов корзины через CSS или `style.display = 'none'`. Line transform применяется при каждом рендере корзины, поэтому переживает обновления, повторные рендеры и повторные открытия панели.

<div id="hide-a-line">
  ## Скрыть строку
</div>

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// Hide free lines from the drawer. The cart total is unchanged.
window.aftersell.cart.hooks.registerLineTransform((line) => {
  if (line.finalLinePrice === 0) {
    line.setHidden(true);
  }
});
```

<Warning>
  **Скрытие — это не удаление.** Скрытая строка остаётся в корзине покупателя, остаётся в итоговой сумме и проходит до оформления заказа; она просто не отрисовывается в панели. При этом она исчезает из `getCart().items` и `itemCount`, поэтому ваш собственный код тоже перестаёт её видеть. Если нужно удалить по-настоящему, используйте [`removeItem`](/ru/aftersell/cart/sdk-actions#removeitemkey).
</Warning>

Типичные кандидаты на скрытие:

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.hooks.registerLineTransform((line) => {
  // An app-injected line, tagged with a private property.
  if (line.properties?._bundle_child) {
    line.setHidden(true);
  }

  // A specific SKU that shouldn't be shopper-managed.
  if (line.variantId === HIDDEN_VARIANT_ID) {
    line.setHidden(true);
  }

  // Gift cards issued by a loyalty app.
  if (line.isGiftCard && line.finalLinePrice === 0) {
    line.setHidden(true);
  }
});
```

<div id="relabel-a-line">
  ## Переименовать строку
</div>

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.hooks.registerLineTransform((line) => {
  // Flag discounted lines.
  if (line.finalLinePrice < line.originalLinePrice) {
    line.setTitle(`${line.title} (On sale)`);
  }

  // Make the subscription cadence read naturally.
  if (line.sellingPlan) {
    line.setVariantTitle(`Delivered ${line.sellingPlan.name.toLowerCase()}`);
  }

  // Drop a meaningless variant label.
  if (line.variantTitle === 'Default Title') {
    line.setVariantTitle(null);
  }
});
```

Четыре сеттера, доступные на строке:

| Сеттер                            | Эффект                                                                                                                                                  |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `setHidden(bool)`                 | Скрыть строку из панели.                                                                                                                                |
| `setTitle(string)`                | Изменить отображаемый заголовок.                                                                                                                        |
| `setVariantTitle(string \| null)` | Изменить отображаемую метку варианта. `null` удаляет её.                                                                                                |
| `setInternalProperties(obj)`      | Объединить свойства только для отображения, чтобы их читал блок [Custom code](/ru/aftersell/cart/custom-code-blocks). Никогда не сохраняются в Shopify. |

<div id="control-the-order">
  ## Управление порядком
</div>

Компаратор имеет ту же форму, что ожидает `Array.prototype.sort`, и выполняется после скрытия и переименования:

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// Subscriptions first, then everything else.
window.aftersell.cart.hooks.registerLineComparator((lineA, lineB) => {
  return (lineB.sellingPlan ? 1 : 0) - (lineA.sellingPlan ? 1 : 0);
});
```

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
// Push free gifts and add-ons to the bottom.
window.aftersell.cart.hooks.registerLineComparator((lineA, lineB) => {
  return (lineA.finalLinePrice === 0 ? 1 : 0) - (lineB.finalLinePrice === 0 ? 1 : 0);
});
```

Возвращайте `0` для пар, которые вас не интересуют. Компараторы компонуются как правила разрешения ничьих: первый, вернувший ненулевое значение, решает судьбу этой пары, а возврат `0` передаёт решение следующему, вместо того чтобы навязывать порядок.

<div id="hide-a-whole-block-not-a-line">
  ## Скрыть целый блок, а не строку
</div>

Line transform работает со строками корзины. Чтобы показывать разные настройки **блока** по стране, рынку или валюте (например, разные уровни Rewards), используйте [условия в редакторе корзины](/ru/aftersell/cart/blocks-overview#show-or-hide-by-market-country-or-currency). Код не требуется, и это переживает редизайны корзины. Итоговая сумма и содержимое корзины **не** являются типами условий редактора.

Обращайтесь к SDK, когда ваше правило не выражается условиями (ID товаров в корзине, пользовательская сумма и т. д.). В этом случае выполните запрос к [shadow root](/ru/aftersell/cart/sdk-overview#shadowroot) по публичному классу `cart-external-*`:

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.events.on('cart_updated', (state) => {
  const root = window.aftersell.cart.shadowRoot;
  if (!root) return;

  const rewards = root.querySelector('.cart-external-rewards');
  if (!rewards) return;

  const hasExcluded = state.items.some((line) => EXCLUDED_PRODUCT_IDS.includes(line.productId));
  rewards.style.display = hasExcluded ? 'none' : '';
});
```

<Warning>
  Это выполняется после каждого рендера, поэтому блок может мелькнуть на экране до того, как ваш код его скроет. У условного рендеринга такой проблемы нет, поэтому предпочитайте его везде, где он подходит.
</Warning>

<div id="things-to-get-right">
  ## Что важно сделать правильно
</div>

* **Трансформации — это вызовы настройки.** Регистрируйте их в начале скрипта Initialization; `ready()` не нужен.
* **Выполняются трансформации всех.** Ваша компонуется с зарегистрированными другими приложениями. Вы не можете заменить их трансформации, а они не могут отбросить вашу.
* **Трансформация не может изменить цену, количество или идентичность.** Она меняет только отображение. Для реальных изменений используйте [действия](/ru/aftersell/cart/sdk-actions).
* **Трансформация, выбросившая ошибку, молча пропускается.** Остальные продолжают работать. Проверяйте [`aftersellCartDebugEvents`](/ru/aftersell/cart/sdk-overview#debugging) во время разработки.
* **`registerLineTransform` возвращает функцию отмены регистрации**, если позже понадобится её отменить.

<div id="where-to-go-next">
  ## Что дальше
</div>

* **[Хуки](/ru/aftersell/cart/sdk-hooks)**: полный справочник по хукам.
* **[Объект корзины](/ru/aftersell/cart/sdk-cart-object)**: каждое поле, по которому можно ветвиться.
* **[Custom CSS](/ru/aftersell/cart/custom-css)**: соглашение о классах `cart-external-*`.
