Beta Preview

GridList

A grid list displays a list of interactive items, with support for keyboard navigation, single or multiple selection, and row actions.

Theme
Desert SunsetPNG • 2/3/2024
Hiking TrailJPEG • 1/10/2022
LionJPEG • 8/28/2021
Mountain SunrisePNG • 3/15/2015
Giraffe tonguePNG • 11/27/2019
Golden HourWEBP • 7/24/2024
ArchitecturePNG • 12/24/2016
Peeking leopardJPEG • 3/2/2016
RoofsJPEG • 4/24/2025
Half Dome DeerDNG • 8/28/2018
layout 
selectionMode 
Example
GridList.tsx
import {Text} from 'react-aria-components';
import {GridList, GridListItem} from './GridList';
import {Button} from './Button';

<GridList
  aria-label="Favorite pokemon"
  selectionMode="multiple"
  layout="grid">
  <GridListItem textValue="Desert Sunset">
    <img src="https://images.unsplash.com/photo-1705034598432-1694e203cdf3?q=80&w=600&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" width={600} height={400} />
    <Text>Desert Sunset</Text>
    <Text slot="description">PNG • 2/3/2024</Text>
  </GridListItem>
  <GridListItem textValue="Hiking Trail">
    <img src="https://images.unsplash.com/photo-1722233987129-61dc344db8b6?q=80&w=600&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" width={600} height={900} />
    <Text>Hiking Trail</Text>
    <Text slot="description">JPEG • 1/10/2022</Text>
  </GridListItem>
  <GridListItem textValue="Lion">
    <img src="https://images.unsplash.com/photo-1629812456605-4a044aa38fbc?q=80&w=600&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" width={600} height={899} />
    <Text>Lion</Text>
    <Text slot="description">JPEG • 8/28/2021</Text>
  </GridListItem>
  <GridListItem textValue="Mountain Sunrise">
    <img src="https://images.unsplash.com/photo-1722172118908-1a97c312ce8c?q=80&w=600&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" width={600} height={900} />
    <Text>Mountain Sunrise</Text>
    <Text slot="description">PNG • 3/15/2015</Text>
  </GridListItem>
  <GridListItem textValue="Giraffe tongue">
    <img src="https://images.unsplash.com/photo-1574870111867-089730e5a72b?q=80&w=600&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" width={600} height={900} />
    <Text>Giraffe tongue</Text>
    <Text slot="description">PNG • 11/27/2019</Text>
  </GridListItem>
  <GridListItem textValue="Golden Hour">
    <img src="https://images.unsplash.com/photo-1718378037953-ab21bf2cf771?q=80&w=600&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" width={600} height={402} />
    <Text>Golden Hour</Text>
    <Text slot="description">WEBP • 7/24/2024</Text>
  </GridListItem>
  <GridListItem textValue="Architecture">
    <img src="https://images.unsplash.com/photo-1721661657253-6621d52db753?w=600&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHx0b3BpYy1mZWVkfDYxfE04alZiTGJUUndzfHxlbnwwfHx8fHw%3D" width={600} height={900} />
    <Text>Architecture</Text>
    <Text slot="description">PNG • 12/24/2016</Text>
  </GridListItem>
  <GridListItem textValue="Peeking leopard">
    <img src="https://images.unsplash.com/photo-1456926631375-92c8ce872def?q=80&w=600&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" width={600} height={400} />
    <Text>Peeking leopard</Text>
    <Text slot="description">JPEG • 3/2/2016</Text>
  </GridListItem>
  <GridListItem textValue="Roofs">
    <img src="https://images.unsplash.com/photo-1721598359121-363311b3b263?w=600&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHx0b3BpYy1mZWVkfDc0fE04alZiTGJUUndzfHxlbnwwfHx8fHw%3D" width={600} height={900} />
    <Text>Roofs</Text>
    <Text slot="description">JPEG • 4/24/2025</Text>
  </GridListItem>
  <GridListItem textValue="Half Dome Deer">
    <img src="https://images.unsplash.com/photo-1472396961693-142e6e269027?q=80&w=600&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" width={600} height={990} />
    <Text>Half Dome Deer</Text>
    <Text slot="description">DNG • 8/28/2018</Text>
  </GridListItem>
</GridList>

Content

GridList follows the Collection Components API, accepting both static and dynamic collections. This example shows a dynamic collection, passing a list of objects to the items prop, and a function to render the children.

