AiCard

AiCard — выбираемая карточка из набора AI Components. Поведение — независимый boolean-переключатель: клик / Enter / Space меняют checked. Подходит для выбора AI-предложений, карточек настроек, любых сценариев, где каждая карточка переключается отдельно.

Компонент рендерится как <button>. Полиморфизм (as) не поддерживается: для навигационной карточки используйте @cloud-ru/ds-card.

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

  • Карточки выбора в AI-сценариях (карточки-пресеты, генеративные варианты).
  • Настройки, где каждая опция — самостоятельный переключатель.
  • Выделенные блоки с состоянием «выделено / не выделено».

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

  • Один из группы (radio-семантика):
    • используйте SegmentControl либо обёртку с собственным состоянием.
  • Статичный контейнер без выбора:
    • используйте @cloud-ru/ds-card.
  • Действие-кнопка:
    • используйте @cloud-ru/ds-button.

Анатомия

Title

Заголовок в одну строку, semibold 14/20 с обрезкой по text-overflow: ellipsis. Слот скрыт, если title не задан.

Content

Контент children под заголовком. Regular 14/20, вторичный цвет текста. Слот скрыт, если children не задан.

Checked state (default false)

checked добавляет акцентный зелёный border и полупрозрачную заливку. :hover усиливает контраст, :focus-visible накладывает outline толщиной 2px акцентного цвета.

checked работает и как controlled-проп (если задан onChange), и как стартовое значение для uncontrolled-режима (если onChange не передан — компонент сам ведёт состояние).

Установка

pnpm add @cloud-ru/ds-ai-card
import { AiCard } from '@cloud-ru/ds-ai-card'

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

Default

DefaultUncontrolled — клик переключает выбор
tsx
import { AiCard } from '@cloud-ru/ds-ai-card';
import { useState } from 'react';

export function Default() {
  const [checked, setChecked] = useState(false);
  return (
    <AiCard title='Card title' checked={checked} onChange={setChecked}>
      Default content
    </AiCard>
  );
}

Selected

SelectedСтартовое selected-состояние через `defaultChecked`
tsx
import { AiCard } from '@cloud-ru/ds-ai-card';
import { useState } from 'react';

export function Selected() {
  const [checked, setChecked] = useState(true);
  return (
    <AiCard title='Selected card' checked={checked} onChange={setChecked}>
      Card content in selected state
    </AiCard>
  );
}

Controlled

ControlledСостояние в родителе через `checked` + `onChange`
tsx
import { AiCard } from '@cloud-ru/ds-ai-card';
import { useState } from 'react';

export function Controlled() {
  const [checked, setChecked] = useState(false);
  return (
    <AiCard title={`Controlled (${checked ? 'on' : 'off'})`} checked={checked} onChange={setChecked}>
      Состояние хранится в родителе.
    </AiCard>
  );
}

Disabled

DisabledDisabled-состояние блокирует клик и клавиатуру
tsx
import { AiCard } from '@cloud-ru/ds-ai-card';

export function Disabled() {
  return (
    <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap', alignItems: 'center' }}>
      <AiCard title='Disabled' disabled>
        Не реагирует на клики
      </AiCard>
      <AiCard title='Disabled + selected' disabled checked>
        Заблокирован в selected-состоянии
      </AiCard>
    </div>
  );
}

Props

Types

PropsAiCardProps
PropTypeDefaultRequiredDescription
checkedbooleanfalsenoSelected-состояние карточки. Controlled — источник истины в родителе. По умолчанию `false`.
childrenReactNodenoКонтент карточки. Не рендерится, если не задан.
classNamestringnoДоп. класс корня.
data-test-idstringai-cardno
disabledbooleanfalsenoDisabled-состояние: opacity 0.4, нативная блокировка кликов и клавиатуры.
onChange((checked: boolean) => void)noСрабатывает при toggle (клик / Enter / Space). Получает новое значение `checked`.
onClick((event: MouseEvent<HTMLButtonElement, MouseEvent>) => void)noНативный обработчик клика. Срабатывает после `onChange` (toggle первичен). Не вызывается для disabled-карточки — браузер сам не дёргает onClick на disabled button.
titlestringnoЗаголовок карточки. Semibold, single-line с ellipsis. Не рендерится, если не задан.

Types

AiCardProps

Storybook

Figma