List

Simple List.

When To Use#

A list can be used to display content related to a single subject. The content can consist of multiple elements of varying type and size.

Examples

Header
  • [ITEM] Racing car sprays burning fuel into crowd.
  • [ITEM] Japanese princess to wed commoner.
  • [ITEM] Australian walks 100km after outback crash.
  • [ITEM] Man charged over missing wedding girl.
  • [ITEM] Los Angeles battles huge wildfires.
Header
  • Racing car sprays burning fuel into crowd.
  • Japanese princess to wed commoner.
  • Australian walks 100km after outback crash.
  • Man charged over missing wedding girl.
  • Los Angeles battles huge wildfires.
Header
  • Racing car sprays burning fuel into crowd.
  • Japanese princess to wed commoner.
  • Australian walks 100km after outback crash.
  • Man charged over missing wedding girl.
  • Los Angeles battles huge wildfires.

Infra Design supports a default list size as well as a large and small size.

If a large or small list is desired, set the size property to either large or small respectively. Omit the size property for a list with the default size.

Customizing the header and footer of list by setting header and footer property.

expand codeexpand code
import { Divider, List, Typography } from 'infrad';
import React from 'react';

const data = [
  'Racing car sprays burning fuel into crowd.',
  'Japanese princess to wed commoner.',
  'Australian walks 100km after outback crash.',
  'Man charged over missing wedding girl.',
  'Los Angeles battles huge wildfires.',
];

const App: React.FC = () => (
  <>
    <Divider orientation="left">Default Size</Divider>
    <List
      header={<div>Header</div>}
      footer={<div>Footer</div>}
      bordered
      dataSource={data}
      renderItem={item => (
        <List.Item>
          <Typography.Text mark>[ITEM]</Typography.Text> {item}
        </List.Item>
      )}
    />
    <Divider orientation="left">Small Size</Divider>
    <List
      size="small"
      header={<div>Header</div>}
      footer={<div>Footer</div>}
      bordered
      dataSource={data}
      renderItem={item => <List.Item>{item}</List.Item>}
    />
    <Divider orientation="left">Large Size</Divider>
    <List
      size="large"
      header={<div>Header</div>}
      footer={<div>Footer</div>}
      bordered
      dataSource={data}
      renderItem={item => <List.Item>{item}</List.Item>}
    />
  </>
);

export default App;
  • Infra Design Title 1

    Infra Design, a design language for background applications, is refined by Ant UED Team
  • Infra Design Title 2

    Infra Design, a design language for background applications, is refined by Ant UED Team
  • Infra Design Title 3

    Infra Design, a design language for background applications, is refined by Ant UED Team
  • Infra Design Title 4

    Infra Design, a design language for background applications, is refined by Ant UED Team

Basic list.

expand codeexpand code
import { Avatar, List } from 'infrad';
import React from 'react';

const data = [
  {
    title: 'Infra Design Title 1',
  },
  {
    title: 'Infra Design Title 2',
  },
  {
    title: 'Infra Design Title 3',
  },
  {
    title: 'Infra Design Title 4',
  },
];

const App: React.FC = () => (
  <List
    itemLayout="horizontal"
    dataSource={data}
    renderItem={item => (
      <List.Item>
        <List.Item.Meta
          avatar={<Avatar src="https://joeschmoe.io/api/v1/random" />}
          title={<a href="https://ant.design">{item.title}</a>}
          description="Infra Design, a design language for background applications, is refined by Ant UED Team"
        />
      </List.Item>
    )}
  />
);

export default App;

Load more list with loadMore property.

expand codeexpand code
import { Avatar, Button, List, Skeleton } from 'infrad';
import React, { useEffect, useState } from 'react';

interface DataType {
  gender?: string;
  name: {
    title?: string;
    first?: string;
    last?: string;
  };
  email?: string;
  picture: {
    large?: string;
    medium?: string;
    thumbnail?: string;
  };
  nat?: string;
  loading: boolean;
}

