The Basics

    What it is

    SelectionList enables users to enter data by selecting 1+ options from a predefined list. This limits users to a specific set of options and increases the predictability of the data users enter.

    How it works

    • The user clicks or activates the option’s checkbox or clicks anywhere in the row to select the option.
    • Once selected, the user deselects it by clicking or activating the option’s checkbox again or clicking anywhere in the row.
    • The user’s selections usually aren’t saved until they take another action, like using a button (“Submit”).

    When to use

    • To ask users to select 1+ options from a list
    • For short lists that can appear directly on the page, reducing the number of clicks
    • To include a helpful visual element in a list, like images of providers or medications

    When not to use

    • For long lists that would take up too much vertical space on the page
    • For lists where only one selection is allowed

    What to use instead

    RadioGroup

    Use RadioGroup if users can select only one option.

    Multiselect

    Use Multiselect if the list of options will take up too much vertical space.

    How to use

    SelectionList contains individual options users can select. By default, each option is a line of text. You can add other elements, like icons or images, but since the entire row is clickable, these elements should not be interactive.

    Do:

    Include visual elements if they help differentiate options.

    <p>Include visual elements if they help differentiate options.</p>
    Don't:

    Include any other interactive elements in the list of options.

    <p>Include any other interactive elements in the list of options.</p>

    An optional description appears above the list options. It acts as a prompt or statement about the list. It’s separate from the form label and should not be used in place of a label. It’s actually coded as the HTML element <legend> for accessibility reasons (see this WebAIM article).

    Do:

    Use a description when context is helpful.

    <p>Use a description when context is helpful.</p>
    Don't:

    Use a description if it’s redundant or unnecessary.

    <p>Use a description if it’s redundant or unnecessary.</p>

    The options in a SelectionList can be separated using gray lines as dividers.

    Do:

    Use dividers when options have multiple lines of text.

    <p>Use dividers when options have multiple lines of text.</p>
    Don't:

    Use dividers with short text, as it introduces visual clutter.

    <p>Use dividers with short text, as it introduces visual clutter.</p>

    Style

    Design details

    Item alignment

    In text-only options, the option text is top-aligned with the matching checkbox. When the text wraps, the top of the text box remains in the same location.

    For more complex options (such as those with images or icons), discuss alignment with the developer.

    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 description text. If also using a label, make sure that the label and description work well together. For example:

    • Label: “Symptoms”
    • Description: “Which symptoms have you had in the past week?”

    Use sentence case for option text (“Abdominal pain”, not “Abdominal Pain”).

    Demos

    Selection List Simple Share

    Selection List Complex Share

    Coding

    Developer tips

    SelectionList can be used on its own or as an input in FormField. For its options list, it takes either a list of SelectionListItem components as its children or an options array prop, the same way that Select and RadioGroup do. Using options is less verbose, but its list items can only be text. SelectionListItem can take any content as its children.

    Value structure

    SelectionList takes as its value an object mapping the uniqueKey of its list items to boolean values. If the options prop was used to generate the list items, the value property for each item in options is used to create that item's uniqueKey.

    For example, if your list contains items A, B, and C, and only B should be checked, set value (or defaultValue if you’re using SelectionList as an uncontrolled component) to this:

    {
    'A': false,
    'B': true,
    'C': false,
    }

    Similarly, SelectionList calls onChange with an event object, where event.target.value is a map of keys to boolean values like the one above.

    Required fields

    Use the required prop to mark SelectionList 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

    SelectionList directory in Bitbucket

    SelectionListItem 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 { SelectionList, SelectionListItem } 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 SelectionList from '@athena/forge/SelectionList';
    import SelectionListItem from '@athena/forge/SelectionListItem';

    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 SelectionList from '@athena/forge/dist/SelectionList';
    import SelectionListItem from '@athena/forge/dist/SelectionListItem';

    Props