List allows users to view individual, but related, text items grouped together.

also known as Unordered List, Ordered list, <ol>, <ul>, <li>

Figma:

Responsive:

Adaptive:

A11y:

Props

Component props
Name
Type
Default
children
Required
<React.Element<typeof List.Item>>
-

Use List.Item to build lists. See subcomponents.

label
string | React.Element<typeof Text>
-

The label for the list. Be sure to localize the text. See the label variant for guidance.

labelDisplay
"visible" | "hidden"
"visible"

Whether the label should be visible or not. If hidden, the label is still available for screen reader users, but does not appear visually. See the accessibility section and the label variant for guidance.

size
"100" | "200" | "300" | "400" | "500" | "600"
300

The sizes are based on our font-size design tokens. See the text sizes variant for more details.

spacing
"regular" | "condensed"
"regular"

The spacing used in List. See the spacing variant for guidance.

type
"bare" | "ordered" | "unordered"
-

Determines the style of the list. See the type variant to learn more about how sizing is applied.

Usage guidelines

When to use
  • To present a grouping of simple, related information. For more complex data, use Table.
  • To break up related content into easily digestable chunks.
When not to use

Best practices

Do

Use List when you are displaying more than two items or points.

Don't

Use List if you are displaying fewer than two items. Instead, consider how to present the information as plain text on the page.

Do

Include links if they are relevent to better understanding the context of the list.

Don't

Use List if the whole list item is selectable. Instead use a navigational component or FieldSet.

Accessibility

Labels

List comes with a label built-in: just use the label prop.

We recommend using a label prop in all lists. The label will be announced by the screenreader describing the purpose or contents of the list. Even though text preceding the list can introduce the list, screenreaders will read both pieces of information in sequential order. When using the label prop, the information is embedded into the list announcement supporting the comprehension of the list.

However, if List is labeled by content elsewhere on the page or a more descriptive label is needed, the labelDisplay prop can be set to 'hidden'. In this case, it is still available to screen reader users, but will not appear visually on the screen.

The following examples showcase different cases where labels need to be hidden.

import { Box, Flex, Heading, List } from 'gestalt';

export default function Example() {
  return (
    <Box
      alignItems="center"
      display="flex"
      height="100%"
      justifyContent="center"
      padding={8}
    >
      <Flex direction="column" gap={4}>
        <Heading accessibilityLevel="none" size="500">
          Asynchronous Analytics Endpoints
        </Heading>
        <List
          label="Use the synchronous analytics endpoints if:"
          labelDisplay="hidden"
          type="unordered"
        >
          <List.Item text="You need data from the last 90 days" />
          <List.Item text="You want a quick response to load a user facing dashboard/component in real time" />
          <List.Item text="You want to avoid large report size/unnecessary data being returned" />
          <List.Item text="You need only basic key metrics for each campaign/ad/etc" />
        </List>
      </Flex>
    </Box>
  );
}

import { Box, Flex, List, Text } from 'gestalt';

export default function Example() {
  return (
    <Box
      alignItems="center"
      display="flex"
      height="100%"
      justifyContent="center"
      padding={8}
    >
      <Flex direction="column" gap={4}>
        <Text>
          The Save button is one of the best ways to get your content onto
          Pinterest —through visitors to your site. Make sure your Save button
          is doing the most for you by following our best practices.
        </Text>
        <List
          label="Best practices for Save Button for developers"
          labelDisplay="hidden"
          type="unordered"
        >
          <List.Item text="Pin type settings: Include 'pinit.js' correctly" />
          <List.Item text="Use the Save button that’s best for your website" />
          <List.Item text="Multiple images on a page (like a blog)" />
        </List>
      </Flex>
    </Box>
  );
}

Subcomponents

List.Item

List.Item is a subcomponent of List. List.Item represents the <li> tag nested within a <ul> or <ol> list tag.

Lists that don't require a alternating between "ordered", "unordered" or "base" can just nest List.Item into each other to build nested lists. If type alternation is required, use List

List.Item Props

List.Item subcomponent props
Name
Type
Default
text
Required
string | React.Element<typeof Text>
-

The content of the list item. See the text variant for guidance.

children
<React.Element<typeof List | typeof List.Item>>
-

