Skip to content

Select: add support for multiple selections#643

Open
mkernohanbc wants to merge 13 commits intomainfrom
feature/select
Open

Select: add support for multiple selections#643
mkernohanbc wants to merge 13 commits intomainfrom
feature/select

Conversation

@mkernohanbc
Copy link
Contributor

@mkernohanbc mkernohanbc commented Mar 4, 2026

This PR makes significant (non-breaking) changes to Select, and minor changes to Tag. See the Vite kitchen sink app for examples. Changes are also documented in Storybook.

The impetus for this was the addition of support for multi-select in React Aria v1.13.0.

Summary of changes in this PR:

  • Select now supports toggling between single or multiple select via the selectionMode prop
  • Added visual indicator for selected items in the ListBox
  • Changed flex behaviour for Select so that it adjusts to its parent container and can grow vertically to show multiple rows
  • <SelectValue> can now wrap over multiple lines, instead of being truncated with ellipsis
  • Adjusted small style for Select to properly use typography.regular.small.body
  • Added a new xsmall Tag variant
  • Updated Tag to properly spread its props

In single-select mode, Select behaves as it currently does (showing the currently-selected value as a text string inside the Select button.)

When selectionMode is set to multiple, it instead renders a <TagGroup> inside the button:

Screenshot 2026-03-04 at 11 22 46 AM

This means that selected items are:

  • Visually separated
  • De-selectable without re-opening the dropdown

Both the dropdown and the TagGroup are fully operable via keyboard:

Screen.Recording.2026-03-04.at.10.48.29.AM.mov

To prevent an accessibility violation from having interactive tags nested inside a button, this PR uses createPortal to render the <TagGroup> outside the Select <Button>. This adds additional styling complexity, but achieves the desired visual structure accessibly.

An alternative approach (f1d97d6) would be to render a <Group> instead of a <Button> when in multi-select mode. However, this approach:

  • Breaks the sizing logic of the popover, because the var(--trigger-width) used to size the popover no longer works
  • Forces a fundamental change in behaviour between Select modes, because in multi-select the dropdown could only be activated by pressing a small button, rather than by pressing anywhere on the Select object

@mkernohanbc mkernohanbc added this to the Components v0.7.0 milestone Mar 4, 2026
@mkernohanbc mkernohanbc self-assigned this Mar 4, 2026
@mkernohanbc mkernohanbc added the Components Changes or issues affect the design-system-react-components package label Mar 4, 2026
@Philip-Cheung
Copy link

Screenshot 2026-03-04 at 1 41 10 PM The component crashed when I clicked on the "sections" control.

@mkernohanbc
Copy link
Contributor Author

The component crashed when I clicked on the "sections" control.

That story is rendering for me (including switching modes and adding/removing selections), suggesting it might be a local Storybook issue on your end? Try killing and restarting Storybook (might also need to do the 'delete node_modules/npm i step if it's still bugging out after that.)

@Philip-Cheung
Copy link

Screenshot 2026-03-04 at 1 45 34 PM

When I add selections into the input, does it expand by default as more items are added? Can I set a fixed width? I have a hunch a lot of folks are not going to like that behaviour as it messes up their forms/design

@Philip-Cheung
Copy link

The component crashed when I clicked on the "sections" control.

That story is rendering for me (including switching modes and adding/removing selections), suggesting it might be a local Storybook issue on your end? Try killing and restarting Storybook (might also need to do the 'delete node_modules/npm i step if it's still bugging out after that.)

I tried restarting the local but I can replicate the issue

@mkernohanbc
Copy link
Contributor Author

When I add selections into the input, does it expand by default as more items are added? Can I set a fixed width? I have a hunch a lot of folks are not going to like that behaviour as it messes up their forms/design

In this example, it's inside a flex container, so its width is constrained by the structure of the page. If there are too many items for the width, it can wrap to a new line cleanly:

Screenshot 2026-03-04 at 1 49 31 PM

@Philip-Cheung
Copy link

When I add selections into the input, does it expand by default as more items are added? Can I set a fixed width? I have a hunch a lot of folks are not going to like that behaviour, as it messes up their forms/design.

In this example, it's inside a flex container, so its width is constrained by the structure of the page. If there are too many items for the width, it can wrap to a new line cleanly:

Screenshot 2026-03-04 at 1 49 31 PM

While I do see the benefit of implementing it this way, I have a couple of concerns as someone who’s used this sort of component in a variety of applications. For web apps, we generally expect it not to wrap onto a new line, as it can disrupt the layout in a wide range of use cases such as filter controls, settings, and forms. Especially in designs with limited vertical space, a new line can significantly interfere with the layout.

Maybe we could introduce a control that allows you to choose the overflow behavior of the multi-select when its contents exceed the container? The Ant design system link I shared with you this morning basically figured out every possible way you can implement a multi select.

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

Labels

Components Changes or issues affect the design-system-react-components package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants