﻿---
description: Компонент для показа кратких сообщений и уведомлений.
tags: notification
---

<Overview group="feedback">

# Snackbar [tag:component]

Компонент для показа кратких сообщений и уведомлений, который можно использовать,
чтобы информировать пользователя о каких-то процессах в приложении, например, "Статья добавлена в закладки".
Имитирует поведение нативных элементов, поддерживает управление жестами.

</Overview>

<Playground hide Wrapper={BlockWrapper}>
  ```jsx
  <Snackbar.Basic
    before={<Icon28CheckCircleOutline fill="var(--vkui--color_icon_positive)" />}
    after={
      <Button mode="link" appearance="accent" size="s">
        Поделиться
      </Button>
    }
  >
    Ссылка скопирована
  </Snackbar.Basic>
  ```
</Playground>

{/* @example-description: Базовый `Snackbar` с действием и иконкой, управляемый через состояние. */}
<Playground>

```jsx
const [snackbar, setSnackbar] = React.useState(null);

const showSnackbar = () => {
  if (snackbar) return;
  setSnackbar(
    <Snackbar
      onClosed={() => setSnackbar(null)}
      action="Поделиться"
      before={
        <Avatar size={24} style={{ background: 'var(--vkui--color_background_accent)' }}>
          <Icon16Done fill="#fff" width={14} height={14} />
        </Avatar>
      }
    >
      Ссылка скопирована
    </Snackbar>,
  );
};

return (
  <>
    <Button onClick={showSnackbar}>Показать уведомление</Button>
    {snackbar}
  </>
);
```

</Playground>

## Обязательные свойства

### `onClosed`

Свойство принимает функцию, которая вызовется после завершения анимации закрытия компонента.
Обязательно удаляйте из `DOM`-дерева компонент `Snackbar` в обработчике `onClosed`, иначе это будет мешать
дальнейшему взаимодействию с элементами и повторному открытию компонента.

> С помощью свойства `duration` можно задать время в миллисекундах, через которое компонент скроется (по умолчанию `4000`).

## Текстовые элементы [#text]

Основной текст сообщения или уведомления передаётся через свойство `children`.
Дополнительный текст под основным можно задать с помощью свойства `subtitle`.