Use List.Item to build nested lists. Use List to combine different types nested lists. See subcomponents.

Variants

Type

1. Bare: An unordered list without any bullets or alphanumeric sequence.
2. Unordered: An unordered list that does not have a sequential order. List items include a bullet point.
3. Ordered: An ordered list that contains items in a sequential order or priority. List items follow an alphanumeric sequence.

import { Box, List, Text } from 'gestalt';

export default function Example() {
  return (
    <Box
      alignItems="center"
      display="flex"
      height="100%"
      justifyContent="center"
      padding={8}
    >
      <List label={<Text weight="bold">Bare list</Text>} type="bare">
        <List.Item text="List item text" />
        <List.Item text="List item text" />
        <List.Item text="List item text" />
        <List.Item text="List item text" />
      </List>
    </Box>
  );
}

import { Box, List, Text } from 'gestalt';

export default function Example() {
  return (
    <Box
      alignItems="center"
      display="flex"
      height="100%"
      justifyContent="center"
      padding={8}
    >
      <List label={<Text weight="bold">Unordered list</Text>} type="unordered">
        <List.Item text="List item text" />
        <List.Item text="List item text" />
        <List.Item text="List item text" />
        <List.Item text="List item text" />
      </List>
    </Box>
  );
}

import { Box, List, Text } from 'gestalt';

export default function Example() {
  return (
    <Box
      alignItems="center"
      display="flex"
      height="100%"
      justifyContent="center"
      padding={8}
    >
      <List label={<Text weight="bold">Ordered list</Text>} type="ordered">
        <List.Item text="List item text" />
        <List.Item text="List item text" />
        <List.Item text="List item text" />
        <List.Item text="List item text" />
      </List>
    </Box>
  );
}

Spacing

1. Default: Space between lines defaults at 16px.
2. Condensed: Space between lines is reduced for all style varients to 8px for more condensed screens.

import { Box, List, Text } from 'gestalt';

export default function Example() {
  return (
    <Box
      alignItems="center"
      display="flex"
      height="100%"
      justifyContent="center"
      padding={8}
    >
      <List
        label={<Text weight="bold">Regular spacing</Text>}
        spacing="regular"
        type="unordered"
      >
        <List.Item text="List item text" />
        <List.Item text="List item text">
          <List.Item text="List item text">
            <List.Item text="List item text" />
            <List.Item text="List item text" />
            <List.Item text="List item text" />
          </List.Item>
          <List.Item text="List item text" />
          <List.Item text="List item text" />
        </List.Item>
        <List.Item text="List item text" />
      </List>
    </Box>
  );
}

import { Box, List, Text } from 'gestalt';

export default function Example() {
  return (
    <Box
      alignItems="center"
      display="flex"
      height="100%"
      justifyContent="center"
      padding={8}
    >
      <List
        label={<Text weight="bold">Condensed spacing</Text>}
        spacing="condensed"
        type="unordered"
      >
        <List.Item text="List item text" />
        <List.Item text="List item text">
          <List.Item text="List item text">
            <List.Item text="List item text" />
            <List.Item text="List item text" />
            <List.Item text="List item text" />
          </List.Item>
          <List.Item text="List item text" />
          <List.Item text="List item text" />
        </List.Item>
        <List.Item text="List item text" />
      </List>
    </Box>
  );
}

Nesting

List allows a maximum of six nested list items levels. Unordered lists alternate between a filled and hollow dots. Ordered lists alternate a sequence of numbers, uppercase letters, and lowercase letters.

List.Items can be nested into each other to created nested levels. Choosing to explicitly set List on each new nested level has the same effect. Gestalt List makes sure to build the right <ul>/<ol> > <li> structure under the hood in both cases. Ommiting nested Lists reduces the amount of (nested) code improving readability and faster development.

Unordered and ordered lists can be combined in the same list as well. However, to combine them, we must explicitly set List in the level with the new type.

import { Box, List, Text } from 'gestalt';

