Skip to main content
Glama

antd-components-mcp

examples.md31.5 kB
## List 组件示例 ### 简单列表 列表拥有大、中、小三种尺寸。 通过设置 `size` 为 `large` `small` 分别把按钮设为大、小尺寸。若不设置 `size`,则尺寸为中。 可通过设置 `header` 和 `footer`,来自定义列表头部和尾部。 ```tsx 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; ``` ### 基础列表 基础列表。 ```tsx import React from 'react'; import { Avatar, List } from 'antd'; 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://api.dicebear.com/7.x/miniavs/svg?seed=${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; ``` ### 加载更多 可通过 `loadMore` 属性实现加载更多功能。 ```tsx import React, { useEffect, useState } from 'react'; import { Avatar, Button, List, Skeleton } from 'antd'; interface DataType { gender?: string; name?: string; email?: string; avatar?: string; loading: boolean; } const PAGE_SIZE = 3; const App: React.FC = () => { const [initLoading, setInitLoading] = useState(true); const [loading, setLoading] = useState(false); const [data, setData] = useState<DataType[]>([]); const [list, setList] = useState<DataType[]>([]); const [page, setPage] = useState(1); const fetchData = (currentPage: number) => { const fakeDataUrl = `https://660d2bd96ddfa2943b33731c.mockapi.io/api/users?page=${currentPage}&limit=${PAGE_SIZE}`; return fetch(fakeDataUrl).then((res) => res.json()); }; useEffect(() => { fetchData(page).then((res) => { const results = Array.isArray(res) ? res : []; setInitLoading(false); setData(results); setList(results); }); }, []); const onLoadMore = () => { setLoading(true); setList(data.concat(Array.from({ length: PAGE_SIZE }).map(() => ({ loading: true })))); const nextPage = page + 1; setPage(nextPage); fetchData(nextPage).then((res) => { const results = Array.isArray(res) ? res : []; const newData = data.concat(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.avatar} />} title={<a href="https://ant.design">{item.name}</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; ``` ### 竖排列表样式 通过设置 `itemLayout` 属性为 `vertical` 可实现竖排列表样式。 ```tsx import React from 'react'; import { LikeOutlined, MessageOutlined, StarOutlined } from '@ant-design/icons'; import { Avatar, List, Space } from 'antd'; const data = Array.from({ length: 23 }).map((_, i) => ({ href: 'https://ant.design', title: `ant design part ${i}`, avatar: `https://api.dicebear.com/7.x/miniavs/svg?seed=${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 draggable={false} 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; ``` ### 分页设置 可通过 `pagination` 属性使用列表分页,并进行设置。 ```tsx import React, { useState } from 'react'; import { Avatar, List, Radio, Space } from 'antd'; 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://api.dicebear.com/7.x/miniavs/svg?seed=${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; ``` ### 栅格列表 可以通过设置 `List` 的 `grid` 属性来实现栅格列表,`column` 可设置期望显示的列数。 ```tsx 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; ``` ### 测试栅格列表 List `grid` 在各种情况下的样式表现,如 Fragment 和封装了 List.Item. ```tsx 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 ListItem = () => ( <List.Item> <Card title="title">Card content</Card> </List.Item> ); 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> )} /> <List grid={{ gutter: 16, column: 4 }} dataSource={data} renderItem={() => <ListItem />} /> <List grid={{ gutter: 16, column: 4 }} dataSource={data} renderItem={() => ( <> <ListItem /> <div /> </> )} /> </> ); export default App; ``` ### 响应式的栅格列表 响应式的栅格列表。尺寸与 [Layout Grid](/components/grid-cn/#col) 保持一致。 ```tsx 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; ``` ### 滚动加载 结合 [react-infinite-scroll-component](https://github.com/ankeetmaini/react-infinite-scroll-component) 实现滚动自动加载列表。 ```tsx 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?: string; email?: string; avatar?: string; id?: string; } const App: React.FC = () => { const [loading, setLoading] = useState(false); const [data, setData] = useState<DataType[]>([]); const [page, setPage] = useState(1); const loadMoreData = () => { if (loading) { return; } setLoading(true); fetch(`https://660d2bd96ddfa2943b33731c.mockapi.io/api/users/?page=${page}&limit=10`) .then((res) => res.json()) .then((res) => { const results = Array.isArray(res) ? res : []; setData([...data, ...results]); setLoading(false); setPage(page + 1); }) .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.avatar} />} title={<a href="https://ant.design">{item.name}</a>} description={item.email} /> <div>Content</div> </List.Item> )} /> </InfiniteScroll> </div> ); }; export default App; ``` ### 拖拽排序 使用自定义元素,我们可以集成 [dnd-kit](https://github.com/clauderic/dnd-kit) 来实现拖拽排序。 ```tsx import React, { useState } from 'react'; import type { DragEndEvent } from '@dnd-kit/core'; import { DndContext, PointerSensor, useSensor, useSensors } from '@dnd-kit/core'; import { restrictToVerticalAxis } from '@dnd-kit/modifiers'; import { arrayMove, SortableContext, useSortable, verticalListSortingStrategy, } from '@dnd-kit/sortable'; import { CSS } from '@dnd-kit/utilities'; import { List } from 'antd'; import type { GetProps } from 'antd'; const SortableListItem: React.FC<GetProps<typeof List.Item> & { itemKey: number }> = (props) => { const { itemKey, style, children, ...rest } = props; const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: itemKey, }); const listStyle: React.CSSProperties = { ...style, transform: CSS.Translate.toString(transform), transition, cursor: 'move', ...(isDragging ? { position: 'relative', zIndex: 9999 } : {}), }; return ( <List.Item {...rest} ref={setNodeRef} style={listStyle}> <div {...attributes} {...listeners}> {children} </div> </List.Item> ); }; const App: React.FC = () => { const [data, setData] = useState([ { key: 1, content: 'Racing car sprays burning fuel into crowd.' }, { key: 2, content: 'Japanese princess to wed commoner.' }, { key: 3, content: 'Australian walks 100km after outback crash.' }, { key: 4, content: 'Man charged over missing wedding girl.' }, { key: 5, content: 'Los Angeles battles huge wildfires.' }, ]); const sensors = useSensors( useSensor(PointerSensor, { activationConstraint: { // https://docs.dndkit.com/api-documentation/sensors/pointer#activation-constraints distance: 1, }, }), ); const onDragEnd = ({ active, over }: DragEndEvent) => { if (!active || !over) { return; } if (active.id !== over.id) { setData((prev) => { const activeIndex = prev.findIndex((i) => i.key === active.id); const overIndex = prev.findIndex((i) => i.key === over.id); return arrayMove(prev, activeIndex, overIndex); }); } }; return ( <DndContext sensors={sensors} modifiers={[restrictToVerticalAxis]} onDragEnd={onDragEnd} id="list-drag-sorting" > <SortableContext items={data.map((item) => item.key)} strategy={verticalListSortingStrategy}> <List dataSource={data} renderItem={(item) => ( <SortableListItem key={item.key} itemKey={item.key}> {item.key} {item.content} </SortableListItem> )} /> </SortableContext> </DndContext> ); }; export default App; ``` ### 拖拽排序(拖拽手柄) 使用 [dnd-kit](https://github.com/clauderic/dnd-kit) 来实现一个拖拽操作列。 ```tsx import React, { createContext, useContext, useMemo, useState } from 'react'; import { HolderOutlined } from '@ant-design/icons'; import type { DragEndEvent, DraggableAttributes } from '@dnd-kit/core'; import { DndContext } from '@dnd-kit/core'; import type { SyntheticListenerMap } from '@dnd-kit/core/dist/hooks/utilities'; import { restrictToVerticalAxis } from '@dnd-kit/modifiers'; import { arrayMove, SortableContext, useSortable, verticalListSortingStrategy, } from '@dnd-kit/sortable'; import { CSS } from '@dnd-kit/utilities'; import { Button, List } from 'antd'; import type { GetProps } from 'antd'; interface SortableListItemContextProps { setActivatorNodeRef?: (element: HTMLElement | null) => void; listeners?: SyntheticListenerMap; attributes?: DraggableAttributes; } const SortableListItemContext = createContext<SortableListItemContextProps>({}); const DragHandle: React.FC = () => { const { setActivatorNodeRef, listeners, attributes } = useContext(SortableListItemContext); return ( <Button type="text" size="small" icon={<HolderOutlined />} style={{ cursor: 'move' }} ref={setActivatorNodeRef} {...attributes} {...listeners} /> ); }; const SortableListItem: React.FC<GetProps<typeof List.Item> & { itemKey: number }> = (props) => { const { itemKey, style, ...rest } = props; const { attributes, listeners, setNodeRef, setActivatorNodeRef, transform, transition, isDragging, } = useSortable({ id: itemKey }); const listStyle: React.CSSProperties = { ...style, transform: CSS.Translate.toString(transform), transition, ...(isDragging ? { position: 'relative', zIndex: 9999 } : {}), }; const memoizedValue = useMemo<SortableListItemContextProps>( () => ({ setActivatorNodeRef, listeners, attributes }), [setActivatorNodeRef, listeners, attributes], ); return ( <SortableListItemContext.Provider value={memoizedValue}> <List.Item {...rest} ref={setNodeRef} style={listStyle} /> </SortableListItemContext.Provider> ); }; const App: React.FC = () => { const [data, setData] = useState([ { key: 1, content: 'Racing car sprays burning fuel into crowd.' }, { key: 2, content: 'Japanese princess to wed commoner.' }, { key: 3, content: 'Australian walks 100km after outback crash.' }, { key: 4, content: 'Man charged over missing wedding girl.' }, { key: 5, content: 'Los Angeles battles huge wildfires.' }, ]); const onDragEnd = ({ active, over }: DragEndEvent) => { if (!active || !over) { return; } if (active.id !== over.id) { setData((prevState) => { const activeIndex = prevState.findIndex((i) => i.key === active.id); const overIndex = prevState.findIndex((i) => i.key === over.id); return arrayMove(prevState, activeIndex, overIndex); }); } }; return ( <DndContext modifiers={[restrictToVerticalAxis]} onDragEnd={onDragEnd} id="list-drag-sorting-handler" > <SortableContext items={data.map((item) => item.key)} strategy={verticalListSortingStrategy}> <List dataSource={data} renderItem={(item) => ( <SortableListItem key={item.key} itemKey={item.key}> <DragHandle /> {item.key} {item.content} </SortableListItem> )} /> </SortableContext> </DndContext> ); }; export default App; ``` ### 栅格拖拽排序 使用自定义元素,我们可以集成 [dnd-kit](https://github.com/clauderic/dnd-kit) 来实现网格布局的拖拽排序。 ```tsx import React, { useState } from 'react'; import type { DragEndEvent } from '@dnd-kit/core'; import { DndContext, PointerSensor, useSensor, useSensors } from '@dnd-kit/core'; import { arrayMove, SortableContext, useSortable } from '@dnd-kit/sortable'; import { CSS } from '@dnd-kit/utilities'; import { Card, List } from 'antd'; import type { GetProps } from 'antd'; const SortableListItem: React.FC<GetProps<typeof List.Item> & { itemKey: number }> = (props) => { const { itemKey, style, ...rest } = props; const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: itemKey, }); const listStyle: React.CSSProperties = { ...style, transform: CSS.Translate.toString(transform), transition, cursor: 'move', ...(isDragging ? { position: 'relative', zIndex: 9999 } : {}), }; return <List.Item {...rest} ref={setNodeRef} style={listStyle} {...attributes} {...listeners} />; }; const App: React.FC = () => { const [data, setData] = useState([ { key: 1, title: 'Title 1' }, { key: 2, title: 'Title 2' }, { key: 3, title: 'Title 3' }, { key: 4, title: 'Title 4' }, { key: 5, title: 'Title 5' }, { key: 6, title: 'Title 6' }, ]); const sensors = useSensors( useSensor(PointerSensor, { activationConstraint: { // https://docs.dndkit.com/api-documentation/sensors/pointer#activation-constraints distance: 1, }, }), ); const onDragEnd = ({ active, over }: DragEndEvent) => { if (!active || !over) { return; } if (active.id !== over.id) { setData((prev) => { const activeIndex = prev.findIndex((i) => i.key === active.id); const overIndex = prev.findIndex((i) => i.key === over.id); return arrayMove(prev, activeIndex, overIndex); }); } }; return ( <DndContext sensors={sensors} onDragEnd={onDragEnd} id="list-grid-drag-sorting"> <SortableContext items={data.map((item) => item.key)}> <List grid={{ gutter: 16, column: 4 }} dataSource={data} renderItem={(item) => ( <SortableListItem key={item.key} itemKey={item.key}> <Card title={item.title}>Card content</Card> </SortableListItem> )} /> </SortableContext> </DndContext> ); }; export default App; ``` ### 栅格拖拽排序(拖拽手柄) 使用自定义元素和拖拽手柄,我们可以集成 [dnd-kit](https://github.com/clauderic/dnd-kit) 来实现网格布局的拖拽排序。 ```tsx import React, { createContext, useContext, useMemo, useState } from 'react'; import { HolderOutlined } from '@ant-design/icons'; import type { DragEndEvent, DraggableAttributes } from '@dnd-kit/core'; import { DndContext } from '@dnd-kit/core'; import type { SyntheticListenerMap } from '@dnd-kit/core/dist/hooks/utilities'; import { arrayMove, SortableContext, useSortable } from '@dnd-kit/sortable'; import { CSS } from '@dnd-kit/utilities'; import { Button, Card, List } from 'antd'; import type { GetProps } from 'antd'; interface SortableListItemContextProps { setActivatorNodeRef?: (element: HTMLElement | null) => void; listeners?: SyntheticListenerMap; attributes?: DraggableAttributes; } const SortableListItemContext = createContext<SortableListItemContextProps>({}); const DragHandle: React.FC = () => { const { setActivatorNodeRef, listeners, attributes } = useContext(SortableListItemContext); return ( <Button type="text" size="small" icon={<HolderOutlined />} style={{ cursor: 'move' }} ref={setActivatorNodeRef} {...attributes} {...listeners} /> ); }; const SortableListItem: React.FC<GetProps<typeof List.Item> & { itemKey: number }> = (props) => { const { itemKey, style, ...rest } = props; const { attributes, listeners, setNodeRef, setActivatorNodeRef, transform, transition, isDragging, } = useSortable({ id: itemKey }); const listStyle: React.CSSProperties = { ...style, transform: CSS.Translate.toString(transform), transition, ...(isDragging ? { position: 'relative', zIndex: 9999 } : {}), }; const memoizedValue = useMemo<SortableListItemContextProps>( () => ({ setActivatorNodeRef, listeners, attributes }), [setActivatorNodeRef, listeners, attributes], ); return ( <SortableListItemContext.Provider value={memoizedValue}> <List.Item {...rest} ref={setNodeRef} style={listStyle} /> </SortableListItemContext.Provider> ); }; const App: React.FC = () => { const [data, setData] = useState([ { key: 1, title: 'Title 1' }, { key: 2, title: 'Title 2' }, { key: 3, title: 'Title 3' }, { key: 4, title: 'Title 4' }, { key: 5, title: 'Title 5' }, { key: 6, title: 'Title 6' }, ]); const onDragEnd = ({ active, over }: DragEndEvent) => { if (!active || !over) { return; } if (active.id !== over.id) { setData((prevState) => { const activeIndex = prevState.findIndex((i) => i.key === active.id); const overIndex = prevState.findIndex((i) => i.key === over.id); return arrayMove(prevState, activeIndex, overIndex); }); } }; return ( <DndContext onDragEnd={onDragEnd} id="list-grid-drag-sorting-handler"> <SortableContext items={data.map((i) => i.key)}> <List grid={{ gutter: 16, column: 4 }} dataSource={data} renderItem={(item) => ( <SortableListItem key={item.key} itemKey={item.key}> <Card title={ <> <DragHandle /> {item.title} </> } > Card content </Card> </SortableListItem> )} /> </SortableContext> </DndContext> ); }; export default App; ``` ### 滚动加载无限长列表 结合 [rc-virtual-list](https://github.com/react-component/virtual-list) 实现滚动加载无限长列表,能够提高数据量大时候长列表的性能。 ```tsx 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: string; avatar: string; } const CONTAINER_HEIGHT = 400; const PAGE_SIZE = 20; const App: React.FC = () => { const [data, setData] = useState<UserItem[]>([]); const [page, setPage] = useState(1); const appendData = (showMessage = true) => { const fakeDataUrl = `https://660d2bd96ddfa2943b33731c.mockapi.io/api/users/?page=${page}&limit=${PAGE_SIZE}`; fetch(fakeDataUrl) .then((res) => res.json()) .then((body) => { const results = Array.isArray(body) ? body : []; setData(data.concat(results)); setPage(page + 1); showMessage && message.success(`${results.length} more items loaded!`); }); }; useEffect(() => { appendData(false); }, []); const onScroll = (e: React.UIEvent<HTMLElement, UIEvent>) => { // Refer to: https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight#problems_and_solutions if ( Math.abs(e.currentTarget.scrollHeight - e.currentTarget.scrollTop - CONTAINER_HEIGHT) <= 1 ) { appendData(); } }; return ( <List> <VirtualList data={data} height={CONTAINER_HEIGHT} itemHeight={47} itemKey="email" onScroll={onScroll} > {(item: UserItem) => ( <List.Item key={item.email}> <List.Item.Meta avatar={<Avatar src={item.avatar} />} title={<a href="https://ant.design">{item.name}</a>} description={item.email} /> <div>Content</div> </List.Item> )} </VirtualList> </List> ); }; export default App; ``` ### 自定义组件 token 自定义组件 Token。 ```tsx import React from 'react'; import { Avatar, ConfigProvider, 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 data1 = [ { title: 'Ant Design Title 1', }, { title: 'Ant Design Title 2', }, { title: 'Ant Design Title 3', }, { title: 'Ant Design Title 4', }, ]; const App: React.FC = () => ( <ConfigProvider theme={{ components: { List: { headerBg: 'pink', footerBg: 'pink', emptyTextPadding: 32, itemPadding: '26px', itemPaddingSM: '16px', itemPaddingLG: '36px', metaMarginBottom: 20, avatarMarginRight: 20, titleMarginBottom: 10, descriptionFontSize: 20, }, }, }} > <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>} /> <Divider orientation="left">Meta</Divider> <List itemLayout="horizontal" dataSource={data1} renderItem={(item, index) => ( <List.Item> <List.Item.Meta avatar={<Avatar src={`https://api.dicebear.com/7.x/miniavs/svg?seed=${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> )} /> <Divider orientation="left">Vertical</Divider> <List itemLayout="vertical" dataSource={data1} renderItem={(item, index) => ( <List.Item> <List.Item.Meta avatar={<Avatar src={`https://api.dicebear.com/7.x/miniavs/svg?seed=${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> )} /> <Divider orientation="left">Empty Text</Divider> <List /> </ConfigProvider> ); export default App; ```

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/zhixiaoqiang/antd-components-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server