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

    RadioGroup

    Use RadioGroup for short lists that can appear directly on the page.

    SingleSelect

    Use SingleSelect for filtering lists with 20+ options.

    Typeahead

    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

    Select With Simple String Options Share

    Select With Complex Options Share

    Select Standalone Use Share

    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:

    <Select
    hasNullDefault={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

    Select directory in Bitbucket

    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 accessability 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';

    Props