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
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
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
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
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
AiCardProps| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
checked | boolean | false | no | Selected-состояние карточки. Controlled — источник истины в родителе. По умолчанию `false`. |
children | ReactNode | — | no | Контент карточки. Не рендерится, если не задан. |
className | string | — | no | Доп. класс корня. |
data-test-id | string | ai-card | no | |
disabled | boolean | false | no | Disabled-состояние: 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. |
title | string | — | no | Заголовок карточки. Semibold, single-line с ellipsis. Не рендерится, если не задан. |