Skip to content

refactor: shadcn consistency audit — idioms, calendar v9, registry deps - #64

Merged
junwen-k merged 7 commits into
nextfrom
refactor/shadcn-consistency
Jul 17, 2026
Merged

junwen-k merged 7 commits into
nextfrom
refactor/shadcn-consistency

Conversation

@junwen-k

@junwen-k junwen-k commented Jul 16, 2026

Copy link
Copy Markdown
Owner

Summary

Follow-up to #63: audited all 36 vendored components/ui/ files against the live base-nova registry payloads and every registry component/example against current shadcn writing idioms.

Audit verdict: the vendored files are current within the limits of the released shadcn@4.13.0 package (live payloads reference unreleased cn-* utilities we correctly substitute). Two real drifts and a handful of idiom violations were found and fixed:

Fixes

  • calendar.tsx (real bug): the vendored copy still used the react-day-picker v8 classNames API (caption, nav_button, head_row, cell) — dead keys against the installed v9.7.0, so the calendar rendered on v9 defaults. Rebuilt from the current base-nova calendar (getDefaultClassNames, --cell-size/--cell-radius, captionLayout, CalendarDayButton), with IconPlaceholder resolved to lucide chevrons and unreleased cn-calendar-* utilities substituted with their released equivalents. Also wired the ref upstream forgot, so the focus effect actually works.
  • registry.json (real bug): internal registryDependencies pointed at dead https://ui-x.junwen-k.dev/r/*.json URLs, breaking transitive resolution of shadcn add junwen-k/ui-x/<item>. Switched all 14 refs to the documented GitHub item-address form (junwen-k/ui-x/<item>). shadcn registry validate passes (26 items).
  • attachment.tsx: restored shimmer and scroll-fade-x (both ship in released shadcn/tailwind.css; they'd been over-substituted). no-scrollbar stays in place of the unreleased scrollbar-none.
  • confirmer.tsx: action button now composes AlertDialogAction instead of a raw Button; description moved inside AlertDialogHeader; exports grouped at the bottom.
  • Idioms: dropped a stray displayName (badge-group), import Reactimport * as React (description-list), ComponentPropsWithoutRefComponentProps (time), raw <label>Label (password-input example), useMemo-wrapped render prop → inline (phone-input example).
  • ROADMAP: synced 4b/4c checkboxes now shipped by feat!: port all primitives and demos to Base UI #63 + this branch (Radix removal, ports, demo rewrite, registry.json/install docs).

Verification

  • tsc --noEmit clean, shadcn registry validate passes, prettier applied.
  • Browser-verified: date-picker calendar (nav, today ring, selection, focus), confirmer dialog (confirm resolves), password-input, badge-group, dropzone, phone-input pages — consoles clean.
  • Fixed in follow-up commit: the hydration mismatch on the phone-input pages from server/client Intl.DisplayNames disagreement ("Falkland Islands (Islas Malvinas)" vs "Falkland Islands") — replaced with the static react-phone-number-input/locale/en labels (already a dependency).

🤖 Generated with Claude Code

junwen-k and others added 6 commits July 16, 2026 21:11
Replace the raw Button with AlertDialogAction, move the description
inside AlertDialogHeader to match the alert-dialog composition, and
group exports at the bottom per shadcn convention.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Drop the stray displayName from badge-group, use namespace React
imports in description-list, switch time to React.ComponentProps,
replace the hand-rolled label in the password-input checkbox example
with the Label component, and pass the phone-input render prop inline
instead of wrapping it in useMemo.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The vendored copy still used the react-day-picker v8 classNames API
(caption, nav_button, head_row, cell) whose keys don't exist in the
installed v9, so every class was dead and the calendar rendered on
v9 defaults. Replace it with the current base-nova calendar
(getDefaultClassNames, --cell-size/--cell-radius, captionLayout,
CalendarDayButton), resolving the site-internal IconPlaceholder to
lucide chevrons and the unreleased cn-calendar-* utilities to their
released equivalents.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
shimmer and scroll-fade-x ship in the released shadcn tailwind.css,
so the animate-pulse substitute and the missing group scroll fade
were over-substitutions; no-scrollbar stays in place of the still
unreleased scrollbar-none.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
registryDependencies pointed at https://ui-x.junwen-k.dev/r/*.json,
which no longer exists on next (no public/r output), breaking
transitive resolution of shadcn add. Use the GitHub item address form
(junwen-k/ui-x/<item>) shadcn documents for same-repo dependencies;
plain shadcn item names are untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Mark the Radix removal, component ports, demo rewrite and
registry.json/install-docs items shipped (PR #63 and this branch).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
ui-x Error Error Jul 17, 2026 3:42am
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
v3-ui-x Skipped Skipped Jul 17, 2026 3:42am

Intl.DisplayNames resolves region names against the runtime ICU data,
and Node and Chrome disagree on a few regions (e.g. FK renders as
"Falkland Islands (Islas Malvinas)" on the server but "Falkland
Islands" in the browser), causing a React hydration error. Use the
static en locale labels from react-phone-number-input, which is
already a dependency of phone-input-primitive.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel
vercel Bot temporarily deployed to Preview – v3-ui-x July 17, 2026 03:42 Inactive
@junwen-k
junwen-k merged commit 6877abf into next Jul 17, 2026
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant