Компоненты/Плавающая кнопка с примагничиванием

Плавающая кнопка с примагничиванием

29 сентября 2026

Перетаскиваемая плавающая кнопка с меню: примагничивается к краю, отстаёт на пружине и закрывается, если бросить её в зону снизу.

Установка

npm install @radix-ui/react-popover @radix-ui/react-tooltip clsx lucide-react motion tailwind-merge
pnpm add @radix-ui/react-popover @radix-ui/react-tooltip clsx lucide-react motion tailwind-merge
yarn add @radix-ui/react-popover @radix-ui/react-tooltip clsx lucide-react motion tailwind-merge
bun add @radix-ui/react-popover @radix-ui/react-tooltip clsx lucide-react motion tailwind-merge

Файлы

draggable-snap-button.tsx
НазадКнопка с подтверждениемДалееРисующий курсор

Круглая плавающая кнопка у края экрана. При наведении слева всплывает подсказка, а по нажатию открывается меню с пунктами. Кнопку можно схватить и перетащить: видимый кружок следует за курсором на пружине с лёгким отставанием.

После броска кнопка с учётом скорости примагничивается к ближайшему боковому краю. Пока её тащат, снизу выезжает зона закрытия: если отпустить кнопку над ней, кружок втягивается в крестик и исчезает.

Вручную

Скопируйте эти файлы в components/draggable-snap-button/:

Общие помощники положите в lib/ проекта:

Проверьте алиас путей. Импорты в коде выше записаны как @/components/... и @/lib/.... Нужен алиас "@/*" на папку, где лежат components/ и lib/, в tsconfig.json — или поправьте импорты под свои пути.

Использование

import { Bell, Settings } from "lucide-react";

import { DraggableSnapButton } from "@/components/draggable-snap-button/draggable-snap-button";

const ITEMS = [
{ icon: Settings, label: "Настройки" },
{ icon: Bell, label: "Уведомления" },
];

export function Page() {
return (
  <div className="relative h-screen">
    <DraggableSnapButton items={ITEMS} tooltipLabel="Быстрые действия" size={44} />
  </div>
);
}

Пропсы

Пропс
Описание
items?

Пункты меню: иконка и подпись

Тип SnapButtonMenuItem[]·По умолчанию шесть пунктов

tooltipLabel?

Текст подсказки и подпись кнопки

Тип string·По умолчанию "Панель Astra"

dropLabel?

Текст зоны закрытия

Тип string·По умолчанию "Перетащите сюда, чтобы закрыть"

releaseLabel?

Текст, когда кнопка над зоной

Тип string·По умолчанию "Отпустите, чтобы закрыть"

size?

Диаметр кнопки в пикселях

Тип number·По умолчанию 40

edge?

Отступ от края при примагничивании

Тип number·По умолчанию 20

showBadge?

Точка уведомления на кнопке

Тип boolean·По умолчанию true

badgeColor?

Цвет точки; по умолчанию фирменный

Тип string

className?

Классы корневого блока

Тип string