fix(company-input-v2): commit typed/autofilled value on blur - #241
Conversation
MUI Autocomplete in freeSolo mode only fires onChange when the user
explicitly selects an option, so values entered via typing-and-tabbing
or browser autofill (notably iOS Chrome) never propagate to the parent
and required-field validation fails on submit.
- Enable Autocomplete autoSelect so the current input value is committed
on blur, matching MUI's intended pattern for free-text combos.
- Normalize string values inside onChange to the {id, name} shape that
consumers expect, since autoSelect emits the raw typed string.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughCompanyInputV2 now enables autoSelect on the Autocomplete component and normalizes raw typed strings by trimming and converting them into ChangesCompany Input String Normalization
Estimated code review effort🎯 2 (Simple) | ⏱️ ~5 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint skipped: no ESLint configuration detected in root package.json. To enable, add Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
MUI Autocomplete in freeSolo mode only fires onChange when the user
explicitly selects an option, so values entered via typing-and-tabbing
or browser autofill (notably iOS Chrome) never propagate to the parent
and required-field validation fails on submit.
- Enable Autocomplete autoSelect so the current input value is committed
on blur, matching MUI's intended pattern for free-text combos.
- Normalize string values inside onChange to the {id, name} shape that
consumers expect, since autoSelect emits the raw typed string.
…241) Follow-up to removing autoSelect. autoSelect (added in #241) committed the input's DOM value on blur, which is how it captured iOS-Chrome browser autofill (autofill writes to the DOM without firing onInputChange). The initial onBlur here read React input state, which would be stale for autofill and reintroduce the #241 required-field-validation bug. - onBlur now reads event.target.value (the DOM value), not React state, so typed AND autofilled values propagate on blur — while still committing the field text, never a highlighted option (the autoSelect-on-hover bug fix stands). - Test: commits a browser-autofilled value on blur even when onInputChange never fired. 26/26 green. Needs a Chrome-iOS device re-test of the #241 autofill path before merge.
…main (v4.x) (#290) Port of PR #289 + layered commits from main: - Remove `autoSelect` (root cause of hover-then-tab wrong-company commits) - Explicit onBlur that reads event.target.value (DOM value; falls back to React input state) so browser autofill still propagates on blur -- preserves #241/#246's iOS Chrome autofill fix - `disableClearable`: with free-text supported, an explicit clear (x) isn't wanted; users empty by deleting the text - Synthetic "Use "<typed>"" row prepended to dropdown when the typed text isn't already listed; committed cleanly (marker stripped) via onChange - Extract `getOptionName` helper used by getOptionLabel, filterOptions, renderOption; rename local `label` in renderOption to `displayLabel` to stop shadowing the outer prop Tests: +7 (28/28 green), including regression coverage for the hover-then-tab guard, the DOM-value autofill path, and the Use/free-text commits.
…"<typed>"" row (#289) * fix: company-input-v2 — explicit selection only, no clear icon, "Use "<typed>"" row Root cause of the wrong-company bug: `autoSelect` committed the currently *highlighted* option on blur, so merely mousing over a suggestion and then tabbing away silently populated the wrong company. - Remove `autoSelect`. Selection is now explicit (click / Enter) only. - New onBlur: tab/click-away commits exactly what was typed — resolved to an existing company only on an exact (case-insensitive) name match, else a free-text { id: 0, name }. Never commits a merely-highlighted option. - `disableClearable`: remove the MUI clear (x) icon; the field commits free text, so an explicit clear affordance isn't wanted (delete text to empty). - Append a synthetic 'Use "<typed>"' row so users can explicitly commit their text; skipped when it already matches a listed company. Commits a clean { id: 0, name }, dropping the display-only marker. - Predictive typeahead unchanged (freeSolo + server-side queryRegistrationCompanies). Tests: +5 (blur keeps typed text / never a highlighted option; clear icon never renders even with a real value; "Use" row commits clean free text; no redundant "Use" row on exact match). 25/25 green. * fix: read DOM value in onBlur so autofill still propagates (preserve #241) Follow-up to removing autoSelect. autoSelect (added in #241) committed the input's DOM value on blur, which is how it captured iOS-Chrome browser autofill (autofill writes to the DOM without firing onInputChange). The initial onBlur here read React input state, which would be stale for autofill and reintroduce the #241 required-field-validation bug. - onBlur now reads event.target.value (the DOM value), not React state, so typed AND autofilled values propagate on blur — while still committing the field text, never a highlighted option (the autoSelect-on-hover bug fix stands). - Test: commits a browser-autofilled value on blur even when onInputChange never fired. 26/26 green. Needs a Chrome-iOS device re-test of the #241 autofill path before merge. * fix: clear the committed company when the field is emptied on blur (CodeRabbit) With disableClearable there's no (x), so delete-all-text + blur is the only way to clear the field — but onBlur previously fired nothing for empty input, leaving the prior company committed (a required field still read as filled). - onBlur now propagates null when the field is emptied, guarded so an already-cleared field doesn't fire a redundant change. Non-empty exact-match / free-text behavior unchanged. - Tests: clear-on-empty-and-blur; no redundant change on already-empty blur. 28/28 green. * fix(company-input-v2): move "Use "<typed>"" row to the top of the dropdown Prepend the synthetic free-text row instead of appending. Puts the user's typed text as the primary action (arrow-down + Enter commits it without scrolling past API suggestions) and matches the intent that they took the trouble to type. * refactor(company-input-v2): extract getOptionName helper getOptionLabel, filterOptions, and renderOption each computed the option-shape-to-name mapping inline. Extracts a single exported helper so the string / company-object / malformed cases live in one place. * refactor(company-input-v2): rename renderOption's local label to displayLabel The local variable shadowed the outer `label` prop, which is confusing to skim. Same-block only, no behavior change. --------- Co-authored-by: Gabriel Horacio Cutrini <gabriel.cutrini@gmail.com>
ref: https://app.clickup.com/t/86b9rnr4r
Summary
CompanyInputV2wraps MUI Autocomplete infreeSolomode, butonChangeonly fires when the user explicitly selects an option. Values entered via typing-and-tabbing or browser autofill (notably iOS Chrome) never propagate to the parent, so required-field validation fails on submit.Reproduce with autofill simulation in DevTools: set the input value via the native setter, dispatch
input, then blur — without this PR the parent'scompanystays{id: null, name: ""}; with it the parent receives{id: 0, name: <typed>}.Changes
autoSelectto the Autocomplete. MUI's intended mechanism for committing the current input value on blur in a free-text combo.onChangeto the{id, name}shape consumers expect, sinceautoSelectcallsonChangewith the raw typed/autofilled string.Summary by CodeRabbit