Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions site/mobile/components/style/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@

#app {
min-height: 100vh;
height: 100vh;
display: flex;
flex-direction: column;
}

.tdesign-mobile-demo {
flex: 1;
overflow-y: scroll;
}
5 changes: 5 additions & 0 deletions site/mobile/mobile.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ export default {
name: 'grid',
component: () => import('tdesign-mobile-react/grid/_example/index.tsx'),
},
{
title: 'List 列表',
name: 'list',
component: () => import('tdesign-mobile-react/list/_example/index.tsx'),
},
{
title: 'Image 图片',
name: 'image',
Expand Down
12 changes: 6 additions & 6 deletions site/web/site.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -388,12 +388,12 @@ export const docs = [
// path: '/mobile-react/components/image-viewer',
// component: () => import('tdesign-mobile-react/image-viewer/image-viewer.md'),
// },
// {
// title: 'List 列表',
// name: 'list',
// path: '/mobile-react/components/list',
// component: () => import('tdesign-mobile-react/list/list.md'),
// },
{
title: 'List 列表',
name: 'list',
path: '/mobile-react/components/list',
component: () => import('tdesign-mobile-react/list/list.md'),
},
{
title: 'Progress 进度条',
titleEn: 'Progress',
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export * from './sticky';
export * from './swiper';
export * from './swipe-cell';
export * from './tag';
export * from './list';
export * from './result';
export * from './table';
export * from './empty';
Expand Down
66 changes: 66 additions & 0 deletions src/list/_example/base.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React, { useEffect, useState, useRef } from 'react';
import './style/index.less';
import { Cell, List } from 'tdesign-mobile-react';

interface ListItem {
id: number;
content: string;
icon: string;
title: string;
}

export default function ListDemo() {
const [isLoading, setIsLoading] = useState(false);
const pageSize = 20;
const stateRef = useRef([]);
const pageRef = useRef(1);
const dataSource: ListItem[] = [];
const total = 100;
for (let i = 0; i < total; i++) {
dataSource.push({
id: i,
content: '列表内容列表内容列表内容',
icon: 'https://tdesign.gtimg.com/list-icon.png',
title: '列表主内容',
});
}

// 模拟请求
const fetchData = async (pageInfo) => {
if (isLoading) return;
setIsLoading(true);
try {
setTimeout(() => {
const { pageNum, pageSize } = pageInfo;
const newDataSource = dataSource.slice((pageNum - 1) * pageSize, pageNum * pageSize);
const newListData = stateRef.current.concat(newDataSource);
pageRef.current = pageNum;
stateRef.current = newListData;
setIsLoading(false);
}, 0);
} catch (err) {
stateRef.current = [];
}
};

const onScroll = (scrollBottom) => {
if (!scrollBottom && stateRef.current.length < total) {
fetchData({ pageNum: pageRef.current + 1, pageSize });
}
};

useEffect(() => {
fetchData({ pageNum: pageRef.current, pageSize });
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

return (
<List asyncLoading={isLoading} onScroll={onScroll}>
{stateRef.current.map((item) => (
<Cell key={item.id} align="middle">
<span className="cell">{item.id}</span>
</Cell>
))}
</List>
);
}
64 changes: 64 additions & 0 deletions src/list/_example/err-tip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import React, { useState, useRef, useEffect } from 'react';
import { Cell, List, Loading } from 'tdesign-mobile-react';

export default function ListDemo() {
const listError = useRef<string[]>([]);
const [loading, setLoading] = useState('');
const [showError, setShowError] = useState(false);

const onLoadError = () => {
setLoading('loading');

setTimeout(() => {
const newVal: string[] = [...listError.current];
for (let i = listError.current.length; i < 8; i++) {
newVal.push(`${i}`);
}
listError.current = newVal;

setShowError(true);
setLoading('');
}, 1000);
};

const onLoadMore = () => {
setShowError(false);
if (listError.current.length >= 60 || loading) {
return;
}
setLoading('loading');

setTimeout(() => {
for (let i = 0; i < 15; i++) {
listError.current.push(`${listError.current.length + 1}`);
}
setLoading('');
}, 1000);
};

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

return (
<List
asyncLoading={loading}
onScroll={onLoadMore}
footer={
showError && (
<Loading indicator={false}>
<div className="custom-error">
请求失败,点击重新<span onClick={onLoadMore}>加载</span>
</div>
</Loading>
)
}
>
{listError.current.map((item) => (
<Cell key={item} align="middle">
<span className="cell">{item}</span>
</Cell>
))}
</List>
);
}
52 changes: 52 additions & 0 deletions src/list/_example/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React, { useState } from 'react';
import { Button } from 'tdesign-mobile-react';
import TDemoBlock from '../../../site/mobile/components/DemoBlock';
// import TDemoHeader from '../../../site/mobile/components/DemoHeader';
import './style/index.less';

import BaseList from './base.jsx';
import ErrTipDemo from './err-tip.jsx';
import PullRefreshDemo from './pull-refresh.jsx';

export default function ListDemo() {
const [currentTab, setCurrentTab] = useState('info');

const onChangeTab = (val) => {
setCurrentTab(val);
history.pushState({}, '', '?tab=demo');
};

return (
<div className="tdesign-mobile-demo">
<div className="list-demo">
{currentTab === 'info' && (
<div>
<h1 className="title">List 列表</h1>
<p className="summary">
瀑布流滚动加载,用于展示同一类型信息的长列表。当列表即将滚动到底部时,会触发事件并加载更多列表项。
</p>
<TDemoBlock title="01 类型" summary="基础列表">
<Button size="large" variant="outline" theme="primary" onClick={() => onChangeTab('base')}>
{' '}
基础列表{' '}
</Button>
<Button size="large" variant="outline" theme="primary" onClick={() => onChangeTab('pull-refresh')}>
下拉刷新
</Button>
<Button size="large" variant="outline" theme="primary" onClick={() => onChangeTab('error-tip')}>
错误提示
</Button>
</TDemoBlock>
</div>
)}
{currentTab === 'base' && <BaseList></BaseList>}
{currentTab === 'error-tip' && <ErrTipDemo></ErrTipDemo>}
{currentTab === 'pull-refresh' && (
<div className="pull-refresh-wrap">
<PullRefreshDemo />
</div>
)}
</div>
</div>
);
}
71 changes: 71 additions & 0 deletions src/list/_example/pull-refresh.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import React, { useState, useEffect, useRef } from 'react';
import { Cell, List, PullDownRefresh } from 'tdesign-mobile-react';

export default function ListDemo() {
const [loading, setLoading] = useState('');
const [refreshing, setRefreshing] = useState(false);

const listData = useRef<string[]>([]);

const MAX_DATA_LEN = 60;

const loadData = (isRefresh) => {
const ONCE_LOAD_NUM = 20;
return new Promise(() => {
setTimeout(() => {
const temp: string[] = [];
for (let i = 0; i < ONCE_LOAD_NUM; i++) {
if (isRefresh) {
temp.push(`${i + 1}`);
} else {
temp.push(`${listData.current.length + 1 + i}`);
}
}

if (isRefresh) {
listData.current = temp;
} else {
listData.current = [...listData.current, ...temp];
}
setLoading('');
setRefreshing(false);
}, 1000);
});
};

const onLoadData = (isRefresh?) => {
if ((listData.current.length >= MAX_DATA_LEN && !isRefresh) || loading.value) {
return;
}
setLoading('loading');
loadData(isRefresh);
};

const onScroll = (scrollBottom) => {
if (scrollBottom < 50) {
onLoadData();
}
};

const onRefresh = () => {
setRefreshing(true);
onLoadData(true);
};

useEffect(() => {
onLoadData();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

return (
<PullDownRefresh value={refreshing} onChange={(val) => setRefreshing(val)} onRefresh={onRefresh}>
<List asyncLoading={loading} onScroll={onScroll}>
{listData.current.map((item) => (
<Cell key={item} align="middle">
<span className="cell">{item}</span>
</Cell>
))}
</List>
</PullDownRefresh>
);
}
30 changes: 30 additions & 0 deletions src/list/_example/style/index.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
.list-demo {
.t-list {
.cell {
width: 100%;
text-align: center;
}
.error {
text-align: center;
color: #969799;
font-size: 14px;
margin-top: 8px;
}
}
.custom-error {
font-size: 14px;
color: #969799;
text-align: center;
padding-top: 16px;
cursor: default;

span {
color: #0052d9;
cursor: pointer;
}
}
.t-button {
margin: 0 16px 16px 16px;
width: calc(100% - 32px);
}
}
8 changes: 8 additions & 0 deletions src/list/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import _List from './list';

import './style/index.js';

export * from './type';

export const List = _List;
export default List;
13 changes: 13 additions & 0 deletions src/list/list.en-US.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
:: BASE_DOC ::

## API

### List Props

name | type | default | description | required
-- | -- | -- | -- | --
asyncLoading | TNode / Function | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
footer | TNode / Function | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
header | TNode / Function | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
onLoadMore | Function | | Typescript:`() => void`<br/> | N
onScroll | Function | | Typescript:`(bottomDistance: number, scrollTop: number) => void`<br/> | N
13 changes: 13 additions & 0 deletions src/list/list.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
:: BASE_DOC ::

## API

### List Props

名称 | 类型 | 默认值 | 描述 | 必传
-- | -- | -- | -- | --
asyncLoading | String / TNode | - | 自定义加载中。值为空不显示加载中,值为 'loading' 显示加载中状态,值为 'load-more' 显示加载更多状态。值类型为函数,则表示自定义加载状态呈现内容。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
footer | String / TNode | - | 底部。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
header | String / TNode | - | 头部。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-vue/blob/develop/src/common.ts) | N
onLoadMore | Function | | TS 类型:`() => void`<br/>点击加载更多时触发 | N
onScroll | Function | | TS 类型:`(bottomDistance: number, scrollTop: number) => void`<br/>列表滚动时触发,bottomDistance 表示底部距离;scrollTop 表示顶部滚动距离 | N
Loading