Skip to content

Latest commit

 

History

History
288 lines (239 loc) · 9.88 KB

File metadata and controls

288 lines (239 loc) · 9.88 KB

import {Layout} from '../../src/Layout'; export default Layout;

import docs from 'docs:react-aria-components'; import {GridList as VanillaGridList, GridListItem} from 'vanilla-starter/GridList'; import vanillaDocs from 'docs:vanilla-starter/GridList'; import '../../tailwind/tailwind.css'; import Anatomy from 'react-aria-components/docs/GridListAnatomy.svg';

export const tags = ['list view'];

GridList

{docs.exports.GridList.description}

```tsx render docs={docs.exports.GridList} links={docs.links} props={['selectionMode']} initialProps={{'aria-label': 'Favorite pokemon', selectionMode: 'multiple'}} type="vanilla" files={["starters/docs/src/GridList.tsx", "starters/docs/src/GridList.css"]} "use client"; import {GridList, GridListItem} from 'vanilla-starter/GridList'; import {Button} from 'vanilla-starter/Button';

<GridList/* PROPS */> Charizard ⓘ Blastoise ⓘ Venusaur ⓘ Pikachu ⓘ


```tsx render docs={docs.exports.GridList} links={docs.links} props={['selectionMode']} initialProps={{'aria-label': 'Favorite animal', selectionMode: 'multiple'}} type="tailwind" files={["starters/tailwind/src/GridList.tsx"]}
"use client";
import {GridList, GridListItem} from 'tailwind-starter/GridList';

<GridList/* PROPS */>
  <GridListItem>Aardvark</GridListItem>
  <GridListItem>Cat</GridListItem>
  <GridListItem>Dog</GridListItem>
  <GridListItem>Kangaroo</GridListItem>
  <GridListItem>Panda</GridListItem>
  <GridListItem>Snake</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.

"use client";
import {GridList, GridListItem} from 'vanilla-starter/GridList';

function Example() {
  let options = [
    { id: 1, name: 'Aardvark' },
    { id: 2, name: 'Cat' },
    { id: 3, name: 'Dog' },
    { id: 4, name: 'Kangaroo' },
    { id: 5, name: 'Koala' },
    { id: 6, name: 'Penguin' },
    { id: 7, name: 'Snake' },
    { id: 8, name: 'Turtle' },
    { id: 9, name: 'Wombat' }
  ];

  return (
    /*- begin highlight -*/
    <GridList aria-label="Animals" items={options} selectionMode="multiple">
      {(item) => <GridListItem>{item.name}</GridListItem>}
    </GridList>
    /*- end highlight -*/
  );
}

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.

"use client";
import {Collection, GridListLoadMoreItem} from 'react-aria-components';
import {GridList, GridListItem} from 'vanilla-starter/GridList';
import {ProgressCircle} from 'vanilla-starter/ProgressCircle';
import {useAsyncList} from '@react-stately/data';

interface Character {
  name: string
}

function AsyncLoadingExample() {
  let list = useAsyncList<Character>({
    async load({ signal, cursor }) {
      if (cursor) {
        cursor = cursor.replace(/^http:\/\//i, 'https://');
      }

      let res = await fetch(
        cursor || `https://swapi.py4e.com/api/people/?search=`,
        { signal }
      );
      let json = await res.json();

      return {
        items: json.results,
        cursor: json.next
      };
    }
  });

  return (
    <GridList
      aria-label="Star Wars Characters"
      selectionMode="multiple"
      renderEmptyState={() => (
        <ProgressCircle isIndeterminate aria-label="Loading..." />
      )}>
      <Collection items={list.items}>
        {(item) => <GridListItem id={item.name}>{item.name}</GridListItem>}
      </Collection>
      {/*- begin highlight -*/}
      <GridListLoadMoreItem
        onLoadMore={list.loadMore}
        isLoading={list.loadingState === 'loadingMore'}>
        <ProgressCircle isIndeterminate aria-label="Loading more..." />
      </GridListLoadMoreItem>
      {/*- end highlight -*/}
    </GridList>
  );
}

Links

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.

"use client";
import {GridList, GridListItem} from 'vanilla-starter/GridList';

<GridList/* PROPS */>
  {/*- begin highlight -*/}
  <GridListItem href="https://adobe.com/" target="_blank">Adobe</GridListItem>
  {/*- end highlight -*/}
  <GridListItem href="https://apple.com/" target="_blank">Apple</GridListItem>
  <GridListItem href="https://google.com/" target="_blank">Google</GridListItem>
  <GridListItem href="https://microsoft.com/" target="_blank">Microsoft</GridListItem>
</GridList>

Empty state

"use client";
import {GridList} from 'vanilla-starter/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.

"use client";
import type {Selection} from 'react-aria-components';
import {GridList, GridListItem} from 'vanilla-starter/GridList';
import {useState} from 'react';

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

  return (
    <div>
      <GridList
        {...props}
        aria-label="Sandwich contents"
        ///- begin highlight -///
        /* PROPS */
        selectedKeys={selected}
        onSelectionChange={setSelected}
        onAction={key => alert(`Clicked ${key}`)}
        ///- end highlight -///
      >
        <GridListItem id="lettuce">Lettuce</GridListItem>
        <GridListItem id="tomato">Tomato</GridListItem>
        <GridListItem id="cheese">Cheese</GridListItem>
        <GridListItem id="tuna" isDisabled>Tuna Salad</GridListItem>
        <GridListItem id="egg">Egg Salad</GridListItem>
        <GridListItem id="ham">Ham</GridListItem>
      </GridList>
      <p>Current selection: {selected === 'all' ? 'all' : [...selected].join(', ')}</p>
    </div>
  );
}

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.

"use client";
import {useListData} from 'react-stately';
import {GridList, GridListItem} from 'vanilla-starter/GridList';
import {useDragAndDrop} from 'react-aria-components';

function Example() {
  let list = useListData({
    initialItems: [
      {id: 1, name: 'Adobe Photoshop'},
      {id: 2, name: 'Adobe XD'},
      {id: 3, name: 'Adobe Dreamweaver'},
      {id: 4, name: 'Adobe InDesign'},
      {id: 5, name: 'Adobe Connect'}
    ]
  });

  ///- begin highlight -///
  let {dragAndDropHooks} = useDragAndDrop({
    getItems: (keys) => [...keys].map(key => ({'text/plain': list.getItem(key).name})),
    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);
      }
    }
  });
  ///- end highlight -///

  return (
    <GridList
      aria-label="Reorderable list"
      selectionMode="multiple"
      items={list.items}
      ///- begin highlight -///
      dragAndDropHooks={dragAndDropHooks}
      ///- end highlight -///
    >
      {item => <GridListItem>{item.name}</GridListItem>}
    </GridList>
  );
}

API

<GridList>
  <GridListItem>
    <Button slot="drag" />
    <Checkbox slot="selection" /> or <SelectionIndicator />
  </GridListItem>
  <GridListLoadMoreItem />
</GridList>

GridList

GridListItem

GridListLoadMoreItem