A Ficus Lyrata LeafBy Clay Banks
Italian beachBy Alan Bajura
Forest roadBy Artem Stoliar
Snowy AuroraBy Janosch Diggelmann
A blue and white firework is seen from aboveBy Janosch Diggelmann
Snowy MountainBy Daniil Silantev
Pastel SunsetBy Marek Piwnicki
Snowy BirchesBy Simon Berger
Snowy Lake ReflectionsBy Daniel Seßler
Rocky night skyBy Dennis Haug
A pine tree covered in snow in a forestBy Anita Austvika
The sun shines through the trees in the forestBy Joyce G
A blurry photo of a field of flowersBy Eugene Golovesov
A foggy road lined with trees and grassBy Ingmar H
A close up of a green palm treeBy Junel Mujar
A green leaf floating on top of a body of waterBy Allec Gomes
Leafy plantsBy Joshua Michaels
A view of a mountain covered in fogBy iuliu illes
A field with tall grass and fog in the backgroundBy Ingmar H
A close up of a wave on a sandy beachBy Jonathan Borba
Desert texturesBy Braden Jarvis
Tew Falls, waterfall, in Hamilton, Canada.By Andre Portolesi
Cave light raysBy Intricate Explorer
Salt Marshes, Isle of Harris, ScotlandBy Nils Leonhardt
An aerial view of a snow covered forestBy Lukas Hädrich
Tall grassBy Ingmar H
Larches on Maple Pass, WashingtonBy Noelle
Heart NebulaBy Arnaud Girault
A pile of shells sitting on top of a sandy beachBy Toa Heftiba
import {GridList, GridListItem} from './GridList';
import {Text} from 'react-aria-components';

function Example() { return ( <GridList
aria-label="Nature photos" selectionMode="multiple" layout="grid" items={images}> {(image) => ( <GridListItem textValue={image.title}> <img src={image.image} width={image.width} height={image.height} /> <Text>{image.title}</Text> <Text slot="description">By {image.user}</Text> </GridListItem> )} </GridList> ); }

Asynchronous loading

Use renderEmptyState to display a spinner during initial load. To enable infinite scrolling, render a <GridListLoadMoreItem> at the end of the list. Use whatever data fetching library you prefer – this example uses useAsyncList from react-stately.

import {GridList, GridListItem, GridListLoadMoreItem} from './GridList';
import {Collection, Text} from 'react-aria-components';
import {ProgressCircle} from './ProgressCircle';
import {useAsyncList} from '@react-stately/data';

function AsyncLoadingExample() {
  let list = useAsyncList<Item, number | null>({
    async load({signal, cursor, items}) {
      let page = cursor || 1;
      let res = await fetch(
        `https://api.unsplash.com/topics/nature/photos?page=${page}&per_page=30&client_id=AJuU-FPh11hn7RuumUllp4ppT8kgiLS7LtOHp_sp4nc`,
        {signal}
      );
      let nextItems = await res.json();
      // Filter duplicates which might be returned by the API.
      let existingKeys = new Set(items.map(i => i.id));
      nextItems = nextItems.filter(i => !existingKeys.has(i.id) && (i.description || i.alt_description));
      return {items: nextItems, cursor: nextItems.length ? page + 1 : null};
    }
  });

  return (
    <GridList
      aria-label="Nature photos"
      layout="grid"
      selectionMode="multiple"
      renderEmptyState={() => (
        <ProgressCircle isIndeterminate aria-label="Loading..." />
      )}>
      <Collection items={list.items}>
        {(item) => (
          <GridListItem textValue={item.description || item.alt_description}>
            <img src={item.urls.regular} width={item.width} height={item.height} />
            <Text>{item.description || item.alt_description}</Text>
            <Text slot="description">By {item.user.name}</Text>
          </GridListItem>
        )}
      </Collection>
      <GridListLoadMoreItem
        onLoadMore={list.loadMore}
        isLoading={list.loadingState === 'loadingMore'} />
    </GridList>
  );
}

Use the href prop on a <GridListItem> to create a link. See the client side routing guide to learn how to integrate with your framework. Link interactions vary depending on the selection behavior. See the selection guide for more details.

Tropical island
Bryce Canyon
Snowy river
Ocean waves
Mount Kazbek at Dawn
Snowy mountain sunrise
Mount Blum
Sunset
selectionBehavior 
import {GridList, GridListItem} from './GridList';
import {Text} from 'react-aria-components';