export default function Example() {
  return (
    <Box
      alignItems="center"
      display="flex"
      height="100%"
      justifyContent="center"
      padding={8}
    >
      <List
        label={<Text weight="bold">Bare unordered nested</Text>}
        type="bare"
      >
        <List.Item text="List item text">
          <List.Item text="List item text">
            <List.Item text="List item text">
              <List.Item text="List item text">
                <List.Item text="List item text">
                  <List.Item text="List item text" />
                </List.Item>
              </List.Item>
            </List.Item>
          </List.Item>
        </List.Item>
      </List>
    </Box>
  );
}

import { Box, List, Text } from 'gestalt';

export default function Example() {
  return (
    <Box
      alignItems="center"
      display="flex"
      height="100%"
      justifyContent="center"
      padding={8}
    >
      <List
        label={<Text weight="bold">Unordered nested</Text>}
        type="unordered"
      >
        <List.Item text="List item text">
          <List.Item text="List item text">
            <List.Item text="List item text">
              <List.Item text="List item text">
                <List.Item text="List item text">
                  <List.Item text="List item text" />
                </List.Item>
              </List.Item>
            </List.Item>
          </List.Item>
        </List.Item>
      </List>
    </Box>
  );
}

import { Box, List, Text } from 'gestalt';

export default function Example() {
  return (
    <Box
      alignItems="center"
      display="flex"
      height="100%"
      justifyContent="center"
      padding={8}
    >
      <List label={<Text weight="bold">Ordered nested</Text>} type="ordered">
        <List.Item text="List item text">
          <List.Item text="List item text">
            <List.Item text="List item text">
              <List.Item text="List item text">
                <List.Item text="List item text">
                  <List.Item text="List item text" />
                </List.Item>
              </List.Item>
            </List.Item>
          </List.Item>
        </List.Item>
      </List>
    </Box>
  );
}

import { Box, List, Text } from 'gestalt';

export default function Example() {
  return (
    <Box
      alignItems="center"
      display="flex"
      height="100%"
      justifyContent="center"
      padding={8}
    >
      <List
        label={<Text weight="bold">Mixed nested</Text>}
        spacing="condensed"
        type="ordered"
      >
        <List.Item text="List item text" />
        <List.Item text="List item text">
          <List type="unordered">
            <List.Item text="List item text" />
            <List.Item text="List item text">
              <List.Item text="List item text" />
              <List.Item text="List item text">
                <List type="ordered">
                  <List.Item text="List item text" />
                  <List.Item text="List item text" />
                </List>
              </List.Item>
            </List.Item>
            <List.Item text="List item text" />
          </List>
        </List.Item>
        <List.Item text="List item text" />
      </List>
    </Box>
  );
}

Text and label

List's label prop and ListItem's text prop accept either a string or Text. Use a string when no visual style is needed. List will handle the text style and adherence to design guidelines.

If custom styles are required, such as bold text, a different size, or inline links, use Text to wrap the content with any additional Text or Link components as needed. If using a Text component, do not specify color. Toast will automatically pick the correct text color for the given variant.

List's label prop is used for accessibility purposes. See the accessibility guidelines section for more information.

Default label with strings
import { Box, List } from 'gestalt';

export default function Example() {
  return (
    <Box
      alignItems="center"
      display="flex"
      height="100%"
      justifyContent="center"
      padding={8}
    >
      <List label="Button settings" type="unordered">
        <List.Item text="Pin type settings: Pin type settings control what content Pinners can save from your page" />
        <List.Item text="Button style settings: Button style settings control how your button looks" />
        <List.Item text="Source settings: Source settings control canonical sources, including descriptions, urls and images" />
      </List>
    </Box>
  );
}

Custom label with Text
import { Box, List, Text } from 'gestalt';

export default function Example() {
  return (
    <Box
      alignItems="center"
      display="flex"
      height="100%"
      justifyContent="center"
      padding={8}
    >
      <List
        label={
          <Text size="400" weight="bold">
            Button settings
          </Text>
        }
        type="unordered"
      >
        <List.Item
          text={
            <Text inline>
              <Text inline weight="bold">
                Pin type settings:{' '}
              </Text>
              Pin type settings control what content Pinners can save from your
              page
            </Text>
          }
        />
        <List.Item
          text={
            <Text inline>
              <Text inline weight="bold">
                Button style settings:{' '}
              </Text>
              Button style settings control how your button looks
            </Text>
          }
        />
        <List.Item
          text={
            <Text inline>
              <Text inline weight="bold">
                Source settings:{' '}
              </Text>
              Source settings control canonical sources, including descriptions,
              urls and images
            </Text>
          }
        />
      </List>
    </Box>
  );
}

