WebberUI

Anchored Buy Rail

錨定購買欄:左欄長捲動、右欄黏性購買面板,捲動時以 FLIP 濃縮成迷你結帳膠囊,逼近評論區再展開。

載入預覽⋯

Playground

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

3280
4180
96
<AnchoredBuyRail />

安裝

npx shadcn@latest add https://webberui.com/r/anchored-buy-rail.json

或在 components.json 設定 registries 後,改用 @webberui/anchored-buy-rail 安裝。

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

npm install motion clsx tailwind-merge lucide-react

使用

import { AnchoredBuyRail } from "@/components/ui/anchored-buy-rail";

<AnchoredBuyRail
  title="Terra 有機棉衛衣"
  price={1280}
  compareAtPrice={1680}
  currency="NT$"
  variants={[
    {
      id: "size",
      label: "尺寸",
      options: [
        { value: "s", label: "S" },
        { value: "m", label: "M" },
        { value: "l", label: "L" },
      ],
    },
  ]}
  onAddToCart={(selection) => console.log(selection)}
  footer={<Reviews />}
>
  <ProductStory />
</AnchoredBuyRail>

左欄放入自由捲動的 children(媒體與描述區塊),右欄購買面板由 props 驅動並自動黏性跟隨。若元件被放進巢狀 overflow 捲動容器,請把容器的 ref 傳給 container

Props

Prop型別預設值說明
titlestring商品名稱
pricenumber價格,搭配 currency 格式化
compareAtPricenumber原價(劃線顯示)
currencystring"$"貨幣符號
thumbnailReactNode商品縮圖,會在面板與膠囊間 FLIP 遷移
subtitlestring副標;無變體時顯示於膠囊
variantsBuyVariantGroup[]變體單選群組(尺寸、顏色…)
valueBuySelection受控選取值
defaultValueBuySelection各組首個可選項非受控初始選取值
onValueChange(v: BuySelection) => void選取變更回呼
onAddToCart(v: BuySelection) => void按下 CTA 的回呼
ctaLabelstring"加入購物車"CTA 文案
noteReactNode免運訊息面板底部的信任訊息
childrenReactNode左欄自由捲動內容
footerReactNode頁尾區塊(評論區);逼近時面板展開
containerRefObject<HTMLElement | null>視窗巢狀捲動容器 ref
stickyTopnumber16黏性吸頂位置(px)
condenseAfternumber96捲離頂端多少 px 後收攏成膠囊
expandMarginnumber160距頁尾多少 px 內提前展開

BuyVariantGroup / BuyOption

interface BuyVariantGroup {
  id: string;
  label: string;
  options: { value: string; label: string; disabled?: boolean }[];
}
type BuySelection = Record<string, string>; // { [群組 id]: 選項 value }

細節

  • 黏性 + FLIP:右欄以 position: sticky 跟隨捲動;價格、縮圖與 CTA 帶相同 layoutId,收攏/展開時由 Motion 的共享 layout 動畫(FLIP)在完整面板與膠囊之間連續補間。
  • 收攏時機:以兩個哨兵搭配 IntersectionObserver 判定——頂端哨兵捲離吸頂線 condenseAfter 後收攏;footer 上緣進入視口(含 expandMargin 提前量)時展開。因此在視窗或任意巢狀捲動容器內都能運作。
  • 受控/非受控:提供 value 即為受控;否則以 defaultValue(或各群組第一個可選項)維護內部狀態。

可及性

  • 變體群組為 role="radiogroup",選項為 role="radio" 並帶 aria-checked;採 roving tabindex,支援方向鍵在群組內移動選取,disabled 選項自動跳過。
  • CTA 為原生 <button>,focus 有可見的 focus ring。
  • 購買面板為 role="region" 並帶 aria-label
  • 使用者開啟「減少動態效果」時,面板恆保持完整態、停用收攏與 FLIP 動畫,所有購買控制項全程可用。

On this page