<GridList layout="grid" items={images} aria-label="Links" selectionMode="multiple"> {image => ( <GridListItem href={image.href} target="_blank" textValue={image.title}> <img src={image.image} width={image.width} height={image.height} /> <Text>{image.title}</Text> </GridListItem> )} </GridList>

Empty state

No results found.
import {GridList} from './GridList';

<GridList
  aria-label="Search results"
  renderEmptyState={() => 'No results found.'}>
  {[]}
</GridList>

Selection and actions

Use the selectionMode prop to enable single or multiple selection. The selected items can be controlled via the selectedKeys prop, matching the id prop of the items. The onAction event handles item actions. Items can be disabled with the isDisabled prop. See the selection guide for more details.

Desert SunsetPNG • 2/3/2024
Hiking TrailJPEG • 1/10/2022
LionJPEG • 8/28/2021
Mountain SunrisePNG • 3/15/2015
Giraffe tonguePNG • 11/27/2019
Golden HourWEBP • 7/24/2024
ArchitecturePNG • 12/24/2016
Peeking leopardJPEG • 3/2/2016
RoofsJPEG • 4/24/2025
Half Dome DeerDNG • 8/28/2018

Current selection:

selectionMode 
selectionBehavior 
disabledBehavior 
disallowEmptySelection 
import {type Selection, Text} from 'react-aria-components';
import {GridList, GridListItem} from './GridList';
import {useState} from 'react';

function Example(props) {
  let [selected, setSelected] = useState<Selection>(new Set());

  return (
    <>
      <GridList
        {...props}
        aria-label="Nature photos"
        layout="grid"
        selectionMode="multiple"
        selectedKeys={selected}
        onSelectionChange={setSelected}
        onAction={key => alert(`Clicked ${key}`)}
      >
        <GridListItem id={1} textValue="Desert Sunset">
          <img src="https://images.unsplash.com/photo-1705034598432-1694e203cdf3?q=80&w=600&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" width={600} height={400} />
          <Text>Desert Sunset</Text>
          <Text slot="description">PNG • 2/3/2024</Text>
        </GridListItem>
        <GridListItem id={2} isDisabled textValue="Hiking Trail">
          <img src="https://images.unsplash.com/photo-1722233987129-61dc344db8b6?q=80&w=600&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" width={600} height={900} />
          <Text>Hiking Trail</Text>
          <Text slot="description">JPEG • 1/10/2022</Text>
        </GridListItem>
        <GridListItem id={3} textValue="Lion">
          <img src="https://images.unsplash.com/photo-1629812456605-4a044aa38fbc?q=80&w=600&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" width={600} height={899} />
          <Text>Lion</Text>
          <Text slot="description">JPEG • 8/28/2021</Text>
        </GridListItem>
        <GridListItem id={4} textValue="Mountain Sunrise">
          <img src="https://images.unsplash.com/photo-1722172118908-1a97c312ce8c?q=80&w=600&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" width={600} height={900} />
          <Text>Mountain Sunrise</Text>
          <Text slot="description">PNG • 3/15/2015</Text>
        </GridListItem>
        <GridListItem id={5} textValue="Giraffe tongue">
          <img src="https://images.unsplash.com/photo-1574870111867-089730e5a72b?q=80&w=600&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" width={600} height={900} />
          <Text>Giraffe tongue</Text>
          <Text slot="description">PNG • 11/27/2019</Text>
        </GridListItem>
        <GridListItem id={6} textValue="Golden Hour">
          <img src="https://images.unsplash.com/photo-1718378037953-ab21bf2cf771?q=80&w=600&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" width={600} height={402} />
          <Text>Golden Hour</Text>
          <Text slot="description">WEBP • 7/24/2024</Text>
        </GridListItem>
        <GridListItem id={7} textValue="Architecture">
          <img src="https://images.unsplash.com/photo-1721661657253-6621d52db753?w=600&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHx0b3BpYy1mZWVkfDYxfE04alZiTGJUUndzfHxlbnwwfHx8fHw%3D" width={600} height={900} />
          <Text>Architecture</Text>
          <Text slot="description">PNG • 12/24/2016</Text>
        </GridListItem>
        <GridListItem id={8} textValue="Peeking leopard">
          <img src="https://images.unsplash.com/photo-1456926631375-92c8ce872def?q=80&w=600&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" width={600} height={400} />
          <Text>Peeking leopard</Text>
          <Text slot="description">JPEG • 3/2/2016</Text>
        </GridListItem>
        <GridListItem id={9} textValue="Roofs">
          <img src="https://images.unsplash.com/photo-1721598359121-363311b3b263?w=600&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHx0b3BpYy1mZWVkfDc0fE04alZiTGJUUndzfHxlbnwwfHx8fHw%3D" width={600} height={900} />
          <Text>Roofs</Text>
          <Text slot="description">JPEG • 4/24/2025</Text>
        </GridListItem>
        <GridListItem id={10} textValue="Half Dome Deer">
          <img src="https://images.unsplash.com/photo-1472396961693-142e6e269027?q=80&w=600&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" width={600} height={990} />
          <Text>Half Dome Deer</Text>
          <Text slot="description">DNG • 8/28/2018</Text>
        </GridListItem>
      </GridList>
      <p>Current selection: {selected === 'all' ? 'all' : [...selected].join(', ')}</p>
    </>
  );
}