Hidden label
import { Box, Flex, List, Text } from 'gestalt';

export default function Example() {
  return (
    <Box
      alignItems="center"
      display="flex"
      height="100%"
      justifyContent="center"
      padding={8}
    >
      <Flex direction="column" gap={4}>
        <Text>
          The Save button is one of the best ways to get your content onto
          Pinterest —through visitors to your site. Make sure your Save button
          is doing the most for you by following our best practices.
        </Text>
        <List
          label="Best practices for Save Button for developers"
          labelDisplay="hidden"
          type="unordered"
        >
          <List.Item text="Pin type settings: Include 'pinit.js' correctly" />
          <List.Item text="Use the Save button that’s best for your website" />
          <List.Item text="Multiple images on a page (like a blog)" />
        </List>
      </Flex>
    </Box>
  );
}

Size

List can be used with different font sizes. The sizes are based on our font-size design tokens. See the Text sizes variant for more details.

import { useState } from 'react';
import { Box, List, SegmentedControl, Text } from 'gestalt';

export default function Example() {
  const [selectedItemIndex, setSelectedItemIndex] = useState(0);
  const items = ['100', '200', '300', '400', '500', '600'];
  return (
    <Box
      alignItems="center"
      direction="column"
      display="flex"
      gap={6}
      height="100%"
      justifyContent="center"
      padding={8}
    >
      <List size={items[selectedItemIndex]} type="ordered">
        <List.Item text="List item text" />
        <List.Item text="List item text">
          <List.Item text="List item text" />
          <List.Item text={<Text>List Item text</Text>} />
        </List.Item>
        <List.Item text="List item text" />
      </List>
      <Box paddingY={8} width="500px">
        <SegmentedControl
          items={items}
          onChange={({ activeIndex }) => {
            setSelectedItemIndex(activeIndex);
          }}
          selectedItemIndex={selectedItemIndex}
        />
      </Box>
    </Box>
  );
}

Subcomponent composability

List requires its own subcomponents as children to build the list.

When building List, we might want to render different combinations of subcomponents conditionally. List supports simple conditional rendering of subcomponents lists wrapped in React.Fragment as well as consecutive arrays of subcomponent arrays. See the example below which illustrates both of these cases.

import { Fragment } from 'react';
import { Box, List } from 'gestalt';

export default function Example() {
  const someCondition = true;

  return (
    <Box
      alignItems="center"
      display="flex"
      height="100%"
      justifyContent="center"
      padding={8}
    >
      <List label="List with conditionals" type="unordered">
        {someCondition && <List.Item text="List item text z" />}
        <List.Item text="List item text 0">
          {someCondition && (
            <Fragment>
              <List.Item text="List item text 1" />
              <List.Item text="List item text 2" />
              <List.Item text="List item text 3" />
            </Fragment>
          )}
        </List.Item>
        {someCondition && (
          <Fragment>
            <List.Item text="List item text A" />
            <List.Item text="List item text B" />
          </Fragment>
        )}
      </List>
    </Box>
  );
}

Writing

Do
  • Length. Content should be short and to the point. Text can be sentence fragments. If you are looking to present more complex information, use Table instead.
  • Formatting. Text should be in sentence case, with a capital letter at the beginning of the phrase.
  • Phrasing. Phrase items in a similar way. For example, use a verb for the first word in each sentence (Download, Get, Book).
Don't
  • Puctuation. For short phrases, do not use periods, commas, semicolons, or any sort of punctuation at the end of each line. If the content is longer than two sentences, add a period at the end of all sentences.

  • Phrasing. Avoid repeating the first word in each list item. Instead of "Take a nap, Take a hike, Take a lap", try something like "Lie down for a nap, Go on a hike, Run a lap".

Text
The Text component is for all non-heading text on all surfaces.

Table
Table is a set of structured data that is easy for users to scan, examine and compare.

Fieldset
Fieldset creates a fieldset and legend for a group of related form items, like RadioGroup or CheckBox.