### Existing components
- Wikit: [[ https://github.com/wmde/wikit/blob/master/vue-components/src/components/Dropdown.vue | Dropdown ]], [[ https://github.com/wmde/wikit/blob/master/vue-components/src/components/OptionsMenu.vue | OptionsMenu ]], [[ https://github.com/wmde/wikit/blob/master/vue-components/src/components/MenuItem.ts | MenuItem ]]
- MediaSearch: [[ https://github.com/wikimedia/mediawiki-extensions-MediaSearch/blob/master/resources/components/base/Select.vue | Select ]] ([[ https://github.com/wikimedia/mediawiki-extensions-MediaSearch/blob/master/resources/components/base/Select.less | styles ]]), [[ https://github.com/wikimedia/mediawiki-extensions-MediaSearch/blob/master/resources/components/base/SelectMenu.vue | SelectMenu ]] ([[ https://github.com/wikimedia/mediawiki-extensions-MediaSearch/blob/master/resources/components/base/SelectMenu.less | styles ]])
- ContentTranslation: [[ https://github.com/wikimedia/mediawiki-extensions-ContentTranslation/blob/master/app/src/lib/mediawiki.ui/components/MWDropdown/MWDropdown.vue | Dropdown ]], [[ https://github.com/wikimedia/mediawiki-extensions-ContentTranslation/blob/master/app/src/lib/mediawiki.ui/components/MWSelect/MWSelect.vue | Select ]]
- Vuetify: [[ https://github.com/vuetifyjs/vuetify/tree/master/packages/vuetify/src/components/VSelect | Select ]]
- Buefy: [[ https://github.com/buefy/buefy/tree/dev/src/components/dropdown | Dropdown ]], [[ https://github.com/buefy/buefy/tree/dev/src/components/select | Select ]]
**Wikimedia Design Style Guide links:**
- [[ https://design.wikimedia.org/style-guide/components/dropdowns.html | Dropdowns ]]
### Potential implementations
#### Select vs. Dropdown
Different libraries have different interpretations of what "select" and "dropdown" mean:
| Library | Select | Dropdown |
| ---- | ---- | ---- |
| OOUI | "Select" is used throughout OOUI to mean anything that involves selecting an option out of a list. SelectWidget is a generic list of options. User interaction with options is handled here, as well as methods for the developer to do things like find or select an option. Various widgets like ButtonSelectWidget, RadioSelectWidget, DropdownWidget, and ComboboxWidget are ultimately based on and expand upon the SelectWidget. | DropdownWidget contains a MenuSelectWidget (which extends SelectWidget) and is basically a prefab way to build a themed, featureful substitute for `<select>` |
| Wikimedia Style Guide | n/a | Themed `<select>` substitute |
| Wikit | n/a | Themed `<select>` substitute |
| MediaSearch| Themed `<select>` substitute | n/a |
| ContentTranslation | Combobox | Themed `<select>` substitute |
| Vuetify | Themed `<select>` substitute | n/a |
| Buefy | Themed `<select>` | Menu of options, like for navigation |
Some general research shows that "select" often means a `<select>` or similar component that shows the currently selected item and can be used in forms, while "dropdown" often means a menu with options that can be chosen (like for navigation).
#### Options menu and other shared UI and behavior
As detailed above, in OOUI, many widgets are based on the functionality provided by the SelectWidget and others. In terms of UI, the menu of options used by the DropdownWidget appears in many other widgets (ButtonSelectWidget, ComboboxWidget, MenuTagMultiselectWidget, LookupElement, and more). Although we're moving away from the inheritance pattern in favor of composition, there are still opportunities to share code via reusable components and mixins.
The following Vue libraries implement some form of reusable or shared code:
- Wikit: separate component for OptionsMenu that handles things like keyboard navigation, scrolling, and styles
- MediaSearch: separate component for SelectMenu, used by the Select and AutocompleteSearchInput components, for displaying a menu of options (but interactivity is handled in the parent)
- Vuetify: Select uses a SelectList component, which uses generic List and ListItem components
Options can be passed into the component either as a prop or as slot content:
- Wikit: An array of objects of type MenuItem (label, description, and optional tag) is passed into Dropdown as a prop, which is then passed to OptionsMenu
- ContentTranslation/MediaSearch (which shamelessly stole this from CT): An array (of values or objects) or an object is passed into Dropdown/Select as a prop. The data is then parsed into a consistent format so it can be displayed. If items take the form of objects, they must have `label` and `value` properties.
- Vuetify: an array of values or objects is passed into VSelect as a prop. If items are objects, you must use the default format (with `text` and `value` properties) or provide the equivalent property names so the Select component knows what to do with the data. Presumably either the VSelect or VList has to deal with the different formats the data could take, but I haven't looked that closely yet.
- Buefy: Since the Select component implements `<select>`, options are passed in as actual `<option>` elements in the main slot
#### HTML elements
As noted above, Buefy is the only library that uses the native `<select>` element. All others build custom markup and must reimplement some of the `<select>` spec. We're currently unable to consistently render a custom-styled `<select>` across browsers, so this isn't even an option for us.