The Basics

What it is

List displays a set of list items in a column without the default bullets and spacing usually included by the browser, making it easy to use in many scenarios.

List has the option to become interactive, allowing users to select 1+ choices 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

List is available in two styles:

  • Simple List: the screen displays a collection of list items arranged vertically.
    • Each item can contain custom HTML, like images and plain or formatted text
  • Selection List: List becomes a clickable interactive element.
    • 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 use a list without the browser’s default CSS styling
  • To show long or complex content with horizontal dividers
  • To display a collection of items without numerals or bullets
  • To show a list with helpful visual elements, like images of providers or medications
  • To ask users to select 1+ options from a list

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
  • For a bulleted or numbered list of items: use the HTML element <ul> (unordered list) for a bulleted list or <ol> (ordered list) for a numbered list

What to use instead

RadioGroup

Use RadioGroup if users can select only one option.

Select

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

SegmentedButton

Use SegmentedButton to display Selection style Lists as a button group.

How to use

List can include dividers between items. This adds a light border at the top of all list items except the first, making it easier to read list items that are longer than 1 line of text or that include both text and images.

In Selection style List, list items act as 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 List 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

Each item in the list can include custom markup, such as images and plain or formatted text (bold, italics).

Item alignment in Selection style Lists

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 in Selection style Lists

Forge offers 3 options to indicate required form fields. See Form for details.

Spacing and size in Selection style Lists

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

List Basic Share

List Selection Share

List Controlled Share

List With Dividers Share

List With Image Share

Coding

Developer tips

The List component is designed to render collections i.e., sets of ListItems, with versatility, accommodating both plain and interactive lists through the “variant” prop. When “variant” is set to “selection”, the component allows for the selection of list items. For non-interactive lists, when “variant” is set to “simple”, List serves to display items without the capability of selection.

List can be used on its own or as an input in FormField.

Value structure

To promote composition, List no longer accepts an “options” prop and simply renders the Children it is supplied. List should exclusively render sets of ListItems. Reported via List’s onChange handler, the List component’s “value” is an array of strings which correspond to each selected 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 List as an uncontrolled component) to this:

[uniqueKeyForItemB]

Required fields

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

List directory in Bitbucket

ListItem 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.

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

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

Props