const count = 3;
const fakeDataUrl = `https://randomuser.me/api/?results=${count}&inc=name,gender,email,nat,picture&noinfo`;

const App: React.FC = () => {
  const [initLoading, setInitLoading] = useState(true);
  const [loading, setLoading] = useState(false);
  const [data, setData] = useState<DataType[]>([]);
  const [list, setList] = useState<DataType[]>([]);

  useEffect(() => {
    fetch(fakeDataUrl)
      .then(res => res.json())
      .then(res => {
        setInitLoading(false);
        setData(res.results);
        setList(res.results);
      });
  }, []);

  const onLoadMore = () => {
    setLoading(true);
    setList(
      data.concat([...new Array(count)].map(() => ({ loading: true, name: {}, picture: {} }))),
    );
    fetch(fakeDataUrl)
      .then(res => res.json())
      .then(res => {
        const newData = data.concat(res.results);
        setData(newData);
        setList(newData);
        setLoading(false);
        // Resetting window's offsetTop so as to display react-virtualized demo underfloor.
        // In real scene, you can using public method of react-virtualized:
        // https://stackoverflow.com/questions/46700726/how-to-use-public-method-updateposition-of-react-virtualized
        window.dispatchEvent(new Event('resize'));
      });
  };

  const loadMore =
    !initLoading && !loading ? (
      <div
        style={{
          textAlign: 'center',
          marginTop: 12,
          height: 32,
          lineHeight: '32px',
        }}
      >
        <Button onClick={onLoadMore}>loading more</Button>
      </div>
    ) : null;

  return (
    <List
      className="demo-loadmore-list"
      loading={initLoading}
      itemLayout="horizontal"
      loadMore={loadMore}
      dataSource={list}
      renderItem={item => (
        <List.Item
          actions={[<a key="list-loadmore-edit">edit</a>, <a key="list-loadmore-more">more</a>]}
        >
          <Skeleton avatar title={false} loading={item.loading} active>
            <List.Item.Meta
              avatar={<Avatar src={item.picture.large} />}
              title={<a href="https://ant.design">{item.name?.last}</a>}
              description="Infra Design, a design language for background applications, is refined by Ant UED Team"
            />
            <div>content</div>
          </Skeleton>
        </List.Item>
      )}
    />
  );
};

export default App;
.demo-loadmore-list {
  min-height: 350px;
}
  • ant design part 0

    Infra Design, a design language for background applications, is refined by Ant UED Team.
    We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently.
    • 156
    • 156
    • 2
    logo
  • ant design part 1

    Infra Design, a design language for background applications, is refined by Ant UED Team.
    We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently.
    • 156
    • 156
    • 2
    logo
  • ant design part 2

    Infra Design, a design language for background applications, is refined by Ant UED Team.
    We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently.
    • 156
    • 156
    • 2
    logo

Set the itemLayout property to vertical to create a vertical list.

expand codeexpand code
import { LikeOutlined, MessageOutlined, StarOutlined } from 'infra-design-icons';
import { Avatar, List, Space } from 'infrad';
import React from 'react';

const data = Array.from({ length: 23 }).map((_, i) => ({
  href: 'https://ant.design',
  title: `ant design part ${i}`,
  avatar: 'https://joeschmoe.io/api/v1/random',
  description:
    'Infra Design, a design language for background applications, is refined by Ant UED Team.',
  content:
    'We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently.',
}));

const IconText = ({ icon, text }: { icon: React.FC; text: string }) => (
  <Space>
    {React.createElement(icon)}
    {text}
  </Space>
);

const App: React.FC = () => (
  <List
    itemLayout="vertical"
    size="large"
    pagination={{
      onChange: page => {
        console.log(page);
      },
      pageSize: 3,
    }}
    dataSource={data}
    footer={
      <div>
        <b>ant design</b> footer part
      </div>
    }
    renderItem={item => (
      <List.Item
        key={item.title}
        actions={[
          <IconText icon={StarOutlined} text="156" key="list-vertical-star-o" />,
          <IconText icon={LikeOutlined} text="156" key="list-vertical-like-o" />,
          <IconText icon={MessageOutlined} text="2" key="list-vertical-message" />,
        ]}
        extra={
          <img
            width={272}
            alt="logo"
            src="https://gw.alipayobjects.com/zos/rmsportal/mqaQswcyDLcXyDKnZfES.png"
          />
        }
      >
        <List.Item.Meta
          avatar={<Avatar src={item.avatar} />}
          title={<a href={item.href}>{item.title}</a>}
          description={item.description}
        />
        {item.content}
      </List.Item>
    )}
  />
);

export default App;
Title 1
Card content
Title 2
Card content
Title 3
Card content
Title 4
Card content

Create a grid layout by setting the grid property of List.

expand codeexpand code
import { Card, List } from 'infrad';
import React from 'react';

const data = [
  {
    title: 'Title 1',
  },
  {
    title: 'Title 2',
  },
  {
    title: 'Title 3',
  },
  {
    title: 'Title 4',
  },
];

const App: React.FC = () => (
  <List
    grid={{ gutter: 16, column: 4 }}
    dataSource={data}
    renderItem={item => (
      <List.Item>
        <Card title={item.title}>Card content</Card>
      </List.Item>
    )}
  />
);

export default App;
Title 1
Card content
Title 2
Card content
Title 3
Card content
Title 4
Card content
Title 5
Card content
Title 6
Card content

Responsive grid list. The size property the is as same as Layout Grid.

expand codeexpand code
import { Card, List } from 'infrad';
import React from 'react';

const data = [
  {
    title: 'Title 1',
  },
  {
    title: 'Title 2',
  },
  {
    title: 'Title 3',
  },
  {
    title: 'Title 4',
  },
  {
    title: 'Title 5',
  },
  {
    title: 'Title 6',
  },
];

const App: React.FC = () => (
  <List
    grid={{
      gutter: 16,
      xs: 1,
      sm: 2,
      md: 4,
      lg: 4,
      xl: 6,
      xxl: 3,
    }}
    dataSource={data}
    renderItem={item => (
      <List.Item>
        <Card title={item.title}>Card content</Card>
      </List.Item>
    )}
  />
);

export default App;
No Data

The example of infinite load with react-infinite-scroll-component.

expand codeexpand code
import { Avatar, Divider, List, Skeleton } from 'infrad';
import React, { useEffect, useState } from 'react';
import InfiniteScroll from 'react-infinite-scroll-component';

interface DataType {
  gender: string;
  name: {
    title: string;
    first: string;
    last: string;
  };
  email: string;
  picture: {
    large: string;
    medium: string;
    thumbnail: string;
  };
  nat: string;
}

const App: React.FC = () => {
  const [loading, setLoading] = useState(false);
  const [data, setData] = useState<DataType[]>([]);

  const loadMoreData = () => {
    if (loading) {
      return;
    }
    setLoading(true);
    fetch('https://randomuser.me/api/?results=10&inc=name,gender,email,nat,picture&noinfo')
      .then(res => res.json())
      .then(body => {
        setData([...data, ...body.results]);
        setLoading(false);
      })
      .catch(() => {
        setLoading(false);
      });
  };

  useEffect(() => {
    loadMoreData();
  }, []);

  return (
    <div
      id="scrollableDiv"
      style={{
        height: 400,
        overflow: 'auto',
        padding: '0 16px',
        border: '1px solid rgba(140, 140, 140, 0.35)',
      }}
    >
      <InfiniteScroll
        dataLength={data.length}
        next={loadMoreData}
        hasMore={data.length < 50}
        loader={<Skeleton avatar paragraph={{ rows: 1 }} active />}
        endMessage={<Divider plain>It is all, nothing more 🤐</Divider>}
        scrollableTarget="scrollableDiv"
      >
        <List
          dataSource={data}
          renderItem={item => (
            <List.Item key={item.email}>
              <List.Item.Meta
                avatar={<Avatar src={item.picture.large} />}
                title={<a href="https://ant.design">{item.name.last}</a>}
                description={item.email}
              />
              <div>Content</div>
            </List.Item>
          )}
        />
      </InfiniteScroll>
    </div>
  );
};

export default App;

An example of infinite & virtualized list via using rc-virtual-list.

expand codeexpand code
import { Avatar, List, message } from 'infrad';
import VirtualList from 'rc-virtual-list';
import React, { useEffect, useState } from 'react';

interface UserItem {
  email: string;
  gender: string;
  name: {
    first: string;
    last: string;
    title: string;
  };
  nat: string;
  picture: {
    large: string;
    medium: string;
    thumbnail: string;
  };
}

const fakeDataUrl =
  'https://randomuser.me/api/?results=20&inc=name,gender,email,nat,picture&noinfo';
const ContainerHeight = 400;

const App: React.FC = () => {
  const [data, setData] = useState<UserItem[]>([]);

  const appendData = () => {
    fetch(fakeDataUrl)
      .then(res => res.json())
      .then(body => {
        setData(data.concat(body.results));
        message.success(`${body.results.length} more items loaded!`);
      });
  };

  useEffect(() => {
    appendData();
  }, []);

  const onScroll = (e: React.UIEvent<HTMLElement, UIEvent>) => {
    if (e.currentTarget.scrollHeight - e.currentTarget.scrollTop === ContainerHeight) {
      appendData();
    }
  };

  return (
    <List>
      <VirtualList
        data={data}
        height={ContainerHeight}
        itemHeight={47}
        itemKey="email"
        onScroll={onScroll}
      >
        {(item: UserItem) => (
          <List.Item key={item.email}>
            <List.Item.Meta
              avatar={<Avatar src={item.picture.large} />}
              title={<a href="https://ant.design">{item.name.last}</a>}
              description={item.email}
            />
            <div>Content</div>
          </List.Item>
        )}
      </VirtualList>
    </List>
  );
};

export default App;

API#

List#

PropertyDescriptionTypeDefaultVersion
borderedToggles rendering of the border around the listbooleanfalse
dataSourceDataSource array for listany[]-
footerList footer rendererReactNode-
gridThe grid type of list. You can set grid to something like {gutter: 16, column: 4}object-
headerList header rendererReactNode-
itemLayoutThe layout of listhorizontal | verticalhorizontal
loadingShows a loading indicator while the contents of the list are being fetchedboolean | SpinProps (more)false
loadMoreShows a load more contentReactNode-
localeThe i18n text including empty textobject{emptyText: No Data}
paginationPagination config, hide it by setting it to falseboolean | objectfalse
renderItemCustomize list item when using dataSource(item) => ReactNode-
rowKeyItem's unique value, could be an Item's key which holds a unique value of type React.Key or function that receives Item and returns a React.Keykeyof T | (item: T) => React.Key"key"
sizeSize of listdefault | large | smalldefault
splitToggles rendering of the split under the list itembooleantrue

pagination#

Properties for pagination.

PropertyDescriptionTypeDefault
positionThe specify the position of Paginationtop | bottom | bothbottom

More about pagination, please check Pagination.

List grid props#

PropertyDescriptionTypeDefaultVersion
columnThe column of gridnumber-
gutterThe spacing between gridnumber0
xs<576px column of gridnumber-
sm≥576px column of gridnumber-
md≥768px column of gridnumber-
lg≥992px column of gridnumber-
xl≥1200px column of gridnumber-
xxl≥1600px column of gridnumber-

List.Item#

PropertyDescriptionTypeDefaultVersion
actionsThe actions content of list item. If itemLayout is vertical, shows the content on bottom, otherwise shows content on the far rightArray<ReactNode>-
extraThe extra content of list item. If itemLayout is vertical, shows the content on right, otherwise shows content on the far rightReactNode-

List.Item.Meta#

PropertyDescriptionTypeDefaultVersion
avatarThe avatar of list itemReactNode-
descriptionThe description of list itemReactNode-
titleThe title of list itemReactNode-