Communitygithub.com

shadcn-ui/ui

React プロジェクトとコンポーネントを Radix UI から Base UI に移行します。radix からの移行、base-ui への移行、radix プリミティブの変換、shadcn プロジェクトのベースライブラリの切り替えを求められたときに使用します。単一コンポーネント(「accordion を移行」)とプロジェクト全体を処理します。

ui とは?

このスキルは、React プロジェクトの UI コンポーネントを Radix UI から @base-ui/react に移行するための自動化されたプロセスを提供します。主に shadcn/ui ベースのプロジェクトを対象としていますが、手動で Radix をラップしたコードや非 shadcn プロジェクトにも対応します。移行は「ゴールデンペア」戦略に基づき、shadcn CLI を使ってベースバリアントを取得し、ユーザーのカスタマイズを維持するために three-way merge を適用します。プログレッシブモード(コンポーネント単位)とプロジェクト全体モードの両方をサポートし、各ステップで型チェックとビルドを実行してプロジェクトの健全性を維持します。cmdk や vaul などの非 Radix ライブラリには一切触れず、動作の差異は報告のみ行います。結果は `.migration/` ディレクトリに詳細なレポートとして出力されます。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/shadcn-ui/ui/tree/HEAD/skills/migrate-radix-to-base

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

Radix UI → Base UI 移行ガイド

shadcn ラッパー、手書きの Radix コンポジション、およびそれらを使用するコードを @base-ui/react に移行します。各ステップでプロジェクトがビルド可能な状態を保ちます。正確に作業し、マッピングを推測しないでください。プロパティやパーツがこれらのリファレンスファイルにない場合は、変換前に 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 ツリーを要求し、ブランチで作業し、コンポーネントごとに 1 コミットとします。
  4. 依存関係に触れる前にベースラインチェックを実行します。プロジェクトの型チェック/ビルドを実行し、既存の障害が決してあなたのせいにされないようにします。
  5. @base-ui/react を Radix と一緒にインストールします。Radix パッケージは、最後のコンポーネントが移行された後にのみ削除されます(両方共存可能)。

