migrate-radix-to-base

migrate-radix-to-base

熱門

將 React 專案與元件從 Radix UI 遷移至 Base UI。當被要求從 radix 遷移、移至 base-ui、轉換 radix 基本元件,或切換 shadcn 專案的基礎函式庫時使用。可處理單一元件(如「遷移 accordion」)與整個專案。

12萬星標
9422分支
更新於 2026/7/16
SKILL.md
readonlyread-only
name
migrate-radix-to-base
description

將 React 專案與元件從 Radix UI 遷移至 Base UI。當被要求從 radix 遷移、移至 base-ui、轉換 radix 基本元件,或切換 shadcn 專案的基礎函式庫時使用。可處理單一元件(如「遷移 accordion」)與整個專案。

Radix UI -> Base UI 遷移

你負責將 shadcn 包裝器、手寫的 radix 組合以及它們的使用者遷移至 @base-ui/react,並確保專案在每一步都能建置。請保持精確;切勿猜測對應關係。當某個 prop 或部分未出現在這些參考檔案中時,請在轉換前檢查 node_modules/@base-ui/react/**/*.d.ts,並在報告中記錄缺口。

前置檢查(務必執行)

  1. 執行 npx shadcn@latest info --json(或專案的執行器):取得目前的基礎、STYLE(例如 radix-lyra)、tailwind 版本、別名、已安裝的元件以及套件管理器。請信任此資訊而非推測。
  2. 偵測套件管理器(packageManager 欄位 / 鎖定檔:pnpm-lock.yaml、bun.lock、yarn.lock、package-lock.json),並使用它進行所有安裝。切勿留下過時的鎖定檔。
  3. 要求乾淨的 git 樹狀結構;在分支上工作;每個元件一個提交。
  4. 在觸碰相依套件之前進行基線檢查:執行專案的型別檢查/建置,以便預先存在的失敗不會歸咎於你。
  5. 安裝 @base-ui/react 並保留 radix。Radix 套件僅在最後一個元件遷移完成後才移除(兩者可以共存)。

