WebberUI

Receipt Cart

熱感應收據隱喻的購物車:品項逐行打印進場、鋸齒紙緣延伸、紙尾小計與免運進度滾動更新、移除時該行被劃線撕出。

載入預覽⋯

Playground

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

60
5
0.05
<ReceiptCart />

安裝

npx shadcn@latest add https://webberui.com/r/receipt-cart.json

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

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

npm install motion lucide-react clsx tailwind-merge

使用

以資料驅動,傳入品項陣列即可。支援受控(items + onItemsChange)與非受控(defaultItems)雙模式:

import { ReceiptCart } from "@/components/ui/receipt-cart";

<ReceiptCart
  defaultItems={[
    { id: "a", name: "手沖濾掛咖啡", price: 12.5, quantity: 2 },
    { id: "b", name: "陶瓷馬克杯", price: 18, note: "霧面炭黑" },
  ]}
  currency="$"
  freeShippingThreshold={75}
  shippingFee={5}
  taxRate={0.08}
  onRemove={(removed) => console.log("撕除", removed.name)}
/>;

Props

Prop型別預設值說明
itemsReceiptCartItem[]受控模式:由外部提供的品項陣列
defaultItemsReceiptCartItem[][]非受控模式:初始品項陣列
onItemsChange(items) => void品項變動後回傳完整陣列
onRemove(removed, remaining) => void某列被撕除後觸發
currencystring"$"幣別前綴符號
freeShippingThresholdnumber免運門檻;提供後於紙尾顯示進度條
shippingFeenumber0未達門檻時的運費
taxRatenumber稅率(0–1),提供後加計稅額
storeNamestring"WEBBER MART"收據抬頭店名
subtitlestring"CUSTOMER RECEIPT"抬頭副標
metaReactNode抬頭下方的日期/交易資訊列
orderNumberstring條碼下方單號文字
removablebooleantrue是否顯示每列移除按鈕
printStaggernumber0.12逐行打印進場的每列間隔(秒)

ReceiptCartItem{ id, name, price, quantity?, note? }

細節

  • 品項如出單機般逐行打印進場:整列淡入下移,內容以 clip-path 由上而下顯影,printStagger 控制節奏
  • 鋸齒紙緣以 SVG pattern 平鋪三角齒,填色跟隨紙張底色,因此紙張隨品項增加自然向下延伸
  • 紙尾小計、稅金、運費與免運進度以 spring 平滑滾動更新;達門檻時運費列切換為「免運 FREE」並填滿進度條
  • 移除品項時該列先被橫向劃線,劃線完成後才真正撕出(列高收合、向右滑移淡出),其餘列平滑遞補

可及性

  • 收據容器帶 role="region"aria-label,免運進度條為 role="progressbar" 並提供 aria-valuenow/min/max
  • 每個移除按鈕帶對應品項名稱的 aria-label,可鍵盤聚焦操作,focus-visible 有清楚焦點環
  • 使用者系統開啟「減少動態效果」時,停用打印與滾動動畫,移除時略過劃線直接撕除,金額直接顯示最終值

On this page