Skip to content

feat!: port all primitives and demos to Base UI - #63

Merged
junwen-k merged 14 commits into
nextfrom
feat/port-password-input
Jul 16, 2026
Merged

junwen-k merged 14 commits into
nextfrom
feat/port-password-input

Conversation

@junwen-k

Copy link
Copy Markdown
Owner

Summary

Ports the entire registry from Radix UI to Base UI (ROADMAP Phase 4c), using the password-input pilot as the blueprint. Radix is fully excised from apps/v4.

  • Primitives ported (one commit per wave): password-input, timeline/virtualizer/use-timescape, dropzone, date-time fields, phone-input, emoji-picker, badge-group, date-picker, sortable — all rebuilt on @base-ui/react idioms (render composition, useControlled, useStableCallback).
  • Form plumbing replaced: components/ui/form.tsx deleted in favor of the base-nova field.tsx components; all 13 example form demos plus the card demo converted to Controller + Field composition. The card demo's submit button is now actually wired to its form (latent bug).
  • Dependencies: all 23 @radix-ui/* packages dropped from package.json and the lockfile (remaining lockfile mentions are transitive).
  • Docs: Radix wording swept from installation/index/primitives pages; virtualizer Scroll Area and Select guides rewritten to match the Base UI demo code.
  • Follow-up fix: timescape form demos now pass field.value ?? null so Base UI's useControlled stays in controlled mode from first render (react-hook-form fields without defaultValues start undefined, which previously tripped the uncontrolled→controlled dev warning).

Verification

  • tsc --noEmit clean; prettier clean.
  • Browser-checked form demos: empty submits render FieldError (role="alert") with focus recovery; typing into the date-time-range field produces no controlled/uncontrolled warning; console clean throughout.

Out of scope (pre-existing)

  • calendar.tsx still uses v8-era classNames (deferred ROADMAP nova item).
  • virtualizer-table demo has a module-scope faker hydration mismatch.
  • Registry payloads (public/r) are rebuilt on feat/style-refresh, not this branch.

🤖 Generated with Claude Code

junwen-k and others added 14 commits July 16, 2026 01:37
Replace Radix utilities with Base UI's useRender, mergeProps, and
useControlled. The asChild prop is replaced by render, and the toggle
and indicator now expose the open state via the data-visible attribute
instead of data-state.

BREAKING CHANGE: PasswordInputPrimitive components no longer accept
asChild; use the render prop instead. data-state="visible|hidden" is
replaced by the presence-based data-visible attribute.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Match the prevailing shadcn/ui style (carousel, form) of inline
provider values instead of memoizing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…e UI

Swap Radix Slot, Primitive, compose-refs, and useControllableState for
Base UI's useRender, mergeProps, useControlled, and useStableCallback.

BREAKING CHANGE: Timeline and Virtualized components no longer accept
asChild; use the render prop instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Swap Radix Primitive and composeEventHandlers for Base UI's useRender
and mergeProps in both the primitive and styled components.

BREAKING CHANGE: Dropzone components no longer accept asChild; use the
render prop instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Convert date-time-field and date-time-range-field primitives from Radix
Primitive/useComposedRefs to Base UI useRender, wiring timescape refs
through useRender's ref param and gating AmPm with the enabled option.
Styled wrappers and date-picker segment slots move from asChild to
render props.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Replace useControllableState with useControlled/useStableCallback for
the value and country states, and swap the Input's asChild/children
composition for a Base UI render element that backs
react-phone-number-input's inputComponent.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Replace Radix popover with Base UI popover parts, adding a Positioner
part and context-based anchor plumbing to preserve Anchor support.
Value and month state now use useControlled with null-based values.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Swap Radix Primitive, Slot, compose-refs and portal helpers for
Base UI useRender and mergeProps, with the drag overlay portaled
via react-dom createPortal. asChild composition becomes render props.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Vendor the base-nova field components and delete the Radix-based
form.tsx, converting all form demos to Controller + Field composition.
Wire the card demo submit button to its form element while at it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Remove all @radix-ui/* packages now that every component and demo is
built on Base UI.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sweep docs and landing copy for Radix mentions, and rewrite the
virtualizer scroll area and select guides to match the Base UI demos.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
react-hook-form fields without defaultValues start as undefined, which
made useTimescape start uncontrolled and warn once typing produced a
value. Pass null so the fields are controlled for their whole lifetime.

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 16, 2026 12:37pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
v3-ui-x Skipped Skipped Jul 16, 2026 12:37pm

@junwen-k
junwen-k merged commit 2324c11 into next Jul 16, 2026
3 of 4 checks passed

This branch had an error being deployed

1 failed and 1 inactive deployments
Preview – ui-x — 7abff75a Deployed Jul 16, 2026 by vercel[bot]
Preview – v3-ui-x — 7abff75a Deployed Jul 16, 2026 by vercel[bot]
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