Skip to content

Let a Combobox be cleared in one gesture - #30

Merged
StanBarrows merged 1 commit into
mainfrom
feat/combobox-clearable
Aug 14, 2026
Merged

Let a Combobox be cleared in one gesture#30
StanBarrows merged 1 commit into
mainfrom
feat/combobox-clearable

Conversation

@StanBarrows

Copy link
Copy Markdown
Contributor

Why

SearchableSelect gained clearable in v1.21.0. Its changelog entry argued the third sibling did not need one, because "Combobox is 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 Select has its placeholder <option value=""> and SearchableSelect now has its ✕; the third control being the odd one out is the inconsistency.

What

clearable (plus clear-label, default "Clear value"). While the field holds anything, an ✕ sits at its right end; pressing it emits update:modelValue with '', 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>:

  • The ✕ sits at right-0, not right-7 — a Combobox has no chevron to sit beside.
  • Visibility gates on modelValue alone, 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 gate SearchableSelect needs for in-flight options has no meaning.
  • The button prevents its own mousedown, or the press blurs the field before the click lands and the blur races the focus handoff.

Padding is pr-10 only while the ✕ is rendered, so a Combobox without the prop keeps aligning with the Input atom beside it.

Verification

  • New Clearable story 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 typecheck clean; npm run build clean including verify:externals, verify:dev-warnings and verify:props.

Version bumped to 1.22.0 (additive).

🤖 Generated with Claude Code

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>
@StanBarrows
StanBarrows merged commit 5a5b7d2 into main Aug 14, 2026
2 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