策略:先建立黃金配對,再使用轉換引擎

  • 透過 CLI 建立黃金配對(首選)。 如果專案是 shadcn 且使用已知樣式(radix-<style>),則 shadcn CLI 本身就是黃金配對的執行者:
    1. 首先對每個 ui 包裝器進行分類:將使用者的檔案與其原始來源進行比對,使用 components.json 中的樣式原樣放入 URL(https://ui.shadcn.com/r/styles/<style>/<component>.json,files[0].content)。這適用於有前綴的樣式(radix-nova)以及舊版無前綴的樣式(new-york、new-york-v4、default),這些都仍然提供服務。
    2. 整個專案模式:立即將 components.json 中的樣式從 radix-<style> 改為 base-<style>。漸進模式:暫時不要更改(專案仍大部分使用 radix;更改僅在最後一個元件後進行一次);改為直接透過 URL 取得 base 變體(https://ui.shadcn.com/r/styles/base-<style>/<component>.json)。
    3. 未修改的包裝器,整個專案模式:執行 shadcn add <component> --overwrite 會以專案確切的圖示/字型/預設解析度提供 base 變體。切勿使用 --all --overwrite 批次處理;應逐個元件進行,否則你會淹沒在不相關的 registry 版本漂移中。漸進模式:切勿使用 --overwrite(它會破壞使用者仍在匯入的原始檔案);改為將取得的 base 變體內容寫入 <component>-base.tsx
    4. 自訂包裝器:取得 base 變體,並將使用者的差異重新套用上去(他們的自訂必須保留;--overwrite 會破壞它們)。可大規模運作的機械化實作:git merge-file user.tsx radix-golden.tsx base-golden.tsx(三方合併,以 radix golden 作為共同祖先)可自動解決大部分檔案;使用參考表格手動解決衝突。
    5. 對每個黃金配對檔案進行強制性的殘留掃描,包括那些合併「乾淨」的檔案:對每個檔案執行 grep -n "radix-ui\|@radix-ui\|IconPlaceholder"。Registry 有時會在變體之間重新排列函式,這會導致三方合併報告零衝突,但卻留下舊的 radix 程式碼片段。乾淨的合併並不代表檔案是乾淨的。
      此方法比重建轉換更可靠;只要配對存在就使用它。消費者/應用程式碼沒有 CLI 機制:一律根據 consumer-props.md 手動遷移。
  • 舊版樣式(new-york、new-york-v4、default):僅分類,不重播。 這些樣式沒有對應的 base 版本(沒有 base-new-york),重新定位到 base-<style> 變體會改變使用者應用程式的樣式。僅使用 radix golden 來偵測自訂,然後在使用者自己的檔案上執行轉換引擎:重新連接基本元件,保留他們確切的 class,套用 class-mapping 重新命名。他們的外觀保持不變。在舊版整個專案遷移結束時,標記(不要修正):樣式名稱對 CLI 來說仍然是 radix,因此未來的 shadcn add 會提供 radix 變體;由使用者決定是否切換樣式或手動新增。
  • 轉換引擎(備用)。 手寫的 radix 程式碼、非 shadcn 專案、未知樣式:使用 universal-patterns.md(兩種形式的匯入:radix-ui@radix-ui/react-*;asChild -> render 搭配範例;Portal>Positioner>Popup;positioner FORWARD 規則;部分重新命名)、各家族的 props 表格(overlays.mdmenus.mdform-controls.mddisclosure.mddisplay-misc.md)、class-mapping.md 用於 data-attribute/CSS-var 重寫,以及 wrapper-shapes.md 用於確切的目標形狀(tooltip arrow、SubContent 預設值、select 解剖結構)。

模式

漸進模式(預設)。「遷移 accordion」= 單一元件,絞殺藤模式:

  1. 首先偵測進行中的狀態:是否存在 <component>-base.tsx,消費者分散在舊/新匯入之間。檔案本身就是狀態;從中繼續,切勿重新開始。
  2. 如果該元件匯入其他仍使用 radix 的 ui 包裝器(select -> button),則停止並建議先從底層開始遷移這些元件。
  3. 將遷移後的版本寫入 <component>-base.tsx(原始檔案保持不變;黃金配對內容透過 URL 取得,或手動轉換,依上述策略);進行型別檢查。一次一個地重新指向消費者(匯入以及 consumer-props.md 中的呼叫端 props);每次進行型別檢查。當沒有消費者匯入原始檔案時:刪除它,將 -base 重新命名為原始名稱,將匯入改回,進行最終檢查,提交。當專案中最後一個 radix 包裝器完成時,將 components.json 改為 base-<style> 並移除 radix 相依套件。

整個專案模式(僅在明確要求時):按照相依順序進行相同的逐個元件工作(先處理葉子/共享包裝器,如 button 和 label)。包裝器完成後,根據 consumer-props.md 掃描所有應用程式碼——呼叫端的破壞面比 asChild 大得多。然後移除 radix 相依套件、安裝、完整建置。

嚴格規則

  • 絕對不要觸碰非 radix 的函式庫或其包裝器:cmdk(command)、vaul(drawer)、sonner、input-otp、react-day-picker(calendar)、recharts(chart)。將它們報告為故意未觸碰。
  • 無 Base UI 對應:AspectRatio -> CSS aspect-ratio div;Label -> 原生 <label>;VisuallyHidden -> sr-only;Direction -> Direction Provider(direction prop,而非 dir)。Popover Anchor 和 NavigationMenu Indicator 沒有對應項目:直接傳遞 + 標記。
  • button.tsx 遷移至真正的 @base-ui/react/button 基本元件,絕不使用手寫的 useRender 包裝器。
  • 行為差異會被標記,絕不默默修補(tabs 手動啟用、選單項目點擊後不關閉、nav-menu 50ms 延遲)。目標是符合 shadcn base registry 的慣用 Base UI。
  • 誠實報告:跳過/還原的檔案被標記為已標記,絕不標記為已遷移。預先存在的失敗被標記為預先存在。

驗證與報告

每個檔案進行型別檢查,每批次進行建置,最後與基線進行完整建置比較。

報告存放在專案根目錄的 .migration/ 目錄中,每個元件一個檔案:.migration/<component>.md(例如 .migration/accordion.md)。規則:

  • 每次執行會為其遷移的每個元件寫入(或完全覆蓋)該檔案。重新執行某個元件會取代其報告;絕不觸碰其他元件的檔案。
  • 多元件執行(如「遷移 alert-dialog 和 dropdown-menu」)會為每個元件寫入一個檔案,每個檔案自包含;共享的消費者掃描備註會重複出現在每個受影響的檔案中。
  • 整個專案模式會寫入每個元件的檔案,加上 .migration/project.md(相依套件交換、應用程式碼掃描摘要、最終建置結果)。
  • 沒有索引檔案。遷移狀態從磁碟推斷,而非維護:當被問到「還剩下什麼」時,掃描專案的 ui 目錄(來自 shadcn info 的 ui 別名,例如 components/ui 或 src/components/ui)以尋找剩餘的 radix 匯入。每次執行的摘要結尾都要包含這個推斷的計數(「還有 N 個包裝器使用 Radix」)。

每個 .migration/<component>.md 使用完全相同的結構(這是公開文件;報告必須符合):

# <component>

<日期,使用的策略(透過 CLI 的黃金配對 / 合併 / 引擎),一行結論>

## 已變更

<每個觸碰的檔案,說明變更內容與原因;對於任何值得注意的項目,包含檔案:行號。確認殘留掃描是乾淨的:
對此元件的檔案執行 grep -n "radix-ui\|@radix-ui">

## 未觸碰

<看似相關但故意未觸碰的檔案,附上原因(cmdk/vaul/sonner 不是 radix;無關的漂移;等等)>

## 行為變更

<編譯正常但行為不同的差異;標記,絕不修補(tabs 啟用、選單點擊關閉、延遲...)。如果沒有則留空>

## 手動驗證

<針對此基本元件家族的簡短手動 QA 檢查清單:對話框的焦點返回、選單/選擇的鍵盤導航 + 打字搜尋、tooltip 延遲感覺、slider 提交事件。具體步驟,約一分鐘的點擊操作>