Skip to content

[6.x] Refine combobox#19295

Open
brianjhanson wants to merge 3 commits into
6.xfrom
feature/refine-combobox
Open

[6.x] Refine combobox#19295
brianjhanson wants to merge 3 commits into
6.xfrom
feature/refine-combobox

Conversation

@brianjhanson

Copy link
Copy Markdown
Contributor

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

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>
@brianjhanson brianjhanson changed the title Consolidate comboboxes into a single performant craft-combobox [6.x] Refine combobox Jul 22, 2026
@github-actions

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown

📚 Storybook previews

@craftcms/uiopen Storybook

Changed components:

resources/jsopen Storybook

No changed components detected in this Storybook.

brianjhanson and others added 2 commits July 22, 2026 15:54
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
brianjhanson marked this pull request as ready for review July 23, 2026 15:24
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