戦略:最初にゴールデンペア、次に変換エンジン

  • CLI によるゴールデンペア(推奨)。 プロジェクトが既知のスタイル(radix-<style>)を持つ shadcn の場合、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 です。変更は最後のコンポーネントの後に 1 回行われます)。代わりに、URL から直接ベースバリアントを取得します(https://ui.shadcn.com/r/styles/base-<style>/<component>.json)。
    3. カスタマイズされていないラッパー、プロジェクト全体モード:shadcn add <component> --overwrite を実行すると、プロジェクトの正確なアイコン/フォント/プリセット解決でベースバリアントが配信されます。--all --overwrite は絶対に使用しないでください。コンポーネントごとに実行します。そうしないと、無関係なレジストリバージョンのドリフトに埋もれます。プログレッシブモード:絶対に --overwrite を使用しないでください(コンシューマーがまだインポートするオリジナルを破壊します)。代わりに、取得したベースバリアントの内容を <component>-base.tsx に書き込みます。
    4. カスタマイズされたラッパー:ベースバリアントを取得し、その上にユーザーの差分を再適用します(カスタマイズは維持されなければなりません。--overwrite はそれらを破壊します)。大規模に機能する機械的な実装:git merge-file user.tsx radix-golden.tsx base-golden.tsx(three-way マージ、Radix ゴールデンを祖先として使用)でほとんどのファイルを自動解決します。競合はリファレンステーブルを使用して手動で解決します。
    5. すべてのゴールデンペアファイルに対して必須の残骸スイープを実行します。「クリーン」にマージされたファイルも含みます。grep -n "radix-ui\|@radix-ui\|IconPlaceholder" をファイルごとに実行します。レジストリがバリアント間で関数を並べ替えることがあり、three-way マージが競合ゼロを報告しながら、古い Radix の断片をそのまま残すことがあります。クリーンマージはクリーンファイルの証明にはなりません。 これは変換を再構築するよりも信頼性が高いため、ペアが存在する場合は常にこれを使用します。コンシューマー/アプリコードには CLI メカニズムがないため、consumer-props.md に従って常に手動で移行します。
  • レガシースタイル(new-york, new-york-v4, default):分類のみ、再適用はなし。 これらにはベースの対応物がなく(base-new-york はありません)、base- バリアントに再ターゲットするとユーザーのアプリのスタイルが変わります。Radix ゴールデンのみを使用してカスタマイズを検出し、次にユーザー自身のファイルで変換エンジンを実行します。プリミティブを配線し直し、正確なクラスを保持し、クラスマッピングの名前変更を適用します。ユーザーの見た目はそのまま維持されます。レガシースタイルのプロジェクト全体の移行が終了したら、フラグを立てます(修正はしません)。スタイル名は CLI に対して依然として Radix として読み取られるため、将来の shadcn add は Radix バリアントを配信します。ユーザーがスタイルを切り替えるか手動で追加するかを決定します。
  • 変換エンジン(フォールバック)。 手書きの Radix コード、非 shadcn プロジェクト、不明なスタイル:universal-patterns.md(両方の形式でのインポート:radix-ui と @radix-ui/react-*、asChild → render の実例付き、Portal > Positioner > Popup、positioner の FORWARD ルール、パーツ名の変更)、ファミリー別のプロップス テーブル(overlays.md, menus.md, form-controls.md, disclosure.md, display-misc.md)、データ属性/CSS 変数の書き換え用の class-mapping.md、正確なターゲット形状用の wrapper-shapes.md(ツールチップの矢印、SubContent のデフォルト、select の構造)を使用して変換します。

モード

プログレッシブ(デフォルト)。 「accordion を移行」= 1 コンポーネント、ストラングラーフィグパターン:

  1. 最初に進行中の状態を検出します。既存の <component>-base.tsx、新旧のインポートが混在するコンシューマー。ファイル自体が状態です。再開し、決して再スタートしません。
  2. コンポーネントがまだ Radix 上にある他の ui ラッパーをインポートしている場合(select → button)、停止し、それらを最初にボトムアップで移行することを推奨します。
  3. 移行済みバージョンを <component>-base.tsx に書き込みます(オリジナルはそのまま。ゴールデンペアの内容は URL で取得するか、上記の戦略に従って手動で変換)。型チェックを行います。コンシューマーを 1 つずつ再ポイントします(インポートと consumer-props.md の呼び出しサイトプロップス)。各変更後に型チェックを行います。コンシューマーがオリジナルをインポートしなくなったら、オリジナルを削除し、-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(dir ではなく direction プロップ)。Popover Anchor と NavigationMenu Indicator には同等のものがないため、影響を及ぼさずにそのまま渡すか、フラグを立てます。
  • button.tsx は、手書きの useRender ラッパーではなく、本物の @base-ui/react/button プリミティブに移行します。
  • 動作の差異はフラグを立て、静かにパッチを当てることはしません(タブの手動アクティベーション、クリック時に閉じないメニュー項目、nav-menu の 50ms 遅延など)。ターゲットは、shadcn ベースレジストリに一致する慣用的な Base UI です。
  • 正直な報告:スキップ/元に戻したファイルは、移行済みとしてではなく、フラグ付きとしてリストされます。既存の障害は、既存のものとして名前を付けます。

検証とレポート

ファイルごとに型チェック、バッチごとにビルド、最後にベースラインと比較してフルビルドを実行します。

レポートはプロジェクトルートの .migration/ ディレクトリに、コンポーネントごとに 1 ファイル配置されます:.migration/<component>.md(例:.migration/accordion.md)。ルール:

  • 各実行は、移行した各コンポーネントのファイルを書き込むか、完全に上書きします。コンポーネントを再実行すると、そのレポートは置き換えられます。他のコンポーネントのファイルには決して触れません。
  • 複数コンポーネントの実行(「alert-dialog と dropdown-menu を移行」)は、コンポーネントごとに 1 ファイルを書き込み、それぞれ自己完結型です。共有のコンシューマースイープノートは、影響を受けるすべてのファイルで繰り返されます。
  • プロジェクト全体モードでは、コンポーネントごとのファイルに加えて、.migration/project.md(依存関係の交換、アプリコードのスイープサマリー、最終ビルド結果)を書き込みます。
  • インデックスファイルはありません。移行ステータスは管理されず、ディスクから導出されます。「何が残っているか」と尋ねられたら、プロジェクトの ui ディレクトリ(shadcn info からの ui エイリアス、例:components/ui または src/components/ui)をスキャンして、残っている Radix インポートを確認します。すべての実行のサマリーを、この導出されたカウントで終了します(「N 個のラッパーが Radix に残っています」)。

各 .migration/<component>.md は、正確にこの構造を使用します(これは公開されて文書化されています。レポートはそれに一致する必要があります):

# <component>

<日付、使用された戦略(CLI / マージ / エンジンによるゴールデンペア)、1行の評価>

## 変更されたもの

<触れたすべてのファイル、何が変更され、なぜ変更されたか。注目すべき点は file:line を含めてください。残骸スキャンがクリーンであることを確認します:
このコンポーネントのファイルに対して grep -n "radix-ui\|@radix-ui">

## そのままにしておいたもの

<関連しているように見えるが意図的に触れなかったファイル、理由付き(cmdk/vaul/sonner は Radix ではない、無関係なドリフトなど)>

## 動作の変更

<コンパイルは正常に通るが動作が異なる差異。フラグを立て、決してパッチを当てません(タブのアクティベーション、メニューのクリック時閉じ、遅延...)。ない場合は空のセクション>

## 手動で確認する項目

<このプリミティブファミリーの短い手動 QA チェックリスト:ダイアログのフォーカスリターン、メニュー/選択のキーボードナビゲーションとタイプアヘッド、ツールチップの遅延感覚、スライダーのコミットイベント。具体的な手順、1分間のクリックテスト>

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

関連スキル