Let a Combobox be cleared in one gesture - #30
Merged
Conversation
SearchableSelect gained `clearable` in v1.21.0 and the entry argued Combobox did not need one, because free text can be erased. True, but not in one gesture: erasing means selecting the contents by hand, and the amount to erase is unbounded because picking a suggestion overwrites the text wholesale. A new `clearable` prop shows an ✕ at the field's right end (accessible name via `clear-label`) that emits '', focuses the field and leaves the list open — clearing here is a step towards another value, not an end state. Three details differ from SearchableSelect's, all because the trigger is an <input> rather than a <button>: the ✕ sits at right-0 with no chevron beside it; visibility gates on modelValue alone, since the typed text IS the value and nothing can be stored while the screen shows nothing; and the button prevents its own mousedown, or the blur races the focus handoff. Padding is pr-10 only while the ✕ is rendered, so a Combobox without the prop still aligns with the Input atom next to it. Pinned by the Clearable story. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
SearchableSelectgainedclearablein v1.21.0. Its changelog entry argued the third sibling did not need one, because "Comboboxis free text that can be erased".True, but not in one gesture: erasing means selecting the field's contents by hand and deleting them, and the amount to erase is unbounded because picking a suggestion overwrites the text wholesale.
The consuming app made that concrete — a field where one option inserts a placeholder token and everything else is typed prose, so the two gestures a user alternates between are "pick" and "start over". The native
Selecthas its placeholder<option value="">andSearchableSelectnow has its ✕; the third control being the odd one out is the inconsistency.What
clearable(plusclear-label, default "Clear value"). While the field holds anything, an ✕ sits at its right end; pressing it emitsupdate:modelValuewith'', focuses the field and leaves the suggestion list open.Three details differ from
SearchableSelect's, all forced by the trigger being an<input>rather than a<button>:right-0, notright-7— a Combobox has no chevron to sit beside.modelValuealone, not on an option's label resolving. Here the typed text is the value, so there is no state where something is stored and nothing is on screen — the gateSearchableSelectneeds for in-flight options has no meaning.mousedown, or the press blurs the field before the click lands and the blur races the focus handoff.Padding is
pr-10only while the ✕ is rendered, so a Combobox without the prop keeps aligning with theInputatom beside it.Verification
Clearablestory pins the loop: clear → model'', field empty and focused, ✕ gone, full list open; type again → ✕ back. Inverted once (prop removed) to confirm it goes red — it does.npx playwright test tests/stories.smoke.spec.ts tests/touch-target.spec.ts— 245 passed.npm run lint— 0 errors (7 pre-existing warnings, none in the touched files);npm run typecheckclean;npm run buildclean includingverify:externals,verify:dev-warningsandverify:props.Version bumped to 1.22.0 (additive).
🤖 Generated with Claude Code