Chromatic Variant Stage
商品展示舞台,點選色票時同步演出三重轉場——背景放射暈染、商品圖交叉溶接、價格與型號翻牌更新。
載入預覽⋯
Playground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
0.7
<ChromaticVariantStage />
安裝
npx shadcn@latest add https://webberui.com/r/chromatic-variant-stage.json或在 components.json 設定 registries 後,改用 @webberui/chromatic-variant-stage 安裝。
安裝依賴後,從 registry JSON(/r/chromatic-variant-stage.json 的 files[0].content)複製 chromatic-variant-stage.tsx 原始碼到你的 components/ui/ 目錄:
npm install motion clsx tailwind-merge使用
import {
ChromaticVariantStage,
type ChromaticVariant,
} from "@/components/ui/chromatic-variant-stage";
const variants: ChromaticVariant[] = [
{ id: "coral", name: "珊瑚橘", color: "#ff6a55", price: "$269", model: "WB-900 / CR" },
{ id: "azure", name: "天青藍", color: "#4f8ff0", price: "$289", model: "WB-900 / AZ" },
];
<ChromaticVariantStage title="Webber 無線耳機" variants={variants} defaultValue="coral" />未提供 image 時會自動以變體色生成一枚預設商品輪廓;要換成實拍或 SVG,把節點放進各變體的 image 欄位即可。
受控模式
傳入 value 與 onValueChange 即由外部主導選中的變體:
const [color, setColor] = React.useState("coral");
<ChromaticVariantStage
variants={variants}
value={color}
onValueChange={setColor}
/>Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
variants | ChromaticVariant[] | — | 所有可選變體,順序即色票排列順序 |
value | string | — | 受控:目前選中的變體 id |
defaultValue | string | 第一個變體 | 非受控模式的初始變體 id |
onValueChange | (id: string) => void | — | 選中變體變更時觸發 |
title | string | — | 舞台上方標題 |
swatchLabel | string | "選擇顏色" | 色票群組的無障礙標籤 |
duration | number | 0.7 | 三重轉場時長(秒) |
ChromaticVariant
| 欄位 | 型別 | 說明 |
|---|---|---|
id | string | 唯一識別碼(受控與非受控切換皆以此為準) |
name | string | 變體名稱:色票 aria-label 與朗讀內容 |
color | string | 變體主色(任何 CSS 色值):色票、放射暈染與舞台背景皆取自此色 |
price | string | 顯示價格(含幣別符號,如 $129) |
model | string | 型號/款式代碼 |
image | React.ReactNode | 商品視覺;未提供時顯示以變體色生成的預設輪廓 |
細節
- 三重轉場:一次點選同步觸發三件事——背景暈染、商品圖交叉溶接(
AnimatePresence疊接淡入淡出並帶輕微縮放)、以及價格與型號的翻牌更新(繞 X 軸rotateX翻轉,價格由下緣、型號由上緣翻起)。三者共用同一條duration與緩動,讀起來像同一個動作的三個面向。 - 放射暈染的原點對位:點色票時會即時量測該色票中心相對舞台的座標,換算成百分比作為放射原點;因此顏色是「從你按的那顆色票」暈開,而非固定從中央擴散。鍵盤移動選取時同樣以對應色票的位置為原點。
- 無跳色交接:暈染層與底色層使用同一支放射背景函式,暈染以
clip-path: circle()從0%展開到150%(150%確保任何原點都能覆蓋整個矩形)。全開瞬間暈染層與底色像素完全一致,動畫結束時把底色推進到新變體、移除暈染層,交接處看不到任何閃跳。
可及性
- 色票群組為
role="radiogroup",各色票為role="radio"並以aria-checked標示選中狀態;採 roving tabindex(僅選中色票可 Tab 進入)。 - 鍵盤操作:方向鍵在色票間移動選取並自動聚焦,
Home/End跳到首尾。 - 價格區塊帶
aria-live="polite",切換變體時朗讀更新後的價格;預設商品輪廓帶role="img"與aria-label。 - 使用者系統開啟「減少動態效果」時,背景直接切換不做暈染,商品圖與文字瞬間更新,不播放任何轉場。