Radix UI -> Base UI-Migration
Sie migrieren shadcn-Wrapper, handgefertigte Radix-Compositions und deren
Verbraucher zu @base-ui/react und halten das Projekt dabei in jedem Schritt
buildbar. Seien Sie präzise; raten Sie niemals ein Mapping. Wenn ein Prop
oder Part nicht in diesen Referenzdateien enthalten ist, prüfen Sie
node_modules/@base-ui/react/**/*.d.ts vor der Transformation und
dokumentieren Sie Lücken im Bericht.
Preflight (immer)
npx shadcn@latest info --json(oder den Projekt-Runner): gibt die aktuelle Basis, den STIL (z.B.radix-lyra), die Tailwind-Version, Aliase, installierte Komponenten und den Paketmanager aus. Vertrauen Sie ihm mehr als Ihrer eigenen Schlussfolgerung.- Erkennen Sie den Paketmanager (packageManager-Feld / Lockfile: pnpm-lock.yaml, bun.lock, yarn.lock, package-lock.json) und verwenden Sie IHN für jede Installation. Lassen Sie niemals ein veraltetes Lockfile zurück.
- Erfordern Sie einen sauberen Git-Baum; arbeiten Sie auf einem Branch; ein Commit pro Komponente.
- Basis-Check VOR dem Berühren von Abhängigkeiten: Führen Sie Typecheck/Build des Projekts aus, damit bereits vorhandene Fehler niemals Ihnen zugeschrieben werden.
- Installieren Sie
@base-ui/reactzusammen mit Radix. Radix-Pakete werden erst entfernt, nachdem die LETZTE Komponente migriert wurde (beide koexistieren problemlos).
Strategie: Zuerst goldenes Paar, dann Transformations-Engine
- Goldenes Paar über die CLI (bevorzugt). Wenn das Projekt ein shadcn mit
einem bekannten Stil ist (
radix-<style>), ist die shadcn-CLI selbst der Ausführer des goldenen Paares:- Klassifizieren Sie zuerst JEDEN ui-Wrapper: Diffen Sie die Datei des
Benutzers gegen ihren Original-Ursprung, wobei Sie den
components.json-Stil WÖRTLICH in der URL verwenden
(
https://ui.shadcn.com/r/styles/<style>/<component>.json, files[0].content). Dies funktioniert für präfixierte Stile (radix-nova) UND legacy unfixierte (new-york, new-york-v4, default), die alle noch ausgeliefert werden. - GANZES-PROJEKT-Modus: Flip
components.jsonStilradix-<style>->base-<style>jetzt. PROGRESSIVER Modus: NICHT flippen (das Projekt ist noch größtenteils Radix; der Flip erfolgt einmal, nach der letzten Komponente); Base-Varianten stattdessen direkt per URL abrufen (https://ui.shadcn.com/r/styles/base-<style>/<component>.json). - UNVERÄNDERTE Wrapper, Ganzes-Projekt-Modus:
shadcn add <component> --overwriteliefert die Base-Variante mit den exakten Icon/Font/Preset-Auflösungen des Projekts. Nie--all --overwritebulk-verwenden; gehen Sie Komponente für Komponente vor, sonst ertrinken Sie in unzusammenhängender Registry-Versionsdrift. PROGRESSIVER Modus: niemals--overwriteverwenden (es zerstört das Original, das Verbraucher noch importieren); schreiben Sie stattdessen den abgerufenen Base-Varianten-Inhalt in<component>-base.tsx. - ANGEPASSTE Wrapper: Holen Sie die Base-Variante und spielen Sie den
Benutzer-Diff darauf ab (deren Anpassungen müssen ÜBERLEBEN;
--overwritewürde sie zerstören). Mechanische Implementierung, die im Maßstab funktioniert:git merge-file user.tsx radix-golden.tsx base-golden.tsx(Drei-Wege- Merge, Radix golden als Vorfahre) löst die meisten Dateien automatisch auf; Konflikte von Hand mit den Referenztabellen lösen. - VERPFLICHTENDER Reste-Durchlauf bei JEDER goldenen Paar-Datei,
einschließlich solcher, die „sauber“ gemergt wurden:
grep -n "radix-ui\|@radix-ui\|IconPlaceholder"pro Datei. Die Registry ordnet manchmal Funktionen zwischen Varianten neu, was dazu führt, dass Drei-Wege-Merges null Konflikte melden, aber alte Radix-Stücke hinterlassen. Ein sauberer Merge ist KEIN Beweis für eine saubere Datei. Dies ist zuverlässiger als das Rekonstruieren von Transformationen; verwenden Sie es, wann immer das Paar existiert. Verbraucher-/App-Code hat keinen CLI-Mechanismus: migrieren Sie ihn immer von Hand gegenconsumer-props.md.
- Klassifizieren Sie zuerst JEDEN ui-Wrapper: Diffen Sie die Datei des
Benutzers gegen ihren Original-Ursprung, wobei Sie den
components.json-Stil WÖRTLICH in der URL verwenden
(
- Legacy-Stile (new-york, new-york-v4, default): nur Klassifikation, kein
Replay. Diese haben keine Base-Entsprechung (es gibt kein base-new-york),
und ein Neuausrichten auf eine base--Variante würde die App des
Benutzers umgestalten. Verwenden Sie das Radix-Golden NUR, um
Anpassungen zu erkennen, und führen Sie dann die Transformations-Engine auf
der eigenen Datei des Benutzers aus: Verkabeln Sie Primitives neu, behalten
Sie deren exakte Klassen, wenden Sie Class-Mapping-Umbenennungen an. Deren
Aussehen bleibt ihres. Am Ende einer Legacy-Ganzes-Projekt-Migration FLAGGEN
(nicht beheben): der Stilname liest sich für die CLI immer noch als radix,
daher wird zukünftiges
shadcn addRadix-Varianten liefern; der Benutzer entscheidet, ob er den Stil wechselt oder manuell hinzufügt. - Transformations-Engine (Fallback). Handgefertigter Radix-Code,
Nicht-shadcn-Projekte, unbekannte Stile: transformieren Sie mit
universal-patterns.md(Importe in BEIDEN Formen:radix-uiund@radix-ui/react-*; asChild->render mit dem durchgearbeiteten Beispiel; Portal>Positioner>Popup; die Positioner-FORWARD-Regel; Part-Umbenennungen), den Pro-Family-Props-Tabellen (overlays.md,menus.md,form-controls.md,disclosure.md,display-misc.md),class-mapping.mdfür Datenattribut/CSS-Var-Umschreibungen undwrapper-shapes.mdfür exakte Zielformen (Tooltip-Pfeil, SubContent-Standardwerte, Select-Anatomie).
Modi
Progressiv (Standard). „Migriere Accordion“ = eine Komponente, Strangler-Fig:
- Erkennen Sie zuerst den laufenden Fortschrittszustand: eine bestehende
<component>-base.tsx, Verbraucher aufgeteilt zwischen alten/neuen Importen. Die Dateien SIND der Zustand; setzen Sie fort, beginnen Sie nie neu. - Wenn die Komponente andere ui-Wrapper importiert, die noch auf Radix sind (select -> button), STOPPEN und empfehlen, diese zuerst, von unten nach oben, zu migrieren.
- Schreiben Sie die migrierte Version nach
<component>-base.tsx(Original unberührt; goldenes Paar-Inhalt per URL abgerufen oder von Hand transformiert, gemäß der obigen Strategie); Typecheck. Verbraucher EINEN NACH DEM ANDEREN umstellen (Importe + die Aufruf-Props inconsumer-props.md); jeden Typecheck. Wenn kein Verbraucher das Original importiert: löschen,-base-> Original umbenennen, Importe zurückflippen, finaler Check, Commit. Wenn der LETZTE Radix-Wrapper im Projekt finalisiert ist,components.jsonaufbase-<style>flippen und Radix-Abhängigkeiten entfernen.
Ganzes Projekt (nur wenn explizit verlangt): gleiche Arbeit pro
Komponente in Abhängigkeitsreihenfolge (Blatt-/gemeinsame Wrapper wie Button
und Label zuerst). Nach den Wrappern ALLE App-Code gegen consumer-props.md
durchkämmen – die Bruchfläche an den Aufrufstellen ist viel größer als bei
asChild. Dann Radix-Abhängigkeiten entfernen, installieren, voller Build.
Harte Regeln
- NIEMALS Nicht-Radix-Bibliotheken oder deren Wrapper anfassen: cmdk (command), vaul (drawer), sonner, input-otp, react-day-picker (calendar), recharts (chart). Melden Sie sie als absichtlich unberührt.
- Keine Base-UI-Entsprechung: AspectRatio -> CSS aspect-ratio div; Label ->
natives
<label>; VisuallyHidden ->sr-only; Direction -> Direction Provider (direction-Prop, nichtdir). Popover Anchor und NavigationMenu Indicator haben kein Äquivalent: inerter Passthrough + Flag. button.tsxwird zum ECHTEN@base-ui/react/button-Primitive migriert, niemals zu einem handgefertigten useRender-Wrapper.- Verhaltensunterschiede werden GEFLAGT, niemals stillschweigend behoben (Tabs manuelle Aktivierung, Menüeinträge schließen nicht bei Klick, nav-menu 50ms Verzögerung). Ziel ist idiomatisches Base UI, das dem shadcn-Basis-Registry entspricht.
- Ehrliche Berichterstattung: übersprungene/rückgängig gemachte Dateien werden als geflaggt aufgelistet, niemals als migriert. Bereits vorhandene Fehler werden als bereits vorhanden benannt.
Verifizieren und berichten
Typecheck pro Datei, Build pro Charge, voller Build am Ende gegen die Basislinie.
Berichte leben in einem .migration/-Verzeichnis im Projektstamm, EINE
DATEI PRO KOMPONENTE: .migration/<component>.md (z.B.
.migration/accordion.md). Regeln:
- Jeder Lauf schreibt (oder überschreibt vollständig) die Datei für jede Komponente, die er migriert hat. Ein erneuter Lauf einer Komponente ersetzt ihren Bericht; berühren Sie niemals die Dateien anderer Komponenten.
- Ein Multi-Komponenten-Lauf („migriere alert-dialog und dropdown-menu“) schreibt eine Datei pro Komponente, jede in sich geschlossen; gemeinsame Verbraucher-Durchlauf-Notizen werden in jeder betroffenen Datei wiederholt.
- Der Ganzes-Projekt-Modus schreibt die Dateien pro Komponente plus
.migration/project.md(Abhängigkeitstausch, App-Code-Durchlauf- Zusammenfassung, endgültiges Build-Ergebnis). - Es gibt KEINE Indexdatei. Der Migrationsstatus wird von der Festplatte abgeleitet, nicht verwaltet: Scannen Sie das ui-Verzeichnis des Projekts (das ui-Alias aus shadcn info, z.B. components/ui oder src/components/ui) nach verbleibenden Radix-Importen, wenn gefragt wird, „was noch übrig ist“. Beenden Sie jeden Lauf mit einer Zusammen- fassung dieser abgeleiteten Anzahl („N Wrapper bleiben noch auf Radix“).
Jede .migration/<component>.md verwendet GENAU diese Struktur (sie ist
öffentlich dokumentiert; Berichte müssen ihr entsprechen):
# <component>
<Datum, verwendete Strategie (goldenes Paar über CLI / Merge / Engine),
einzeiliges Urteil>
## Geändert
<jede berührte Datei, mit was geändert wurde und warum; fügen Sie datei:zeile
für alles Bemerkenswerte hinzu. Bestätigen Sie, dass der Reste-Durchlauf
sauber ist:
grep -n "radix-ui\|@radix-ui" für die Dateien dieser Komponente>
## In Ruhe gelassen
<Dateien, die relevant aussehen, aber absichtlich nicht berührt wurden, mit
dem Grund (cmdk/vaul/sonner sind nicht radix; unabhängiger Drift; etc.)>
## Verhaltensänderungen
<Unterschiede, die problemlos kompilieren, sich aber anders verhalten;
geflaggt, niemals stillschweigend behoben (Tabs-Aktivierung, Menü-
Schließen-bei-Klick, Verzögerungen...). Leerer Abschnitt, wenn keine>
## Von Hand verifizieren
<kurze manuelle QA-Checkliste für diese Primitive-Familie:
Fokusrückkehr bei Dialogen, Tastaturnavigation + Typeahead bei Menüs/Select,
Gefühl der Tooltip-Verzögerung, Commit-Ereignisse des Sliders. Konkrete
Schritte, eine Minute Klicken>