AI 應用元件
程式變更導讀
步驟式程式差異導讀:每一步高亮一段刪除或新增的程式行,右側說明卡同步推進,用白話向非工程師解釋這次改了什麼。
把一次程式變更拆成幾個步驟講給非工程師聽:左邊是 diff 視窗(檔名列、舊/新行號、程式行),右邊(窄螢幕在下方)是說明卡,底部有上一步、下一步與自動播放。每進入一步,該步提到的行會加上底色與左緣色條;刪除行在講完之後「流走」,新增行在講到時才展開,其餘的行淡到 45%,視線自然停在這一步改的地方。說明卡上有對應的行號徽章,點說明步驟或點程式行都能直接跳到那一步。
把這個效果裝進你的專案
在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。
npx webberui@latest add "https://webberui.com/r/code-change-explainer.json?t=<安裝 token>"Playground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
3200
編輯中的呼叫預設屬性
<CodeChangeExplainer/>
完整範例包含預覽的排版與資料。先安裝元件,再把範例檔貼入你的專案。
安裝
npx webberui@latest add "https://webberui.com/r/code-change-explainer.json?t=<安裝 token>"或在 components.json 設定 registries 後,改用 @webberui/code-change-explainer 安裝。
使用
import {
CodeChangeExplainer,
type CodeChangeLine,
type CodeChangeStep,
} from "@/components/ui/code-change-explainer";
const lines: CodeChangeLine[] = [
{ id: "table", type: "add", text: "const FEE = { north: 60, south: 80, islands: 150 };" },
{ id: "sig", type: "context", text: "export function shippingFee(cart: Cart): number {" },
{ id: "fixed", type: "remove", text: " return 60; // 一律 60 元" },
{ id: "lookup", type: "add", text: " return FEE[cart.region] ?? 60;" },
{ id: "close", type: "context", text: "}" },
];
const steps: CodeChangeStep[] = [
{ id: "s1", lineIds: ["fixed"], title: "拿掉寫死的 60 元", body: "原本不論寄到哪裡都收 60 元,這行拿掉。" },
{ id: "s2", lineIds: ["table", "lookup"], title: "改成依地區查表", body: "北部 60、南部 80、離島 150。" },
];
<CodeChangeExplainer
filename="shipping-fee.ts"
lines={lines}
steps={steps}
autoPlay
onStepChange={(step) => console.log("目前第", step + 1, "步")}
/>;Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
filename | string | — | diff 視窗標題列顯示的檔名;未提供時顯示「程式變更」 |
lines | CodeChangeLine[] | — | 所有程式行,依檔案順序排列;刪除行與新增行交錯放在它們原本的位置 |
steps | CodeChangeStep[] | — | 講解步驟,依播放順序排列 |
step | number | — | 受控的目前步驟(從 0 起算);未提供時由元件內部管理 |
defaultStep | number | 0 | 非受控模式的初始步驟 |
onStepChange | (step: number) => void | — | 步驟變動時回呼 |
autoPlay | boolean | false | 是否自動播放;播到最後一步會回到第一步,滑鼠移入元件時暫停 |
interval | number | 3200 | 自動播放每一步的停留時間(毫秒),最小 600 |
showLineNumbers | boolean | true | 是否顯示舊/新兩欄行號 |
className | string | — | 透傳到最外層容器 |
CodeChangeLine
| 欄位 | 型別 | 預設值 | 說明 |
|---|---|---|---|
id | string | — | 行的唯一識別碼,steps 以此指涉 |
type | "context" | "add" | "remove" | — | 未變動的上下文、新增或刪除 |
text | string | — | 該行原始文字(保留縮排) |
CodeChangeStep
| 欄位 | 型別 | 預設值 | 說明 |
|---|---|---|---|
id | string | — | 步驟唯一識別碼 |
lineIds | string[] | — | 這一步要高亮的行 id |
title | string | — | 說明卡標題 |
body | string | — | 說明卡內文,建議用白話解釋這幾行改了什麼 |
另外具名匯出 CodeChangeLineType 與 CodeChangeExplainerProps 型別。
細節
- 行何時出現、何時消失:每一行以「第一個提到它的步驟」為準。刪除行在那一步之前與當下都還在(當下高亮給人看),往後一步才以高度收合、淡出並向左位移 12px 的方式流走;新增行在那一步才展開。沒有任何步驟提到的行一律顯示。往回切步時,流走的刪除行會再展開回來
- 行號:採用舊/新兩欄,跟一般 diff 一樣——刪除行只有舊行號、新增行只有新行號。說明卡的徽章依此寫成
−3 · +9–11這樣的範圍 - 語法上色:元件內建極簡 tokenizer,只分關鍵字、字串、數字、註解四類(雙斜線與單行區塊註解),不依賴任何高亮函式庫
- CSS 變數:
--wb-code-change-duration(預設320ms)、--wb-code-change-ease(預設cubic-bezier(0.22,1,0.36,1))、--wb-code-change-add(預設rgb(34 197 94 / 0.12))、--wb-code-change-remove(預設rgb(239 68 68 / 0.12)),以及上色用的--wb-code-change-keyword、--wb-code-change-string、--wb-code-change-number、--wb-code-change-comment。未覆寫時,深色模式會改用較亮的預設色 - 自動播放:
autoPlay開啟後每隔interval毫秒前進一步,到最後一步再回到第一步;滑鼠移入元件時暫停,移開後繼續。底部的播放鍵可隨時切換 - 版面:元件以 container query 判斷寬度,容器寬於 36rem 時說明卡放在 diff 右側,較窄時移到下方
可及性
- diff 以
role="table"呈現,每一行role="row"並帶aria-label,新增行以「新增:」、刪除行以「刪除:」開頭;行首另有+/−符號,高亮不只靠顏色 - 說明卡區塊為
aria-live="polite",切步時螢幕閱讀器會朗讀新的說明;行號徽章另附完整文字說法 - 上一步、下一步、自動播放與每個步驟項目都是
type="button",帶focus-visible外框;目前步驟以aria-current="step"標示,自動播放鍵以aria-pressed表示狀態 - 焦點在元件內(diff 捲動區除外)時,左右方向鍵可切換上一步/下一步;diff 捲動區可用 Tab 聚焦,方向鍵留給水平捲動
- 點程式行跳步是滑鼠的捷徑,鍵盤使用者可以用步驟清單達到同樣效果
- 使用者系統開啟「減少動態效果」時,行直接出現或消失,不做高度與位移動畫;說明卡直接切換,不做上下滑動