﻿---
description: Базовый компонент для создания интерактивных элементов, который автоматически адаптирует семантику и поведение под контекст.
tags: buttons
---

<Overview group="utils">

# Tappable [tag:component]

Базовый компонент для создания интерактивных элементов, который автоматически адаптирует семантику и поведение под контекст.
Обрабатывает состояния наведения, нажатия и фокуса, обеспечивая:

- визуальную обратную связь через фоновые эффекты;
- ripple-эффект на Android;
- автоматическую установку `cursor: pointer`;
- основу для интерактивных компонентов вроде [`Button`](/components/button),
  [`Cell`](/components/cell), [`ActionSheetItem`](/components/action-sheet#action-sheet-item);

</Overview>

{/* @example-description: Базовый интерактивный `Tappable` с обработчиком нажатия. */}
<Playground>
  ```jsx
  <Tappable onClick={() => alert('Обработчик нажатия')}>
    <Text>Я - кнопка</Text>
  </Tappable>
  ```
</Playground>

## Логика выбора элемента

Компонент динамически выбирает HTML-тег на основе переданных свойств:

| Условия              | Тег       | Роль/Атрибуты                 | Особенности                      |
| -------------------- | --------- | ----------------------------- | -------------------------------- |
| Передан `Component`  | Кастомный | Наследует переданные свойства | Требует ручной настройки a11y    |
| Указан `href`        | `<a>`     | `role="link"` при `disabled`  | Блокировка через `aria-disabled` |
| Указан `onClick`     | `<div>`   | `role="button" tabIndex="0"`  | Обработка клавиш Space/Enter     |
| Без `href`/`onClick` | `<div>`   | -                             | Неинтерактивный контейнер        |

## Особенности состояний

### Наведение

- Свойство `hasHover` включает/выключает реакцию на наведение.
- Свойство `hovered` включает состояние наведения.
- Свойство `hoverMode` позволяет стилизовать состояние.
  Если передать произвольную строку, она добавится как css-класс во время наведения.

### Нажатие

Задается свойством `active`:

- Свойство `hasActive` включает/выключает реакцию на нажатие.
- Свойство `activated` включает состояния нажатия.
- Свойство `activeMode`/`activeClassName` позволяет стилизовать состояние.
  Если передать произвольную строку, она добавится как css-класс во время нажатия.
- Свойство `activeEffectDelay` отвечает за длительность подсветки (в миллисекундах).

### Focus (фокус)

- Свойство `focusVisibleMode` позволяет стилизовать стиль состояния фокуса.
  Если передать произвольную строку, она добавится как css-класс при `:focus-visible`

## Скругление углов

Задается свойством `borderRadiusMode`:

- `auto` — адаптивный режим (нет скруглений на мобильных);
- `inherit` — наследование стилей.

## Взаимодействие с дочерними элементами

### Групповая подсветка

```jsx
// Родитель сохраняет hover при наведении на детей
<Tappable hasHoverWithChildren>
  <IconButton />
  <IconButton />
</Tappable>
```

### Проброс состояния

```jsx
// Дочерний элемент активирует hover родителя
<Tappable>
  <IconButton unlockParentHover />
</Tappable>
```

## Доступность (a11y) [#a11y]

### Основные принципы

- **Автоматическая семантика**

  Компонент сам выбирает подходящий HTML-тег:
  - `<a>` при передаче `href`;
  - `<div role="button">` при наличии `onClick`;
  - в остальных случаях `<div>`.

- **Блокировка элементов**

  При `disabled`:
  - Для ссылок: `aria-disabled="true"` + удаление `href`
  - Для кнопок: `aria-disabled="true"` + `tabIndex="-1"`

- **Клавиатурные события**

  Кнопки (`role="button"`) обрабатывают:
  - Нажатие клавиш `Space`/`Enter`
  - Фокус через клавишу `Tab`

### Критические правила

- **Иконки без текста**

  Всегда добавляйте текстовую метку:

  ```jsx
  // Плохо
  <Tappable><Icon16Close /></Tappable>

  // Хорошо
  <Tappable aria-label="Закрыть">
    <Icon16Close />
  </Tappable>
  ```

- **Смешение href и onClick**

  Избегайте комбинации — это нарушает семантику:

  ```jsx
  // Антипаттерн
  <Tappable href="/page" onClick={handleClick} />

  // Правильно
  <Tappable href="/page">Ссылка</Tappable>
  <Tappable onClick={handleClick}>Кнопка</Tappable>
  ```

- **Кастомные элементы**

  Для нестандартных тегов явно укажите:

  ```jsx
  <Tappable Component="span" role="button" tabIndex={0} aria-label="Действие" />
  ```

### Визуальный фокус

- Используйте `focusVisibleMode` для кастомизации.
- Не переопределяйте `:focus-visible` без веской причины.

## Свойства и методы [#api]

| Свойство | Тип | По умолчанию | Описание |
| --- | --- | --- | --- |
| `activated` | `boolean` | `-` | Позволяет управлять `activated`-состоянием извне. |
| `activeClassName` | `string` | `-` | **Deprecated**: Since 7.3.0. Будет удалено в **VKUI v9**.  Используйте свойство `activeMode`. |
| `activeEffectDelay` | `number` | `-` | Длительность показа `active`-состояния. |
| `activeMode` | `StateModeLiteral` | `background` | Стиль подсветки active-состояния. Если передать произвольную строку, она добавится как css-класс во время active. |
| `baseClassName` | `string \| false` | `-` | Базовый класс. |
| `baseStyle` | `CSSProperties` | `-` | Базовые стили. |
| `borderRadiusMode` | `"auto" \| "inherit"` | `auto` | Задает border-radius элементу В режиме `auto` на маленьких экранах `border-radius: 0`, иначе определяется токеном `--vkui--size_border_radius--regular`. |
| `Component` | `ElementType<any, keyof IntrinsicElements>` | `-` |  |
| `DefaultComponent` | `ElementType<any, keyof IntrinsicElements>` | `-` | Компонент который будет при передаче `onClick`. По умолчанию `"div"`. |
| `focusVisibleMode` | `FocusVisibleMode` | `-` | Стиль аутлайна focus visible. Если передать произвольную строку, она добавится как css-класс при :focus-visible |
| `getRootRef` | `Ref<HTMLElement>` | `-` |  |
| `hasActive` | `boolean` | `-` | Указывает, должен ли компонент реагировать на `active`-состояние. |
| `hasHover` | `boolean` | `-` | Указывает, должен ли компонент реагировать на `hover`-состояние. |
| `hasHoverWithChildren` | `boolean` | `-` | Позволяет родительскому компоненту иметь `hovered`-cостояние при наведении на любой дочерний элемент. По умолчанию состояние hovered у родителя сбрасывается.  Присваивается родителькому компоненту. |
| `hoverClassName` | `string` | `-` | **Deprecated**: Since 7.3.0. Будет удалено в **VKUI v9**.  Используйте свойство `hoverMode`. |
| `hovered` | `boolean` | `-` | Позволяет управлять `hovered`-состоянием извне. |
| `hoverMode` | `StateModeLiteral` | `background` | Стиль подсветки hover-состояния. Если передать произвольную строку, она добавится как css-класс во время hover. |
| `unlockParentHover` | `boolean` | `-` | Позволяет родительскому компоненту показывать hovered-состояние при наведении на текущий дочерний компонент.  Присваивается дочернему компоненту. |

