Hover Expand Gallery
橫向擠壓展開圖庫,游標懸停或鍵盤聚焦時面板佔位變化,其餘面板順勢收合降暗。
載入預覽⋯
Playground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
5
1
8
<HoverExpandGallery />
安裝
npx shadcn@latest add https://webberui.com/r/hover-expand-gallery.json或在 components.json 設定 registries 後,改用 @webberui/hover-expand-gallery 安裝。
安裝依賴後,從 registry JSON(/r/hover-expand-gallery.json 的 files[0].content)複製 hover-expand-gallery.tsx 原始碼到你的 components/ui/ 目錄:
npm install motion clsx tailwind-merge使用
import {
HoverExpandGallery,
HoverExpandGalleryItem,
} from "@/components/ui/hover-expand-gallery";
<HoverExpandGallery className="h-64 w-full max-w-md" defaultActiveIndex={0}>
<HoverExpandGalleryItem label="山稜" description="破曉時分的稜線">
<img src="/mountain.jpg" alt="" className="h-full w-full object-cover" />
</HoverExpandGalleryItem>
<HoverExpandGalleryItem label="海灣" description="退潮後的沙洲">
<img src="/bay.jpg" alt="" className="h-full w-full object-cover" />
</HoverExpandGalleryItem>
</HoverExpandGallery>;面板佔位以 flex-grow 權重驅動:展開的面板放大、其餘面板等比收合。容器需要一個高度(水平方向)或寬度(垂直方向),子面板會自動撐滿。
Props
HoverExpandGallery
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
children | ReactNode | — | 放入 HoverExpandGalleryItem 子元件 |
activeIndex | number | null | — | 受控的展開索引,null 代表全部等分收合 |
defaultActiveIndex | number | null | 0 | 非受控初始展開索引,設 null 則預設等分 |
onActiveIndexChange | (index: number | null) => void | — | 展開索引提交時觸發(hover 不觸發) |
orientation | "horizontal" | "vertical" | "horizontal" | 排列方向:橫向或縱向擠壓 |
expandOnHover | boolean | true | 是否在游標懸停時展開 |
expandedFlex | number | 5 | 展開面板的 flex-grow 權重 |
collapsedFlex | number | 1 | 收合面板的 flex-grow 權重 |
gap | number | 8 | 面板間距(px) |
minItemSize | number | 44 | 收合面板的最小尺寸(px) |
aria-label | string | "互動圖庫" | 圖庫群組的無障礙名稱 |
HoverExpandGalleryItem
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
children | ReactNode | — | 面板的滿版背景視覺(圖片、漸層等) |
label | ReactNode | — | 展開時揭示的標題,同時作為無障礙名稱 |
description | ReactNode | — | 展開時揭示的副標描述 |
icon | ReactNode | — | 收合時仍可見的角落識別圖示 |
細節
- 展開狀態由「懸停」與「已提交(active)」兩層決定:游標懸停時暫時展開懸停面板,離開後回到 active 面板。
- 點擊或鍵盤聚焦某面板會將其提交為 active,因此以鍵盤瀏覽時焦點所在的面板即會展開。
activeIndex越界或設為null時,所有面板以collapsedFlex等分排列。- 展開時面板底部揭示漸層遮罩與標題,收合面板疊上半透明暗色以凸顯焦點。
可及性
- 每個面板為原生
<button>,帶aria-expanded反映展開狀態,並以label(或description)作為無障礙名稱。 - 容器為
role="group"並帶aria-label,可透過同名 prop 覆寫。 - 鍵盤操作:
Tab逐格聚焦,方向鍵(水平用 ←/→、垂直用 ↑/↓)於面板間移動焦點,Home/End跳至首尾;Enter/Space提交展開。 - 使用者系統開啟「減少動態效果」時,面板佔位與揭示直接切換、不套用轉場動畫。