The original SelectWidget seemed to have been written with a single selection in mind, and to be fair, that's the most common behavior we've expected of it up to very recently.
This means that in the code and in the product thinking, SelectWidget's selectItem allows for a single selection -- it unselects the current and replaces it with a new selection. This works great for single-selection widgets like a general MenuSelectWidget, but creates a myriad of problems when we use it in widgets that require the paradigm of multiple selections.
The ability to select multiple items exists in things like TagMultiselectWidget (where the items are the tags/bubbles that are selected) and MenuTagMultiselectWidget where the multiple items are the tag/bubbles but the selection in the menu itself is one-only, which exposes the mismatch.
The different paradigms of "selecting" things
There are different ways we seem to relate or think (and code) for selections in the widgets. We should try to consolidate, normalize, and/or find a good UX for the widgets that make sense to have multi- or single-selection behavior.
In TagMultiselectWidget, the items included aren't selected themselves, they're added to the group in general. The "selection" occurs when a tag is clicked, though, arguably, it has no real meaning. Selection -- one-off or multiple -- is probably not really meaningful for this widget unless we want to use the same interface as other selection-based widgets and call all added tags as "selected".
In contrast, MenuTagMultiselectWidget has a different meaning for "selected". The items come from the menu at minimum (plus, if allowed, arbitrary tags) and so "selected" may have a different meaning when you ask the general TagMultiselectWidget and when you ask its nested MenuSelectWidget. The way it currently works: MenuSelectWidget only has one selection (as SelectWidget only allows one) and so when we click/select an item to be added from the menu, the selection switches from the previously added item to the newly added item, repeatedly. There's no visual indication, really, about the multiple items that were already selected from the menu except to see them as 'tags' in the bigger widget.
This creates a bunch of problems with code consistency, like adding an item from the menu incorrectly, not recognizing properly arbitrary values that are allowed alongside a fixed menu, and other UX problems, like showing the user which of the items inside the menu they're looking at are already selected into the bigger widget without having the user look through the tags to compare. This is even more important when the menu is bigger.
To solve this, I think the solution should be to add an ability for SelectWidget and MenuSelectWidget to deal and accept multiple selections. The menu could show the selected background color for multiple items, indicating to the user that there are multiple things included, and getSelectedItem can return an array that actually represents the selections.
- For one, MenuSelectWidget with multiselect option (even without the TagMultiselectWidget interface/UX) can be a useful general widget, if the UX is fixed.
- Enabling the menu to display multiple-selected items would make MenuTagMultiselectWidget easier to manage UX-wise, because the user will have an indication in the menu itself which items are included. This is similar to the concept that's used in RecentChangesFilters where selected itsems display with a [x] near them, indicating they're selected.
- If we enable multiple selections for the menu, especially in MenuTagMultiselectWidget we can also enable the "toggling" behavior; meaning, you click on a menu item to select it, and click it again to unselect it. This makes the menu (and keyboard interaction in general) much more useful.
- Potentially, this can somewhat solve (or go towards consolidating and solving) the issue of having also a MultioptionWidget which is already a little confusing, and creates other issues of consistency within the widgets.
- Many other libraries allow their menus to have either single or multiple selection modes, and we have widgets that use menu concept (and SelectWidget concept) within them that would benefit from the multiple selection option as well.
Overall, I argue that the concept of single-selection is no longer valid. Many other libraries allow for the option of single- vs multiple-selection, and making this possible will fix both code issues and bugs that we see in MenuTagMultiselectWidget as well as UX issues with the menu that's attached to it and doesn't currently actually represents the state of that widget.
Examples from other libraries
The idea of having a menu widget that allows for either single or multiple selections isn't a new concept. A quick search shows the following as examples:
- selectize.js http://selectize.github.io/selectize.js/ comes with single and multiple selection choice out of the box
- Select2 library https://select2.org/advanced/default-adapters/selection SingleSelection vs MultipleSelection as default implementations of SelectionAdapter
- react-select https://github.com/JedWatson/react-select/ has isMulti config for multiple selections
- AngularJS <select> https://docs.angularjs.org/api/ng/directive/select allows for multiple prop