Skip to content

SearchableChipSelect: Add form primitive to @wordpress/ui - #80779

Merged
mirka merged 11 commits into
trunkfrom
add-ui-searchable-chip-select
Jul 30, 2026
Merged

SearchableChipSelect: Add form primitive to @wordpress/ui#80779
mirka merged 11 commits into
trunkfrom
add-ui-searchable-chip-select

Conversation

@mirka

@mirka mirka commented Jul 28, 2026

Copy link
Copy Markdown
Member

What?

Adds a SearchableChipSelect form primitive to @wordpress/ui.

Why?

The design system needs a searchable multi-select control with chip-based selection state. This builds on the existing Combobox primitives and will support a higher-level control wrapper later.

How?

Add the SearchableChipSelect primitive, composing Combobox subcomponents with InputLayout for the chip input chrome.

Testing Instructions

  1. Run Storybook and open Design System / Components / Form / Primitives / SearchableChipSelect.
  2. Check the Default story with pre-selected chips: the container should grow to fit chips and the search input, with the placeholder sitting inside the border.
  3. Try searching, selecting, and removing chips.
  4. Check the Creatable, WithCustomChipsAndItems, WithCustomEmptyContent, and WithoutClearButton stories.
  5. Toggle WordPress global CSS in the Storybook toolbar and confirm the component still looks correct.

Screenshots

SearchableChipSelect

@mirka mirka self-assigned this Jul 28, 2026
@github-actions github-actions Bot added the [Package] UI /packages/ui label Jul 28, 2026
@mirka mirka added the [Type] Enhancement A suggestion for improvement. label Jul 28, 2026
@mirka mirka mentioned this pull request Jul 28, 2026
17 tasks
@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown

Size Change: 0 B

Total Size: 7.76 MB

compressed-size-action

@mirka
mirka marked this pull request as ready for review July 28, 2026 12:29
@mirka
mirka requested a review from a team as a code owner July 28, 2026 12:29
@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: mirka <0mirka00@git.wordpress.org>
Co-authored-by: simison <simison@git.wordpress.org>
Co-authored-by: Mamaduka <mamaduka@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@simison

simison commented Jul 29, 2026

Copy link
Copy Markdown
Member

Doesn't need solving in this PR as it's a bit of an edge case, but likely would need a follow-up:

Screenshot 2026-07-29 at 15 57 25 Screenshot 2026-07-29 at 15 57 31

Reminded me about the need for a Truncation component (#77391). Depending on content, consumer might want to wrap or truncate in different ways, for example at the end vs in the middle for text/domains/emails.

onValueChange={ ( values: typeof ITEMS, event ) => {
if ( values.some( ( item ) => item.value === 'create' ) ) {
// eslint-disable-next-line no-alert
alert( `Create new item: '${ inputValue }'` );

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just had a thought to use prompt() instead of alerting empty when nothing was entered, but how it's now is fine too for the sake of the demo.

Image

@simison simison left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not deeply familiar with combobox components (which I know can have lots of complexity) so you might want second thoughts, but overall this looks, feels and works well for me. I tested with Chrome & Firefox, desktop and mobile.

What should I expect from keyboard navigation for a component like this? Should each chip and "clear all" button be accessible by keyboard, or would I be expecting to navigate contents via the dropdown list only?

Design-wise only oddity to me is how when popover is above search input, it covers the chips and casts a shadow over search text:

Image

...but also nice to have it with close proximity to search.

Below -version looks good as-is:

Image

mirka and others added 2 commits July 30, 2026 05:44
Co-authored-by: Mikael Korpela <mikael@ihminen.org>
@mirka

mirka commented Jul 29, 2026

Copy link
Copy Markdown
Member Author

Design-wise only oddity to me is how when popover is above search input, it covers the chips and casts a shadow over search text

Great catch. This will be addressed in 473bc59, after adding an InputGroup subcomponent (#80869).

@mirka

mirka commented Jul 29, 2026

Copy link
Copy Markdown
Member Author

What should I expect from keyboard navigation for a component like this? Should each chip and "clear all" button be accessible by keyboard, or would I be expecting to navigate contents via the dropdown list only?

We don't have an APG pattern for multiselect comboboxes unfortunately. But as I understand it, all features are accessible by keyboard, if not with the exact same mechanisms as a mouse. Chips are navigable by arrow keys, deletable by the delete key, and the Clear All function is available through the escape key. The Clear All button not being focusable is a bit quirky, but I guess that's how it works in a standard <input type="search"> too. If anything, I was wondering if we should or shouldn't show the Clear All button at all. We'll see.

@mirka

mirka commented Jul 29, 2026

Copy link
Copy Markdown
Member Author

Doesn't need solving in this PR as it's a bit of an edge case, but likely would need a follow-up:

Screenshot 2026-07-29 at 15 57 25

I'll keep it breakable for now:

Long chips with line breaks

@Mamaduka

Copy link
Copy Markdown
Member

Looking forward to this.

As an experiment, I migrated FlatTermSelector to use the new Combobox, and I'm quite happy with the results. The SearchableChipSelect should reduce the boilerplate.

For async search, is there a plan to support a standardized way to handle "loading state"? Base UI suggests using Combobox.Status, but it's not exposed by our UI library.

@mirka

mirka commented Jul 30, 2026

Copy link
Copy Markdown
Member Author

For async search, is there a plan to support a standardized way to handle "loading state"? Base UI suggests using Combobox.Status, but it's not exposed by our UI library.

Mm, thanks for the call out. I'll add them in.

# Conflicts:
#	packages/ui/CHANGELOG.md
@mirka
mirka requested a review from desrosj as a code owner July 30, 2026 12:28
@mirka

mirka commented Jul 30, 2026

Copy link
Copy Markdown
Member Author

Design-wise only oddity to me is how when popover is above search input, it covers the chips and casts a shadow over search text

This is now fixed.

Flipped popup

@mirka
mirka enabled auto-merge (squash) July 30, 2026 12:55
@mirka
mirka merged commit 514d0f0 into trunk Jul 30, 2026
63 checks passed
@mirka
mirka deleted the add-ui-searchable-chip-select branch July 30, 2026 13:03
@github-actions github-actions Bot added this to the Gutenberg 23.8 milestone Jul 30, 2026
@github-actions

Copy link
Copy Markdown

Flaky tests detected in 0ade97a.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

πŸ” Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/30542698930
πŸ“ Reported issues:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Package] UI /packages/ui [Type] Enhancement A suggestion for improvement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants