Круглая плавающая кнопка у края экрана. При наведении слева всплывает подсказка, а по нажатию открывается меню с пунктами. Кнопку можно схватить и перетащить: видимый кружок следует за курсором на пружине с лёгким отставанием.
После броска кнопка с учётом скорости примагничивается к ближайшему боковому краю. Пока её тащат, снизу выезжает зона закрытия: если отпустить кнопку над ней, кружок втягивается в крестик и исчезает.
Скопируйте эти файлы в 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