Select
A dropdown list where users select a single option.
The Basics
What it is
Select enables users to enter data by selecting an option from a predefined list. This limits users to a specific set of values and increases the predictability of the data users enter. Select is often used in forms.
How it works
- The user clicks or focuses on Select, which makes it active.
- A system dropdown menu appears, listing all available options.
- When the user hovers on an option, it’s highlighted.
- When the user clicks an option, it’s selected, and the dropdown closes.
- The Select field now features the selected option.
When to use
- To ask users to choose a single option from a list
When not to use
- For a short list that could be displayed directly on the page, reducing the number of clicks
- For a long list of options (e.g., a complete list of medications) that would be difficult to navigate
What to use instead
Use RadioGroup for short lists that can appear directly on the page.
Use SingleSelect for filtering lists with 20+ options.
Use Typeahead for list filtering plus freeform text entry.
How to use
Select can be used as a standalone component, but it’s better when used with Form and FormField. Form provides a consistent, responsive layout, and FormField adds features like labels, error message handling, and hint text.
HTML-based
Select uses the native HTML <select>
element. Its visuals are largely handled by the operating system, which means that CSS and Forge styling has limited impact on this input’s appearance, especially for the dropdown menu itself. The benefits of this approach include:
- It works across all browsers and is familiar to users of each operating system.
- It provides a superior touch-based UI on mobile devices.
- The dropdown portion positions itself based on its location on the page. This guarantees that the menu content is viewable in most cases.
First option
By default, Select’s first option is a placeholder (“- Select -”) that has no value. You can set Select to remove this placeholder and use the first list option as the default value instead. However, this risks users accidentally submitting this default value without actively editing the field. For example, if Select has no placeholder option and “Allergies: None” is the first option in the list, “Allergies: None” becomes the default value. Users could submit this value without deliberately selecting it, potentially causing a patient safety issue. For this reason, avoid removing Select’s placeholder option unless you’re certain that this design choice won’t cause data errors.
Style
Design details
Required fields
Forge offers 3 options to indicate required form fields. See Form for details.
Spacing and size
The height of this component and the vertical space around it vary according to the form layout (i.e., medium, compact, super-compact). See Form for details.
Placement and hierarchy
No additional information for this component.
Content
Use sentence case for label text (“Reason for visit”, not “Reason For Visit”).
Use sentence case for option text (“Abdominal pain”, not “Abdominal Pain”).
Demos
Coding
Developer tips
Updating options
If the options in Select need updating after its original render, be sure to instantiate a new array and reassign it to the options
prop. Merely updating the existing array doesn’t trigger a re-render of the component with the options in a modified array.
Setting the default selected option
Set hasNullDefault
to false
to remove the placeholder option and make the first list option the default selected option.
To make a different list option the default selected option, set defaultValue
to that option’s value:
<SelecthasNullDefault={false}defaultValue={'banana'}options={[{ text: "A", value: 'apple' },{ text: "B", value: 'banana' },{ text: "C", value: 'coconut', disabled: true }]}/>
Required fields
For required fields, use the required
prop to mark Select as required.
Forge offers 3 options to indicate required form fields. When using Form with this component, set Form’s requiredVariation
prop. See Form for details.
Repository
Implementation links
Implementation details
It is strongly recommended to familiarize yourself with the Forge source code. While this documentation is a best effort to document the intent and usage of a component, sometimes some features only become clear when looking at the source code. Also, looking at Forge's source code may help identify and fix bugs in either your application or Forge itself.
Storybook files
Forge maintains at least one storybook file per component. While the primary audience for these files is typically the Forge team, these storybook files may cover usages of the component not covered by a demo. The storybook for the latest version of forge can be found at go/forge-storybook-lts.
Testing library
Forge strongly encourages using testing-library to write tests for your application.
"The more your tests resemble the way your software is used, the more confidence they can give you."
If you're having trouble testing a Forge component using testing-library, it would be a good idea to see how Forge tests its own components. For the most part, Forge tries to use screen.getByRole as much as it can, as that API provides the best feedback on a11y compliance. Forge discourages the use of document.querySelector and screen.getByTestId as both APIs encourage using implementation details to test your component, and discourage adding roles to your component.
With that being said, many of Forge's components were not built with accessibility in mind. These components do break the recommendations listed above.
Import statements
In Nimbus applications
athenaOne serves the Forge bundle independently from your application's bundle. Importing Forge components directly from '@athena/forge'
takes advantage of this feature.
import { Select } from '@athena/forge'
In standalone applications
Importing components using the exact path to the module takes advantage of webpack's tree shaking feature. Webpack will include only that module and its dependencies.
import Select from '@athena/forge/Select';
To use this import guidance, Typescript applications must use typescript >= 4.7.3
, and should add this setting to their tsconfig.json file:
{"compilerOptions": {"moduleResolution": "Node16",}}
If this setting doesn't work for your application, use this import statement instead:
import Select from '@athena/forge/dist/Select';