[6.x] Refine combobox#19295
Open
brianjhanson wants to merge 3 commits into
Open
Conversation
Replace the parallel headlessui-based Vue combobox stack with the Lit `craft-combobox` web component as the single implementation. The component takes an `options` array property and renders only the filtered top-`limit` (default 150) matches as `craft-option` children, keeping the DOM node count bounded for large lists (timezones, locales, languages). Lion still drives selection, keyboard nav, and a11y. `parser` maps a selected option's label back to its value so v-model receives the option value (e.g. "Online" -> "1"), while unmatched text passes through as a custom value for env-var entry. - craft-combobox: options API, filter (label/value/keywords), limit cap with footer, optgroups, clearable, rich options; rewritten story + component tests - generate-vue-wrappers: dedicated combobox wrapper binding .options as a property - app CraftCombobox.vue: thin delegator over the WC wrapper, retaining the env-var callout messaging - delete InputCombobox.vue and InputComboboxOption.vue - migrate direct/bare consumers (settings/sites/Index, useEditableTable); drop the dead #item slot in settings/General Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
📚 Storybook previews@craftcms/ui — open Storybook Changed components: resources/js — open Storybook No changed components detected in this Storybook. |
Three fixes on top of the initial consolidation, found while testing in Storybook and on the sites settings page: - Reflect the selected option's label into the textbox. With autocomplete='list' Lion only syncs the model to the input when blurred, and selecting refocuses it, so the chosen label never appeared. Force the sync on overlay close (a committed selection); typing is unaffected. - Stop option text from duplicating on re-filter (e.g. "Option 000Option 300"). Lion's match-highlighting mutates each option's DOM, which collides with our lit-html rendering. Disable the highlight — we own option content. - Open the listbox on Down/Up arrow even when empty. Lion otherwise only opens an empty field when showAllOnEmpty is set, so arrow-to-browse did nothing on select-style fields (e.g. the sites language picker). Adds regression tests for all three. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
brianjhanson
marked this pull request as ready for review
July 23, 2026 15:24
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.
Replace the parallel headlessui-based Vue combobox stack with the Lit
craft-comboboxweb component as the single implementation.The component takes an
optionsarray property and renders only the filtered top-limit(default 150) matches ascraft-optionchildren, keeping the DOM node count bounded for large lists (timezones, locales, languages). Lion still drives selection, keyboard nav, and a11y.parsermaps a selected option's label back to its value so v-model receives the option value (e.g. "Online" -> "1"), while unmatched text passes through as a custom value for env-var entry.