Select: add support for multiple selections#643
Conversation
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 |
I tried restarting the local but I can replicate the issue |
ty2k
left a comment
There was a problem hiding this comment.
Lots going on in this component now! I think the createPortal() stuff works nicely for using the TagGroup inside of the Select for multi-select. Overall, I can't really break this visually and it seems like the keyboard navigation is solid. Great stuff!
Couple thoughts beyond the specific line number comments below:
-
IMO, I think we need a visual indicator of some kind in multi-select mode when
overflowis set toscrolland there is more information to be viewed. I see we're hiding the scrollbar here, but maybe there's an opportunity for something like the Gov.bc.ca gradient on the breadcrumbs, as an example? I think there's a risk of hiding information with this style in this general. I would personally opt for theoverflow: wrapor a checkbox list in this situation. -
There's a pixel or so worth of vertical layout shift happening in multi-select mode when there is nothing selected vs the first option is selected. This seems to be the case whether using
sizemedium or small. When we're in multi-select mode, can we set a different min-height equal to the height of the tags to accommodate?
ty2k
left a comment
There was a problem hiding this comment.
One visual height issue remains on this when we're in multi-select and moving between having no options selected and having one option selected.
| color: var(--icons-color-danger); | ||
| /* Sizing */ | ||
| .bcds-react-aria-Select.small .bcds-react-aria-Select--Button { | ||
| min-height: 32px; |
There was a problem hiding this comment.
Following up on the comments here, I think this value needs to change to accommodate the extra ~1px happening when we're in multi-select mode with one option selected.
What I suggest is adding a class on the Select to indicate that you're in multi-select mode, and then choosing one of these:
-
To keep all of the fields the same height, you could start playing with the padding inside of the Select button to accommodate the extra ~1px of height the Tag causes.
-
If you don't care if the overall height of the Select field in multi-select mode is slightly taller than other components, you can set this
min-heightto 40px and the equivalentmediummin-heightto 46px.




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:
selectionModeprop<SelectValue>can now wrap over multiple lines, instead of being truncated with ellipsissmallstyle for Select to properly usetypography.regular.small.bodyxsmallTag variantIn single-select mode, Select behaves as it currently does (showing the currently-selected value as a text string inside the Select button.)
When
selectionModeis set tomultiple, it instead renders a<TagGroup>inside the button:This means that selected items are:
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:var(--trigger-width)used to size the popover no longer works