# List
The list is a scrollable component in which the list rows are rendered.
### Product List

```tsx
import React, {useState} from 'react';
import {
  Navigator,
  Screen,
  List,
  Text,
  ScrollView,
  Section,
  ListRowSubtitle,
  reactExtension,
} from '@shopify/ui-extensions-react/point-of-sale';

const SmartGridModal = () => {
  const [seeDetails, setSeeDetails] = useState(false);
  const listData = [
    {
      id: 'graphicTees',
      leftSide: {
        label: 'Graphic Tees',
        subtitle: [{content: 'Summer Collection'}, {content: 'Unisex'}] as [
          ListRowSubtitle,
          ListRowSubtitle?,
        ],
      },
      rightSide: {
        label: 'Product details',
        showChevron: true,
      },
      onPress: () => setSeeDetails(!seeDetails),
    },
    {
      id: 'denimShorts',
      leftSide: {
        label: 'Denim Shorts',
        subtitle: [{content: 'Summer Collection'}, {content: 'Denim'}] as [
          ListRowSubtitle,
          ListRowSubtitle?,
        ],
      },
    },
  ];
  return (
    <Navigator>
      <Screen name="ProductList" title="Product List">
        <List title="Products" data={listData} />
        {seeDetails && (
          <ScrollView>
            <Section title="Our T-shirts">
              <Text>Our shirts are made with 100% organic cotton!</Text>
            </Section>
          </ScrollView>
        )}
      </Screen>
    </Navigator>
  );
};

export default reactExtension('pos.home.modal.render', () => (
  <SmartGridModal />
));

```

```ts
import {
  Navigator,
  Screen,
  List,
  Text,
  ScrollView,
  Section,
  ListRowSubtitle,
  extension,
} from '@shopify/ui-extensions/point-of-sale';

export default extension('pos.home.modal.render', (root, api) => {
  let showDetails = false;
  const section = root.createComponent(Section, {
    title: 'Our T-shirts',
  });

  const scrollView = root.createComponent(ScrollView);

  const triggerShowDetails = () => {
    showDetails = !showDetails;
    if (showDetails) {
      scrollView.append(section);
    } else {
      scrollView.removeChild(section);
    }
  };

  const listData = [
    {
      id: 'graphicTees',
      leftSide: {
        label: 'Graphic Tees',
        subtitle: [{content: 'Summer Collection'}, {content: 'Unisex'}] as [
          ListRowSubtitle,
          ListRowSubtitle?,
        ],
      },
      rightSide: {
        label: 'Product details',
        showChevron: true,
      },
      onPress: () => triggerShowDetails(),
    },
    {
      id: 'denimShorts',
      leftSide: {
        label: 'Denim Shorts',
        subtitle: [{content: 'Summer Collection'}, {content: 'Denim'}] as [
          ListRowSubtitle,
          ListRowSubtitle?,
        ],
      },
    },
  ];

  const list = root.createComponent(List, {
    title: 'Products',
    data: listData,
  });

  const textBlock = root.createComponent(
    Text,
    null,
    'Our shirts are made with 100% organic cotton!',
  );

  section.append(textBlock);

  const screen = root.createComponent(Screen, {
    name: 'ProductList',
    title: 'Product List',
  });

  screen.append(list);

  if (showDetails) {
    scrollView.append(section);
  }

  screen.append(scrollView);

  const navigator = root.createComponent(Navigator);
  navigator.append(screen);

  root.append(navigator);
});

```


## List

### ListProps

### data
The array of `ListRow` which will be converted into rows for this list.
### imageDisplayStrategy
The logic behind displaying an image or placeholder. `automatic` will display an image or placeholder if it detects that a `ListItem` in `data` has an `imageUri` value. `never` will never display images or placeholders. `always` will always display images or placeholders if `imageUri` is undefined or empty.
### isLoadingMore
Whether or not more data is being loaded. Set this to `true` when paginating and fetching more data for the list.
### listHeaderComponent
A header component for the list.
### onEndReached
Callback for when the user reaches the end of the `List`. This can be used to fire a request to load more data.
### title
A large display title at the top of the `List`.
### ListRow

### id
The unique identifier for this list item.
### leftSide
The user interface of the left side of the row.
### onPress
Callback for when the user taps the row.
### rightSide
The user interface of the right side of the row.
### ListRowLeftSide

### badges
Colored badges that are displayed underneath the `title` and `subtitles`.
### image

### label
The main label that will be displayed on the left side of the row.
### subtitle
The subtitles to display beneath the main label. Up to 3 subtitles can be displayed. Subtitles can optionally be configured with colors by passing an object with a `content` and `color` properties.
### BadgeProps

### status
A circle icon displaying the status of the badge.
### text
The text displayed inside the badge.
### variant
The appearance and function of the badge.
### BadgeStatus

'empty' | 'partial' | 'complete'
### BadgeVariant

'neutral' | 'critical' | 'warning' | 'success' | 'highlight'
### ListRowSubtitle

string | SubtitleType
### SubtitleType

### color
Property used to modify the subtitle appearance.
### content
The subtitles to display beneath the main label.
### ColorType

'TextNeutral' | 'TextSubdued' | 'TextDisabled' | 'TextWarning' | 'TextCritical' | 'TextSuccess' | 'TextInteractive' | 'TextHighlight'
### ListRowRightSide

### label
The main label that will be displayed on the right side of the row.
### showChevron
Show a chevron. Set this to true if pressing on the row navigates to another screen.
### toggleSwitch
A toggle switch that is be displayed on the right side of the row.
### ToggleSwitch

### disabled
Whether or not the toggle switch is disabled.
### value
Whether or not the toggle switch is on or off.
## Related
- [ProductSearch API](/api/pos-ui-extensions/apis/productsearch-api#example-search-for-products-with-a-search-bar)