Drag and drop

GridList supports drag and drop interactions when the dragAndDropHooks prop is provided using the hook. Users can drop data on the list as a whole, on individual items, insert new items between existing ones, or reorder items. React Aria supports drag and drop via mouse, touch, keyboard, and screen reader interactions. See the drag and drop guide to learn more.

A Ficus Lyrata Leaf in the sunlight (2/2) (IG: @clay.banks)Clay Banks
beach of Italyalan bajura
A winding road in the middle of a forestArtem Stoliar
A green and purple aurora over a snow covered forestJanosch Diggelmann
A blue and white firework is seen from aboveJanosch Diggelmann
A snow covered mountain with a sky backgroundDaniil Silantev
"Pastel Sunset"Marek Piwnicki
Leave the weight behind! You must make yourself light to strive upwards — to reach the light. (A serene winter landscape featuring a dense collection of bare, white trees.)Simon Berger
A snow covered tree with a sky backgroundDaniil Silantev
A lake surrounded by trees covered in snowDaniel Seßler
The night sky with stars above a rock formationDennis Haug
A pine tree covered in snow in a forestAnita Austvika
The sun shines through the trees in the forestJoyce G
A blurry photo of a field of flowersEugene Golovesov
A foggy road lined with trees and grassIngmar H
A close up of a green palm treeJunel Mujar
A green leaf floating on top of a body of waterAllec Gomes
green-leafed plantJoshua Michaels
A view of a mountain covered in fogiuliu illes
A field with tall grass and fog in the backgroundIngmar H
A close up of a wave on a sandy beachJonathan Borba
Desert texturesBraden Jarvis
Tew Falls, waterfall, in Hamilton, Canada.Andre Portolesi
Find me on Instagram! @intricateexplorerIntricate Explorer
Salt Marshes, Isle of Harris, Scotland by Nils Leonhardt. Visit my website: https://nilsleonhardt.com/storytelling-harris/ Instagram: @am.basteirNils Leonhardt
An aerial view of a snow covered forestLukas Hädrich
A close up of a tall grass with a sky in the backgroundIngmar H
Larches on Maple Pass, Washingtonnoelle
IC 1805 La nébuleuse du coeurarnaud girault
A pile of shells sitting on top of a sandy beachToa Heftiba
import {useListData} from 'react-stately';
import {GridList, GridListItem} from './GridList';
import {useDragAndDrop, Text} from 'react-aria-components';

function Example() { let list = useListData({ initialItems: images
}); let {dragAndDropHooks} = useDragAndDrop({ getItems: (keys) => [...keys].map(key => ({'text/plain': list.getItem(key).title})), onReorder(e) { if (e.target.dropPosition === 'before') { list.moveBefore(e.target.key, e.keys); } else if (e.target.dropPosition === 'after') { list.moveAfter(e.target.key, e.keys); } } }); return ( <GridList aria-label="Reorderable list" layout="grid" selectionMode="multiple" items={list.items} dragAndDropHooks={dragAndDropHooks} > {image => ( <GridListItem textValue={image.title}> <img src={image.image} width={image.width} height={image.height} /> <Text>{image.title}</Text> <Text slot="description">{image.user}</Text> </GridListItem> )} </GridList> ); }

API

DocumentsItemSelectioncheckboxDragbutton12 itemsOnboardingPDFBudgetXLSSales PitchPPTDragbutton