Simple List.
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.
import React from 'react';
import { Divider, List, Typography } from 'antd';
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;
import { Avatar, List } from 'antd';
import React from 'react';
const data = [
{
title: 'Ant Design Title 1',
},
{
title: 'Ant Design Title 2',
},
{
title: 'Ant Design Title 3',
},
{
title: 'Ant Design Title 4',
},
];
const App: React.FC = () => (
<List
itemLayout="horizontal"
dataSource={data}
renderItem={(item, index) => (
<List.Item>
<List.Item.Meta
avatar={<Avatar src={`https://joesch.moe/api/v1/random?key=${index}`} />}
title={<a href="https://ant.design">{item.title}</a>}
description="Ant Design, a design language for background applications, is refined by Ant UED Team"
/>
</List.Item>
)}
/>
);
export default App;
import React, { useEffect, useState } from 'react';
import { Avatar, Button, List, Skeleton } from 'antd';
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="Ant 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;
}
import { LikeOutlined, MessageOutlined, StarOutlined } from '@ant-design/icons';
import { Avatar, List, Space } from 'antd';
import React from 'react';
const data = Array.from({ length: 23 }).map((_, i) => ({
href: 'https://ant.design',
title: `ant design part ${i}`,
avatar: `https://joesch.moe/api/v1/random?key=${i}`,
description:
'Ant 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;
import { Avatar, List, Radio, Space } from 'antd';
import React, { useState } from 'react';
type PaginationPosition = 'top' | 'bottom' | 'both';
type PaginationAlign = 'start' | 'center' | 'end';
const data = [
{
title: 'Ant Design Title 1',
},
{
title: 'Ant Design Title 2',
},
{
title: 'Ant Design Title 3',
},
{
title: 'Ant Design Title 4',
},
];
const positionOptions = ['top', 'bottom', 'both'];
const alignOptions = ['start', 'center', 'end'];
const App: React.FC = () => {
const [position, setPosition] = useState<PaginationPosition>('bottom');
const [align, setAlign] = useState<PaginationAlign>('center');
return (
<>
<Space direction="vertical" style={{ marginBottom: '20px' }} size="middle">
<Space>
<span>Pagination Position:</span>
<Radio.Group
optionType="button"
value={position}
onChange={(e) => {
setPosition(e.target.value);
}}
>
{positionOptions.map((item) => (
<Radio.Button key={item} value={item}>
{item}
</Radio.Button>
))}
</Radio.Group>
</Space>
<Space>
<span>Pagination Align:</span>
<Radio.Group
optionType="button"
value={align}
onChange={(e) => {
setAlign(e.target.value);
}}
>
{alignOptions.map((item) => (
<Radio.Button key={item} value={item}>
{item}
</Radio.Button>
))}
</Radio.Group>
</Space>
</Space>
<List
pagination={{ position, align }}
dataSource={data}
renderItem={(item, index) => (
<List.Item>
<List.Item.Meta
avatar={<Avatar src={`https://joesch.moe/api/v1/random?key=${index}`} />}
title={<a href="https://ant.design">{item.title}</a>}
description="Ant Design, a design language for background applications, is refined by Ant UED Team"
/>
</List.Item>
)}
/>
</>
);
};
export default App;
import React from 'react';
import { Card, List } from 'antd';
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;
import React from 'react';
import { Card, List } from 'antd';
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;
import React, { useEffect, useState } from 'react';
import { Avatar, Divider, List, Skeleton } from 'antd';
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;
import React, { useEffect, useState } from 'react';
import { Avatar, List, message } from 'antd';
import VirtualList from 'rc-virtual-list';
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;
Property | Description | Type | Default | Version |
---|---|---|---|---|
bordered | Toggles rendering of the border around the list | boolean | false | |
dataSource | DataSource array for list | any[] | - | |
footer | List footer renderer | ReactNode | - | |
grid | The grid type of list. You can set grid to something like {gutter: 16, column: 4} | object | - | |
header | List header renderer | ReactNode | - | |
itemLayout | The layout of list | horizontal | vertical | horizontal | |
loading | Shows a loading indicator while the contents of the list are being fetched | boolean | SpinProps (more) | false | |
loadMore | Shows a load more content | ReactNode | - | |
locale | The i18n text including empty text | object | {emptyText: No Data } | |
pagination | Pagination config, hide it by setting it to false | boolean | object | false | |
renderItem | Customize list item when using dataSource | (item) => ReactNode | - | |
rowKey | Item'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.Key | keyof T | (item: T) => React.Key | "key" | |
size | Size of list | default | large | small | default | |
split | Toggles rendering of the split under the list item | boolean | true |
Properties for pagination.
Property | Description | Type | Default |
---|---|---|---|
position | The specify the position of Pagination | top | bottom | both | bottom |
align | The specify the alignment of Pagination | start | center | end | end |
More about pagination, please check Pagination
.
Property | Description | Type | Default | Version |
---|---|---|---|---|
column | The column of grid | number | - | |
gutter | The spacing between grid | number | 0 | |
xs | <576px column of grid | number | - | |
sm | ≥576px column of grid | number | - | |
md | ≥768px column of grid | number | - | |
lg | ≥992px column of grid | number | - | |
xl | ≥1200px column of grid | number | - | |
xxl | ≥1600px column of grid | number | - |
Property | Description | Type | Default | Version |
---|---|---|---|---|
actions | The actions content of list item. If itemLayout is vertical , shows the content on bottom, otherwise shows content on the far right | Array<ReactNode> | - | |
extra | The extra content of list item. If itemLayout is vertical , shows the content on right, otherwise shows content on the far right | ReactNode | - |
Property | Description | Type | Default | Version |
---|---|---|---|---|
avatar | The avatar of list item | ReactNode | - | |
description | The description of list item | ReactNode | - | |
title | The title of list item | ReactNode | - |