Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 16 additions & 8 deletions packages/components/shadcn-components.json
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@
"dependencies": [
"radix-ui"
],
"registryDependencies": []
"registryDependencies": [],
"localEdits": "Tailwind v4 syntax. Local uses `origin-(--radix-context-menu-content-transform-origin)`; upstream still ships v3's `origin-[--radix-…]`, which on Tailwind 4.x compiles to the bare `transform-origin: --radix-…` rather than `var(--radix-…)` — invalid CSS that browsers drop, so the open/close animation would scale from the default origin instead of the one Radix computes. Verified against tailwindcss 4.3.3: the paren form emits `var()`, the bracket form does not. Same for `max-h-(--radix-context-menu-content-available-height)`. Applied repo-wide in 925051db6; do not revert piecemeal."
},
"dialog": {
"source": "https://ui.shadcn.com/r/styles/default/dialog.json",
Expand All @@ -148,7 +149,8 @@
"dependencies": [
"radix-ui"
],
"registryDependencies": []
"registryDependencies": [],
"localEdits": "Tailwind v4 syntax. Local uses `origin-(--radix-dropdown-menu-content-transform-origin)`; upstream still ships v3's `origin-[--radix-…]`, which on Tailwind 4.x compiles to the bare `transform-origin: --radix-…` rather than `var(--radix-…)` — invalid CSS that browsers drop, so the open/close animation would scale from the default origin instead of the one Radix computes. Verified against tailwindcss 4.3.3: the paren form emits `var()`, the bracket form does not. Applied repo-wide in 925051db6; do not revert piecemeal."
},
"form": {
"source": "https://ui.shadcn.com/r/styles/default/form.json",
Expand All @@ -160,14 +162,16 @@
"registryDependencies": [
"button",
"label"
]
],
"localEdits": "FormItem accepts `Record<`data-${string}`, string | undefined>` on top of upstream's `React.HTMLAttributes<HTMLDivElement>`, so callers can attach a stable `data-testid` to the field wrapper (ADR-0054 testability contract). Upstream has no equivalent; syncing removes it and the locators go with it."
},
"hover-card": {
"source": "https://ui.shadcn.com/r/styles/default/hover-card.json",
"dependencies": [
"radix-ui"
],
"registryDependencies": []
"registryDependencies": [],
"localEdits": "Tailwind v4 syntax. Local uses `origin-(--radix-hover-card-content-transform-origin)`; upstream still ships v3's `origin-[--radix-…]`, which on Tailwind 4.x compiles to the bare `transform-origin: --radix-…` rather than `var(--radix-…)` — invalid CSS that browsers drop, so the open/close animation would scale from the default origin instead of the one Radix computes. Verified against tailwindcss 4.3.3: the paren form emits `var()`, the bracket form does not. Applied repo-wide in 925051db6; do not revert piecemeal."
},
"input": {
"source": "https://ui.shadcn.com/r/styles/default/input.json",
Expand All @@ -193,7 +197,8 @@
"dependencies": [
"radix-ui"
],
"registryDependencies": []
"registryDependencies": [],
"localEdits": "Tailwind v4 syntax. Local uses `origin-(--radix-menubar-content-transform-origin)`; upstream still ships v3's `origin-[--radix-…]`, which on Tailwind 4.x compiles to the bare `transform-origin: --radix-…` rather than `var(--radix-…)` — invalid CSS that browsers drop, so the open/close animation would scale from the default origin instead of the one Radix computes. Verified against tailwindcss 4.3.3: the paren form emits `var()`, the bracket form does not. Applied repo-wide in 925051db6; do not revert piecemeal."
},
"navigation-menu": {
"source": "https://ui.shadcn.com/r/styles/default/navigation-menu.json",
Expand All @@ -214,7 +219,8 @@
"dependencies": [
"radix-ui"
],
"registryDependencies": []
"registryDependencies": [],
"localEdits": "Tailwind v4 syntax. Local uses `origin-(--radix-popover-content-transform-origin)`; upstream still ships v3's `origin-[--radix-…]`, which on Tailwind 4.x compiles to the bare `transform-origin: --radix-…` rather than `var(--radix-…)` — invalid CSS that browsers drop, so the open/close animation would scale from the default origin instead of the one Radix computes. Verified against tailwindcss 4.3.3: the paren form emits `var()`, the bracket form does not. Applied repo-wide in 925051db6; do not revert piecemeal."
},
"progress": {
"source": "https://ui.shadcn.com/r/styles/default/progress.json",
Expand Down Expand Up @@ -289,7 +295,8 @@
"sonner",
"next-themes"
],
"registryDependencies": []
"registryDependencies": [],
"localEdits": "Re-exports `toast` from the module (`import { Toaster as Sonner, toast }` / `export { Toaster, toast }`) so consumers get it from @object-ui/components rather than depending on `sonner` directly — plugin-form, plugin-kanban and others import it that way. Upstream exports only `Toaster`; syncing breaks those imports."
},
"switch": {
"source": "https://ui.shadcn.com/r/styles/default/switch.json",
Expand Down Expand Up @@ -341,7 +348,8 @@
"dependencies": [
"radix-ui"
],
"registryDependencies": []
"registryDependencies": [],
"localEdits": "Tailwind v4 syntax. Local uses `origin-(--radix-tooltip-content-transform-origin)`; upstream still ships v3's `origin-[--radix-…]`, which on Tailwind 4.x compiles to the bare `transform-origin: --radix-…` rather than `var(--radix-…)` — invalid CSS that browsers drop, so the open/close animation would scale from the default origin instead of the one Radix computes. Verified against tailwindcss 4.3.3: the paren form emits `var()`, the bracket form does not. Applied repo-wide in 925051db6; do not revert piecemeal."
}
},
"customComponents": {
Expand Down
27 changes: 24 additions & 3 deletions scripts/shadcn-sync.js
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,10 @@ async function checkComponent(name, manifest) {
status = 'modified';
message = `${localOnly.length} local line(s) upstream lacks — --update would refuse`;
if (upstreamOnly.length > 0) message += `, ${upstreamOnly.length} upstream line(s) pending`;
// Divergence with a recorded reason is a decision; divergence without
// one is an open question. Surfacing the split makes the untriaged
// components a visible to-do instead of undifferentiated noise.
message += componentInfo.localEdits ? ' [documented]' : ' [UNDOCUMENTED]';
} else if (upstreamOnly.length > 0) {
status = 'outdated';
message = `${upstreamOnly.length} upstream line(s) to pick up — safe to sync`;
Expand All @@ -272,6 +276,7 @@ async function checkComponent(name, manifest) {
shadcnLines,
localOnly: localOnly.length,
upstreamOnly: upstreamOnly.length,
documented: Boolean(componentInfo.localEdits),
message,
};
} catch (fetchError) {
Expand Down Expand Up @@ -349,10 +354,20 @@ async function checkAllComponents() {
}

if (results.modified.length > 0) {
const undocumented = results.modified.filter((r) => !r.documented);
const documented = results.modified.filter((r) => r.documented);

log('\nThese carry local edits a sync would delete:', 'yellow');
log(` ${results.modified.map((r) => `${r.name}(${r.localOnly})`).join(', ')}`, 'dim');
log(' Port the edits onto the new upstream version by hand, or --force to', 'dim');
log(' take upstream as-is. `--diff <name>` shows both sides.', 'dim');
if (documented.length > 0) {
log(` documented (${documented.length}): ${documented.map((r) => `${r.name}(${r.localOnly})`).join(', ')}`, 'dim');
log(' → reason recorded in `localEdits` in shadcn-components.json', 'dim');
}
if (undocumented.length > 0) {
log(` UNDOCUMENTED (${undocumented.length}): ${undocumented.map((r) => `${r.name}(${r.localOnly})`).join(', ')}`, 'yellow');
log(' → nobody has written down why these diverge. Until someone does,', 'dim');
log(' there is no way to tell a deliberate fix from stale drift.', 'dim');
log(' Triage with `--diff <name>`, then add a `localEdits` note.', 'dim');
}
}

return results;
Expand Down Expand Up @@ -429,6 +444,12 @@ async function updateComponent(name, manifest, options = {}) {
log(`✗ Refusing to overwrite ${name}.tsx — ${lost.length} local line(s) upstream does not have:`, 'red');
lost.slice(0, 8).forEach((l) => log(` ${l.length > 96 ? l.slice(0, 96) + '…' : l}`, 'dim'));
if (lost.length > 8) log(` … and ${lost.length - 8} more`, 'dim');
if (componentInfo.localEdits) {
// Someone already worked out why this diverges. Say so here rather
// than making the next person re-derive it from a wall of diff.
log(` Why it diverges (localEdits in shadcn-components.json):`, 'cyan');
log(` ${componentInfo.localEdits}`, 'dim');
}
log(` Overwriting deletes these. Port them onto the new upstream version by hand,`, 'yellow');
log(` or re-run with --force if they are genuinely obsolete.`, 'yellow');
return 'skipped';
Expand Down
Loading