# @snack-uikit/dropdown

> `npm i @snack-uikit/dropdown`

Latest version **1.0.1** (published 2026-09-21) · Apache-2.0 license · 0 weekly downloads

## Install

```sh
npm install @snack-uikit/dropdown
pnpm add @snack-uikit/dropdown
yarn add @snack-uikit/dropdown
bun add @snack-uikit/dropdown
```

## Health

**Score 65/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; recently updated; high maintenance score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 1.0.1 |
| Published | 2026-09-21 |
| First published | 2024-01-30 |
| Weekly downloads | 0 |
| License | Apache-2.0 |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 3 |
| Unpacked size | 36.1 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 23 |
| Author | Nikita Ershov |
| Maintainers | yetihead, agrigorii, cloud-ru-tech |

## Links

- npm: https://www.npmjs.com/package/@snack-uikit/dropdown
- Repository: https://github.com/cloud-ru-tech/snack-uikit
- Homepage: https://github.com/cloud-ru-tech/snack-uikit/tree/master/packages/dropdown
- Issues: https://github.com/cloud-ru-tech/snack-uikit/issues
- npm.io page: https://npm.io/package/@snack-uikit/dropdown

## Dependencies (3)

- [classnames](https://npm.io/package/classnames.md) ^2.5.1
- [@snack-uikit/utils](https://npm.io/package/@snack-uikit/utils.md) ^5.0.0
- [@snack-uikit/popover-private](https://npm.io/package/@snack-uikit/popover-private.md) ^1.0.1

## Recent versions

- 1.0.1 (latest) — 2026-09-21
- 1.0.1-preview-acb79d0b.0 (preview) — 2026-09-21
- 1.0.1-preview-b2e4ed46.0 — 2026-09-21
- 1.0.1-preview-27969f64.0 — 2026-09-21
- 1.0.1-preview-fe85442f.0 — 2026-09-18
- 0.5.9-preview-fc6b5b87.0 — 2026-08-20
- 0.5.8 — 2026-07-03
- 0.5.8-preview-74429015.0 — 2026-07-03
- 0.5.8-preview-02d918ac.0 — 2026-07-03
- 0.5.8-preview-6a625dbd.0 — 2026-06-30
- 0.5.7 — 2026-06-24
- 0.5.7-preview-f9bb03b8.0 — 2026-06-08
- 0.5.7-preview-69415993.0 — 2026-06-03
- 0.5.7-preview-ed2b3588.0 — 2026-06-03
- 0.5.6 — 2026-05-18
- … 79 more at https://npm.io/package/@snack-uikit/dropdown/versions

## README

# Dropdown

## Installation
`npm i @snack-uikit/dropdown`

[Changelog](./CHANGELOG.md)

## Description

- Пакет `@snack-uikit/dropdown` экспортирует компонент `Dropdown` — универсальный выпадающий контейнер для отображения дополнительного контента (меню, подсказки, произвольные блоки) относительно управляющего элемента.
- В основе `Dropdown` используется внутренний компонент `PopoverPrivate`, за счёт чего доступны гибкие настройки положения (`placement`), стратегии ширины (`widthStrategy`), отступа (`offset`) и поведения при кликах/наведении/фокусе.
- Компонент может работать в контролируемом режиме через пропы `open` и `onOpenChange`, поддерживает закрытие по клику вне (`outsideClick`), по клавише `Esc` (`closeOnEscapeKey`) и при изменении истории браузера (`closeOnPopstate`).
- В качестве триггера можно использовать либо дочерний React-элемент (`children`), либо вынесенный наружу элемент через `triggerRef`; при отсутствии и того, и другого `Dropdown` не отрисовывается.
- Ширина выпадающего контейнера задаётся стратегией `widthStrategy`: можно зафиксировать её равной ширине триггера, сделать не меньше ширины триггера или полностью подогнать под контент.
- Отступ между триггером и контейнером контролируется явно через проп `offset` или через CSS-переменную `--offset`, пробрасываемую в `triggerClassName` (пример ниже); при одновременном указании приоритет имеет значение пропа `offset`.
- Figma: [`Dropdown`](https://www.figma.com/file/GZSkePkicPQbtrYIu1F8GQ/Dropdown?type=design&node-id=0%3A1&t=H7kVBUAPq83jxLpg-1).

Чтобы указать оффсет через стили, нужно в `triggerClassName` передать CSS-переменную `--offset`:

Например:

```scss
.triggerClassName {
  --offset: #{$some-var};
}
```

Важное уточнение: если переменная передается через scss-переменную, она должна быть обернута в `#{ }`.

Если значение явно передано через проп `offset`, то будет применено значение пропа.

## Example

```tsx
import { Dropdown } from '@snack-uikit/dropdown';
import { ButtonFilled } from '@snack-uikit/button';

function DropdownExample() {
  return (
    <Dropdown
      content={
        <div>
          <div>Строка 1 контента</div>
          <div>Строка 2 контента</div>
          <div>Строка 3 контента</div>
        </div>
      }
      placement='bottom-start'
      widthStrategy='gte'
      offset={8}
      data-test-id='dropdown'
    >
      <ButtonFilled label='Открыть выпадающее меню' />
    </Dropdown>
  );
}
```

[//]: DOCUMENTATION_SECTION_START
[//]: THIS_SECTION_IS_AUTOGENERATED_PLEASE_DONT_EDIT_IT
## Dropdown
### Props
| name | type | default value | description |
|------|------|---------------|-------------|
| content* | `ReactNode` | - |  |
| className | `string` | - | CSS-класс |
| triggerClassName | `string` | - | CSS-класс триггера |
| open | `boolean` | - | Управляет состоянием показан/не показан. |
| onOpenChange | `(isOpen: boolean) => void` | - | Колбек отображения компонента. Срабатывает при изменении состояния open. |
| hoverDelayOpen | `number` | - | Задержка открытия по ховеру |
| hoverDelayClose | `number` | - | Задержка закрытия по ховеру |
| widthStrategy | enum PopoverWidthStrategy: `"auto"`, `"gte"`, `"eq"` | gte | Стратегия управления шириной контейнера поповера <br> - `auto` - соответствует ширине контента, <br> - `gte` - Great Than or Equal, равен ширине таргета или больше ее, если контент в поповере шире, <br> - `eq` - Equal, строго равен ширине таргета. |
| offset | `number` | 0 | Отступ поповера от его триггер-элемента (в пикселях). |
| children | `ReactNode \| ChildrenFunction` | - | Триггер поповера (подробнее читайте ниже) |
| closeOnEscapeKey | `boolean` | true | Закрывать ли по нажатию на кнопку `Esc` |
| triggerClickByKeys | `boolean` | true | Вызывается ли попоповер по нажатию клавиш Enter/Space (при trigger = `click`) |
| triggerRef | `ForwardedRef<ReferenceType \| HTMLElement>` | - | Ref ссылка на триггер |
| outsideClick | `boolean \| OutsideClickHandler` | - | Закрывать ли при клике вне поповера |
| fallbackPlacements | `Placement[]` | - | Цепочка расположений которая будет применяться к поповеру от первого к последнему если при текущем он не влезает. |
| disableSpanWrapper | `boolean` | - | Отключает для `isValidElement` внешнюю обертку триггера <br> Пригодится для элементов с `position: absolute` |
| closeOnPopstate | `boolean` | - | Закрывать ли поповер при пекреходе по истории браузера |
| trigger | enum Trigger: `"click"`, `"hover"`, `"focusVisible"`, `"focus"`, `"hoverAndFocusVisible"`, `"hoverAndFocus"`, `"clickAndFocusVisible"` | click | Условие отображения поповера: <br> - `click` - открывать по клику <br> - `hover` - открывать по ховеру <br> - `focusVisible` - открывать по focus-visible <br> - `focus` - открывать по фокусу <br> - `hoverAndFocusVisible` - открывать по ховеру и focus-visible <br> - `hoverAndFocus` - открывать по ховеру и фокусу <br> - `clickAndFocusVisible` - открывать по клику и focus-visible |
| placement | enum Placement: `"left"`, `"left-start"`, `"left-end"`, `"right"`, `"right-start"`, `"right-end"`, `"top"`, `"top-start"`, `"top-end"`, `"bottom"`, `"bottom-start"`, `"bottom-end"` | bottom-start | Положение поповера относительно своего триггера (children). |


[//]: DOCUMENTATION_SECTION_END

---
_Source: https://npm.io/package/@snack-uikit/dropdown · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
