Skip to content

[field] Fix stale filled and focused state on control replacement - #5345

Draft
atomiks wants to merge 1 commit into
mui:masterfrom
atomiks:claude/field-lifecycle-audit-fixes-73dada
Draft

[field] Fix stale filled and focused state on control replacement#5345
atomiks wants to merge 1 commit into
mui:masterfrom
atomiks:claude/field-lifecycle-audit-fixes-73dada

Conversation

@atomiks

@atomiks atomiks commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Two Field lifecycle states could go stale across control replacement. A filled uncontrolled control replaced by a fresh empty one under the same Field.Root kept data-filled set, and a control removed while focused never fires blur, leaving data-focused stuck on the root.

filled now follows last-attach-wins ownership of the shared input ref: the owning control publishes unconditionally on attach, a superseded control can't clear its successor's state, and a survivor reclaims a null ref after the owner unmounts. Each control also tracks whether it holds the field's focused state and releases it on unmount only in that case. Form registration reads the control's own element rather than the mutable shared ref, so field values stay readable when overlapping control lifetimes clear that ref.

Native label association is deliberately left on the existing commit-driven lifecycle (tests now pin it, including labels in other containers, htmlFor retargeting, and OTP slots mounting late). Label changes with no control rerender at all remain untracked in v1: useAriaLabelledBy patches over the hidden-input-inside-label layout, which is slated for rework in v2, and observer-based tracking measurably regressed mount performance for what it covered.

@atomiks atomiks added component: field Changes related to the field component. type: bug It doesn't behave as expected. labels Jul 27, 2026
@pkg-pr-new

pkg-pr-new Bot commented Jul 27, 2026

Copy link
Copy Markdown

commit: 69c0549

@code-infra-dashboard

code-infra-dashboard Bot commented Jul 27, 2026

Copy link
Copy Markdown

Bundle size

Bundle Parsed size Gzip size
@base-ui/react 🔺+107B(+0.02%) 🔺+22B(+0.02%)

Details of bundle changes

Performance

Total duration: 1,250.90 ms +99.64 ms(+8.7%) | Renders: 78 (+0) | Paint: 1,976.31 ms +176.62 ms(+9.8%)

Test Duration Renders
Menu mount (300 instances) 148.33 ms 🔺+31.96 ms(+27.5%) 2 (+0)
Mixed surface mount (app-like density) 83.82 ms 🔺+18.83 ms(+29.0%) 5 (+0)
Menu open (500 items) 87.23 ms 🔺+17.19 ms(+24.5%) 12 (+0)
Select open (500 options) 44.85 ms +4.69 ms(+11.7%) 14 (+0)

11 tests within noise — details

Metric alarms

Test Metric Change
Menu mount (300 instances) bench:paint 🔺 +46.40 ms
Mixed surface mount (app-like density) bench:paint 🔺 +26.85 ms
Menu open (500 items) bench:paint 🔺 +24.24 ms
Menu open (500 items) bench:paint#menu-open 🔺 +24.24 ms
Select open (500 options) bench:paint 🔺 +19.61 ms

…and 1 more metric alarm — details


Check out the code infra dashboard for more information about this PR.

@netlify

netlify Bot commented Jul 27, 2026

Copy link
Copy Markdown

Deploy Preview for base-ui ready!

Name Link
🔨 Latest commit 69c0549
🔍 Latest deploy log https://app.netlify.com/projects/base-ui/deploys/6a66ee3962396b0008c0dfd8
😎 Deploy Preview https://deploy-preview-5345--base-ui.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@atomiks
atomiks force-pushed the claude/field-lifecycle-audit-fixes-73dada branch from 9ba0306 to 4354b0e Compare July 27, 2026 05:35
@atomiks
atomiks force-pushed the claude/field-lifecycle-audit-fixes-73dada branch from 4354b0e to 69c0549 Compare July 27, 2026 05:35
@atomiks atomiks changed the title [field] Fix stale label association and lifecycle state on control replacement [field] Fix stale filled and focused state on control replacement Jul 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component: field Changes related to the field component. type: bug It doesn't behave as expected.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant