WebberUI

Gooey Menu

液態黏滯展開選單:懸浮觸發鈕點開後,項目以 SVG goo 濾鏡從按鈕中「拉」出並融合,支援四方向與扇形放射。

載入預覽⋯

Playground

即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。

16
44
56
<GooeyMenu />

安裝

npx shadcn@latest add https://webberui.com/r/gooey-menu.json

或在 components.json 設定 registries 後,改用 @webberui/gooey-menu 安裝。

安裝依賴後,從 registry JSON(/r/gooey-menu.jsonfiles[0].content)複製 gooey-menu.tsx 原始碼到你的 components/ui/ 目錄:

npm install motion clsx tailwind-merge lucide-react

使用

import { Heart, Bookmark, Share2 } from "lucide-react";
import { GooeyMenu, type GooeyMenuItem } from "@/components/ui/gooey-menu";

const items: GooeyMenuItem[] = [
  { icon: <Heart />, label: "喜歡", onClick: () => like() },
  { icon: <Bookmark />, label: "收藏", onClick: () => save() },
  { icon: <Share2 />, label: "分享", href: "/share" },
];

<GooeyMenu items={items} direction="up" />;

受控模式:

const [open, setOpen] = useState(false);

<GooeyMenu items={items} open={open} onOpenChange={setOpen} direction="radial" />;

Props

Prop型別預設值說明
itemsGooeyMenuItem[]選單項目(見下表)
direction'up' | 'down' | 'left' | 'right' | 'radial''up'展開方向;radial 為向上扇形放射
openboolean受控開啟狀態,不傳則由內部管理
onOpenChange(open: boolean) => void開啟狀態變更回呼
iconReactNode<Plus />觸發鈕圖示;預設圖示開啟時旋轉 45° 成叉號
labelstring「開啟/關閉選單」觸發鈕的無障礙標籤
gapnumber16液滴之間的間距(px)
itemSizenumber44項目直徑(px)
triggerSizenumber56觸發鈕直徑(px)
radiusnumber自動推算radial 模式的放射半徑(px)
closeOnSelectbooleantrue點擊項目後是否自動收合
classNamestring追加到根容器的 className

GooeyMenuItem

欄位型別說明
iconReactNode圖示(建議 lucide-react,尺寸由元件統一控制)
labelstring無障礙標籤,同時作為懸停/聚焦時的提示文字
onClick() => void點擊回呼
hrefstring若提供則此項渲染為連結 <a>
classNamestring追加到此項按鈕的 className

細節

  • goo 濾鏡:液體層套上 SVG feGaussianBlur + feColorMatrix——先模糊、再拉高 alpha 對比,使觸發鈕與項目的圓形背景融成一團有機黏滯的液面;濾鏡 id 以 useId 產生,同頁多個選單不會互相污染
  • 雙層結構:純色液滴背景與圖示分屬兩層——背景層負責黏滯融合,圖示與點擊互動放在不套濾鏡的上層,因此圖示始終清晰、不受模糊影響
  • 黏滯拉扯:收合時所有項目縮回觸發鈕中心並藏於同色液滴內;展開時由近而遠、收合時由遠而近地錯開時序,配合 spring 讓液滴像被「拉」出又「吸」回
  • 方向與放射updownleftright 沿單軸等距排開,radial 以正上方為中心展成扇形(項目越多扇面越寬)

可及性

  • 觸發鈕為原生 <button>,帶 aria-haspopup="menu"aria-expandedaria-controls;項目容器為 role="menu"、各項為 role="menuitem"
  • 完整鍵盤支援:於觸發鈕按方向鍵即開啟並聚焦首項;項目間以 roving tabindex 搭配方向鍵/Home/End 巡覽;Esc 收合並將焦點歸還觸發鈕
  • 點擊選單外部自動收合;每個項目以 aria-label 命名,懸停或聚焦時另顯示視覺提示標籤(標籤本身 aria-hidden,避免重複朗讀)
  • 液體層與濾鏡皆標記 aria-hidden,純裝飾不干擾輔助科技
  • 使用者系統開啟「減少動態效果」時,液滴的錯落時序、按壓與懸停縮放皆停用,改為即時開闔(DOM 結構不變)

On this page