# @snack-uikit/popover-private

> `npm i @snack-uikit/popover-private`

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

## Install

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

## 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 | 2023-12-05 |
| Weekly downloads | 0 |
| License | Apache-2.0 |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 5 |
| Unpacked size | 117.9 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 23 |
| Author | Сергей Хлупин |
| Maintainers | yetihead, agrigorii, cloud-ru-tech |

## Links

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

## Dependencies (5)

- [react-is](https://npm.io/package/react-is.md) ^18.2.0
- [classnames](https://npm.io/package/classnames.md) ^2.5.1
- [uncontrollable](https://npm.io/package/uncontrollable.md) ^8.0.4
- [@floating-ui/react](https://npm.io/package/@floating-ui/react.md) ^0.26.24
- [@snack-uikit/utils](https://npm.io/package/@snack-uikit/utils.md) ^5.0.0

## 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.15.9-preview-fc6b5b87.0 — 2026-08-20
- 0.15.8 — 2026-07-03
- 0.15.8-preview-74429015.0 — 2026-07-03
- 0.15.8-preview-02d918ac.0 — 2026-07-03
- 0.15.8-preview-6a625dbd.0 — 2026-06-30
- 0.15.7 — 2026-06-24
- 0.15.7-preview-f9bb03b8.0 — 2026-06-08
- 0.15.7-preview-69415993.0 — 2026-06-03
- 0.15.7-preview-ed2b3588.0 — 2026-06-03
- 0.15.6 — 2026-05-18
- … 85 more at https://npm.io/package/@snack-uikit/popover-private/versions

## README

# Popover Private

## Installation
`npm i @snack-uikit/popover-private`

[Changelog](./CHANGELOG.md)

## Description

- Пакет `@snack-uikit/popover-private` предоставляет низкоуровневый компонент `PopoverPrivate` для отображения всплывающих окон (поповеров) относительно триггер-элемента.
- Компонент использует библиотеку Floating UI для позиционирования и автоматической адаптации поповера при выходе за границы видимой области.
- Поддерживает **различные типы триггеров** отображения: клик, ховер, фокус и их комбинации (`click`, `hover`, `focus`, `focusVisible`, `hoverAndFocus`, `hoverAndFocusVisible`, `clickAndFocusVisible`).
- Позволяет задать **12 вариантов размещения** поповера относительно триггера (top, bottom, left, right и их вариации с `-start` и `-end`), а также цепочку резервных позиций (`fallbackPlacements`) для автоматического переключения при нехватке места.
- Поддерживает **управляемый и неуправляемый режимы** работы через пропы `open` и `onOpenChange`.
- Предоставляет **гибкие стратегии управления размерами** контейнера поповера: автоматические размеры по контенту, привязка к ширине/высоте триггера (`widthStrategy`, `heightStrategy`).
- Может отображать **стрелку** (`hasArrow`), указывающую на триггер, с настраиваемыми CSS-классами для стилизации.
- Поддерживает **различные варианты работы с триггером**: оборачивание элемента в `span`, передача функции-рендера, использование внешнего `ref` без оборачивания (`triggerRef`, `disableSpanWrapper`).
- Автоматически закрывается при клике вне поповера, по нажатию `Esc`, при навигации по истории браузера (опционально).
- Поддерживает **задержки открытия и закрытия** для триггера `hover` (`hoverDelayOpen`, `hoverDelayClose`).
- Работает с вложенными поповерами через `FloatingTree` из Floating UI.

## Example

```typescript jsx
import { useRef } from "react";
import { PopoverPrivate } from "@snack-uikit/popover-private";

function App() {
  return (
    <PopoverPrivate
        placement='top'
        popoverContent='Не нажимать, опасно!'
        trigger='click'
      >
        <button>Button with popover</button>
    </PopoverPrivate>
  );
}

// Без оборачивания таргета
function App() {
  const triggerRef = useRef(null)

  return (
    <>
      <PopoverPrivate
        placement='top'
        popoverContent='Не нажимать, опасно!'
        trigger='click'
        triggerRef={triggerRef}
      />
      <button ref={triggerRef}>Button with popover</button>
    </>
  );
}
```

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


[//]: DOCUMENTATION_SECTION_END


#### **`children: ReactNode | ChildrenFunction`**
  Референс, относительно которого рисуется поповер. Возможно несколько вариантов:
 - в **`children`** передан компонент, который принимает в себя `ref`. В таком случае пропсы этого компонента будут дополнены необходимыми для работы триггеров отображения: `useHoverTrigger`, `useClickTrigger`, `useFocusTrigger`. 
    
    > Осторожно, `ref` будет перезаписан. Если вы хотите получить ref на children поповера, можете передать ref в параметр triggerRef. Тогда поповер установит туда значение:
    ```typescript jsx
      <PopoverPrivate
        popoverContent={<div className={style.content}>some tip here</div>}
        useHoverTrigger
        triggerRef={(button) => { /* button HTMLElement из children */ }}
      >
        <button>some button</button>
      </PopoverPrivate>
    ```

  - в **`children`** передан компонент, который **НЕ** принимает в себя `ref`. В таком случае компонент будет обернут в `span`, который и послужит рефом для поповера.

  - в **`children`** передана функция. Эта функция будет вызвана на каждый рендер, она должна возвращать `ReactNode`. В параметры принимает ref, который нужно установить в целевой компонент и функцию `getReferenceProps`, возвращающую необходимые для ref параметры.
  Пример:
    ```typescript jsx
      <PopoverPrivate
        popoverContent={<div className={style.content}>some tip here</div>}
        useHoverTrigger
      >
        {({ getReferenceProps, ref }) => (
          <label>
            Set the value
            <input ref={ref} {...getReferenceProps({ onClick: onClickInputHandler })} />
          </label>
        )}
      </PopoverPrivate>
    ```

  - в **`children`** передан примитив string, number или React.Fragment. Children будет обернут в `span`.

  - **`children`**  не передан в компонент, в таком случае необходимо передать `ref` элемента в `triggerRef`, который будет служить триггером для поповера.
  Пример:
  ```typescript jsx
  const triggerRef = useRef(null)

  return (
    <>
      <PopoverPrivate 
        popoverContent={<div className={style.content}>some tip here</div>}
        useHoverTrigger
        triggerRef={triggerRef}
      />
      <button ref={triggerRef}>Click me</button>
    </>
  )
  ```

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