> Свойство `subtitle` не может использоваться одновременно с [кнопкой действия](#action).

## Контент в начале/в конце

В компоненте доступна возможность добавления дополнительного контента слева и/или справа от текста,
задаётся свойством `before` и `after` соответственно.

В `before` рекомендуется размещать следующий контент:

- иконка размером `24px` или `28px`;
- аватар `Avatar` размером `32px`;
- изображение `Image` размером `40px`.

В `after` рекомендуется размещать следующий контент:

- кнопки `Button` размером `size="s"`;
- иконки размером `24px`.

import { BlockWrapper } from '@/components/wrappers';

{/* @example-description: Визуальный пример `Snackbar.Basic` с иконкой и кнопкой действия справа. */}
<Playground Wrapper={BlockWrapper}>
  ```jsx
  <Snackbar.Basic
    before={<Icon28CheckCircleOutline fill="var(--vkui--color_icon_positive)" />}
    after={
      <Button mode="link" appearance="accent" size="s">
        Поделиться
      </Button>
    }
  >
    Ссылка скопирована
  </Snackbar.Basic>
  ```
</Playground>

## Стили отображения

Задаётся свойством `mode`.

- `"default"` — стандартный вид компонент;
- `"dark"` — тёмная тема компонента.

## Позиционирование

### `placement`

Данное свойство отвечает за расположение компонента на экране.

- `"top-start"` — расположение в верхнем левом углу;
- `"top"` — расположение по центру сверху;
- `"top-end"` — расположение в верхнем правом углу;
- `"bottom-start"` — расположение в нижнем левом углу (по умолчанию);
- `"bottom"` — расположение по центру снизу;
- `"bottom-end"` — расположение в нижнем правом углу.

В зависимости от расположения изменяется анимация появления. Так для `"top-start"` появление компонента ожидается
с верхнего левого края, а для `"bottom"` - снизу. Анимация скрытия происходит в обратном направлении.
Также есть возможность скрыть компонент смахиванием в обратную от анимации появления сторону.

> **Ограничения для мобильных устройств**
>
> Значения `"top-start"`/`"top-end"` равносильны `"top"`, чтобы сохранить имитацию нативного поведения.
>
> Значение `"bottom"` равносильно `"bottom-start"`, чтобы избежать вызова системных функций,
> таких как `Pull To Refresh` и Режим управления одной рукой.
>
> Значения `"bottom-start"`/`"bottom-end"` закрываются смахиванием в любое из направлений по горизонтальной оси.

### Отступы

С помощью `offsetY` можно задать отступ (в пикселях) снизу (для всех `placement="bottom*"`) или сверху (для всех `placement="top*"`),
чтобы компонент не перекрывал нужные элементы интерфейса.

## Кнопка действия [#action]

С помощью свойства `action` можно задать название для кнопки действия.

> Свойство `action` не может использоваться одновременно со свойством [`subtitle`](#text).

```jsx
<Snackbar action="Перейти в раздел «Понравилось»" onActionClick={() => alert('Ты - молодец!')}>
  Ссылка сохранена в закладки
</Snackbar>
```

Задать вариант расположения кнопки действия можно с помощью свойства `layout`:

- `"vertical"` — кнопка располагается справа от основного текста;
- `"horizontal"` — кнопка располагается под основным текстом.

По умолчанию на устройствах с шириной больше или равно `ViewWidth.SMALL_TABLET` или при наличии свойства `after`
значение будет равно `"vertical"`, в остальных случаях — `"horizontal"`.

Обработать нажатие на кнопку действия можно с помощью свойства `onActionClick`.

## Snackbar.Basic [tag:component]

Если вам нужен только визуальный компонент без позиционирования и логики смахивания, то используйте `Snackbar.Basic`.
Он будет полезен, если вы используете стороннюю систему уведомлений.

{/* @example-description: Использование `Snackbar.Basic` как чисто визуального компонента без логики показа. */}
<Playground Wrapper={BlockWrapper}>
  ```jsx
  <Snackbar.Basic
    before={<Icon28CheckCircleOutline fill="var(--vkui--color_icon_positive)" />}
    after={
      <Button mode="link" appearance="accent" size="s">
        Поделиться
      </Button>
    }
  >
    Ссылка скопирована
  </Snackbar.Basic>
  ```
</Playground>

## Хук `useSnackbarManager`

Для более удобного управления снекбарами вы можете использовать менеджер в виде хука [`useSnackbarManager`](/components/use-snackbar-manager)

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

### Snackbar

| Свойство | Тип | По умолчанию | Описание |
| --- | --- | --- | --- |
| `action` | `ReactNode` | `-` | Название кнопки действия в уведомлении Не может использоваться одновременно с `subtitle`. |
| `after` | `ReactNode` | `-` | Контент в правой части, может быть иконкой 24x24. |
| `before` | `ReactNode` | `-` | Может быть следующими компонентами:  - цветная иконка 24x24 или 28x28 пикселя  - `<Avatar size={32} />`  - `<Image size={40} />`. |
| `duration` | `number \| null` | `4000` | Время в миллисекундах, через которое плашка скроется. |
| `getRootRef` | `Ref<HTMLDivElement>` | `-` |  |
| `layout` | `"horizontal" \| "vertical"` | `-` | Варианты расположения кнопки действия По умолчанию на десктопах, или при наличии элементов `after` или `subtitle` имеет значение `vertical`, в остальных случаях `horizontal`. |
| `mode` | `"default" \| "dark"` | `default` | Задает стиль снекбара. |
| `offsetY` | `Bottom<string \| number>` | `-` | Величина отступа снизу. Используется для позиционирования элемента в случае, когда нежелательно, чтобы Snackbar при появлении перекрывал важные элементы интерфейса. |
| `onActionClick` | `((event: MouseEvent<Element, MouseEvent>) => void)` | `-` | Будет вызвано при нажатии на кнопку действия. |
| `onClose` | `((reason: SnackbarCloseReason) => void)` | `-` | Обработчик закрытия уведомления. |
| `**onClosed** \*` | `() => void` | `-` | Обработчик закрытия уведомления, срабатывающий после окончания анимации. |
| `open` | `boolean` | `-` | Для контролируемого управления состоянием открытия снекбара. |
| `placement` | `SnackbarPlacement` | `bottom-start` | Задаёт расположение компонента.  > Note: в мобильном режиме: > - `"top-start"`/`"top-end"` перебивается на `"top"`, чтобы поведение было схожим с нативными >   уведомлениями; > - `"bottom"` перебивается на `"bottom-start"`, чтобы избежать вызова системных >   функций, таких как **Pull To Refresh** и **Режим управления одной рукой**. > - `"bottom-start"`/`"bottom-end"` закрываются смахиванием в любое из направлений >   по горизонтальной оси. |
| `slotProps` | `{ root?: (Omit<HTMLAttributes<HTMLDivElement>, "children"> & HasRootRef<HTMLDivElement> & HasDataAttribute); action?: (HTMLAttributes<...> & ... 1 more ... & HasDataAttribute) \| undefined; } \| undefined` | `-` | Свойства, которые можно прокинуть внутрь компонента: - `root`: свойства для прокидывания в корень компонента; - `action`: свойства для прокидывания в кнопку действия. |
| `subtitle` | `ReactNode` | `-` | Дополнительная строка текста под `children`. Не может использоваться одновременно с `action`. |

### Snackbar.Basic

| Свойство | Тип | По умолчанию | Описание |
| --- | --- | --- | --- |
| `action` | `ReactNode` | `-` | Элемент действия. Не может использоваться одновременно с `subtitle`. |
| `after` | `ReactNode` | `-` | Контент в правой части, может быть иконкой 24x24. |
| `before` | `ReactNode` | `-` | Может быть следующими компонентами:  - цветная иконка 24x24 или 28x28 пикселя  - `<Avatar size={32} />`  - `<Image size={40} />`. |
| `getRootRef` | `Ref<HTMLDivElement>` | `-` |  |
| `layout` | `"horizontal" \| "vertical"` | `-` | Варианты расположения кнопки действия По умолчанию на десктопах, или при наличии элементов `after` или `subtitle` имеет значение `vertical`, в остальных случаях `horizontal`. |
| `mode` | `"default" \| "dark"` | `-` | Задает стиль снекбара. |
| `subtitle` | `ReactNode` | `-` | Дополнительная строка текста под `children`. Не может использоваться одновременно с `action`. |

