ItemContent

ItemContent — каноничная разметка основного контента item’а: заголовок (label), мета справа (caption), подпись снизу (description). Используется как значение поля item.content, а также экспортируется отдельно для кастомного рендеринга внутри contentRender.

Когда использовать

  • Всегда, когда элемент списка можно описать как «заголовок + мета-подпись + короткое описание».
  • Когда нужен одинаковый truncate-алгоритм во всех списках пакета.
  • Когда content задаётся как объект в items — ровно это и есть ItemContent под капотом.

Когда не нужен:

  • Совсем кастомный layout внутри item — передавайте в content свой ReactNode, но тогда единый visual-signal и truncate ложатся на вас.
  • Элемент с одной иконкой без текста — передавайте beforeContent / afterContent и оставьте content пустым.

Анатомия

Slots

  • label (required) — заголовок item’а (имя файла, название валюты, email-адрес).
  • caption — короткая мета справа (счётчик, дата, badge, shortcut).
  • description — подпись под заголовком (хвост описания, короткая справка, секундный статус).

Вне ItemContent, но рядом (поля item’а):

  • beforeContent — иконка / аватар слева.
  • afterContent — слот справа: чеврон / trailing-иконка в иконочном квадрате; произвольный контент (счётчик, badge, tag) рендерится в натуральном размере без обрезки.
  • switch: true — заменяет чекбокс/маркер на Switch справа; состояние тумблера берётся из selection. Для списков-настроек, где выбор = включение функции. showSwitchIcon зарезервирован под иконку тумблера.

Group variant

У групповых item’ов (type: 'group' / 'group-select') заголовок оформляется ItemContent-независимо, через groupVariant:

  • subtitle — контрастный подзаголовок секции.
  • subtitleTertiary (default) — приглушённый третичный текст.

Truncate

  • Дефолт: label — 1 строка, description — 2 строки, вариант обрезки — end (многоточие в конце).
  • Переопределяется через truncate.label, truncate.description, truncate.variant (end / middle).

Установка

ItemContent поставляется вместе с @cloud-ru/ds-list:

import { ItemContent } from '@cloud-ru/ds-list'

Примеры использования

99% случаев — content передаётся как объект, компонент сам строит <ItemContent /> под капотом:

content как объект

content как объектitem.content = { label, caption, description } — List оборачивает в ItemContent сам.
tsx
import { List } from '@cloud-ru/ds-list';

import styles from './styles.module.scss';

export function BasicList() {
  return (
    <div className={styles.box}>
      <List
        size='s'
        items={[
          { id: 'inbox', content: { label: 'Входящие', caption: '12' } },
          { id: 'sent', content: { label: 'Отправленные' } },
          { id: 'archive', content: { label: 'Архив', caption: '238' } },
          { id: 'trash', content: { label: 'Корзина', description: 'Удаляется через 30 дней' } },
        ]}
      />
    </div>
  );
}

Слоты beforeContent / afterContent

Слоты beforeContent / afterContentИконка слева, caption-счётчик справа от заголовка и trailing-иконка в afterContent.
tsx
import { FileSVG, FolderSVG, StarSVG } from '@cloud-ru/ds-icons/interface/system';
import { List } from '@cloud-ru/ds-list';

import styles from './styles.module.scss';

export function ItemContentSlots() {
  return (
    <div className={styles.box}>
      <List
        size='m'
        items={[
          {
            id: 'reports',
            beforeContent: <FolderSVG />,
            content: { label: 'Отчёты', caption: '24' },
            afterContent: <StarSVG />,
          },
          {
            id: 'invoice',
            beforeContent: <FileSVG />,
            content: { label: 'invoice-2024.pdf', caption: '1.2 МБ' },
          },
        ]}
      />
    </div>
  );
}

Заголовок, caption и description вместе

Заголовок, caption и description вместеlabel + caption (мета справа) + description (подпись снизу) в одном item.
tsx
import { List } from '@cloud-ru/ds-list';

import styles from './styles.module.scss';

export function ItemContentDescription() {
  return (
    <div className={styles.box}>
      <List
        size='l'
        items={[
          {
            id: 'eu-west',
            content: {
              label: 'eu-west-1',
              caption: 'Доступно',
              description: 'Ирландия — основной регион размещения',
            },
          },
          {
            id: 'us-east',
            content: {
              label: 'us-east-1',
              caption: 'Деградация',
              description: 'Северная Виргиния — повышенная задержка отклика',
            },
          },
        ]}
      />
    </div>
  );
}

Обрезка текста (truncate)

Обрезка текста (truncate)truncate.label/description задают число строк, variant — место многоточия (end/middle). В узком контейнере длинный текст обрезается.
tsx
import { List } from '@cloud-ru/ds-list';

import styles from './styles.module.scss';

export function ItemContentTruncate() {
  return (
    <div className={styles.narrowBox}>
      <List
        size='m'
        items={[
          {
            id: 'truncated',
            content: {
              label: 'very-long-instance-name-that-overflows.example.internal',
              caption: '8',
              description:
                'Длинное описание ресурса, которое не помещается в одну строку и обрезается по заданному числу строк',
              truncate: { label: 1, description: 2, variant: 'middle' },
            },
          },
        ]}
      />
    </div>
  );
}

Если нужен кастомный слот (бейдж, превью, аватар) поверх стандартной разметки — используйте contentRender на List. Внутри возвращайте <ItemContent {...props} /> плюс свои дополнения. Это сохраняет типографику и truncate.

Доступность

  • label остаётся текстовым заголовком — ассистивные технологии прочитают его как основное имя элемента.
  • caption и description находятся в том же DOM-узле и читаются следом за заголовком.
  • Визуальные truncate-поведения реализованы через CSS -webkit-line-clamp, текст не вырезается из DOM и остаётся доступен скринридеру целиком.
  • Disabled-элементы получают уменьшенный контраст + data-disabled, но цвет не единственный сигнал: интерактивность выключается и на уровне родительского item’а.

Props

Types

PropsItemContentProps
PropTypeDefaultRequiredDescription
captionstringno
classNamestringno
data-test-idstringno
descriptionstringno
disabledbooleanno
labelstring | numberyes
truncateTruncatePropsno

Types

ItemContentProps

Storybook

ItemContent живёт внутри List, отдельной истории нет — все сценарии видны в List playground.

Figma