Skip to content

Commit 37f55f0

Browse files
authored
feat: Add Progress component. (#182)
* feat:添加进度条 * doc:添加文档 * fix:添加动画
1 parent 3edeb93 commit 37f55f0

File tree

10 files changed

+415
-205
lines changed

10 files changed

+415
-205
lines changed

example/examples/ios/Podfile.lock

Lines changed: 205 additions & 205 deletions
Large diffs are not rendered by default.

example/examples/src/routes.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,4 +354,12 @@ export const stackPageData: Routes[] = [
354354
description: '轮播图',
355355
},
356356
},
357+
{
358+
name: 'Progress',
359+
component: require('./routes/Progress').default,
360+
params: {
361+
title: 'Progress 进度条',
362+
description: 'Progress 表明某个任务的当前进度',
363+
},
364+
},
357365
];
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import React, {useState} from 'react';
2+
import {View, Text} from 'react-native';
3+
import {Progress, Button, Spacing} from '@uiw/react-native';
4+
import Layout, {Container} from '../../Layout';
5+
6+
const {Header, Body, Card} = Layout;
7+
8+
const ProgressDemo = (props: any) => {
9+
const {route} = props;
10+
const description = route.params.description;
11+
const title = route.params.title;
12+
13+
const [val, setValue] = useState<number>(0);
14+
15+
const onPress = () => {
16+
let count = val + 10;
17+
if (count > 100) {
18+
count = 0;
19+
}
20+
setValue(count)
21+
}
22+
23+
return (
24+
<Container>
25+
<Progress progress={30}/>
26+
<Header title={title} description={description} />
27+
<Body>
28+
<Card title="基础实例" style={{margin:10}}>
29+
<Progress progressColor="red" progress={40}/>
30+
<Spacing />
31+
<Button onPress={onPress}>(+-)10</Button>
32+
<Spacing />
33+
<View style={{flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center'}}>
34+
<Progress progress={val} progressColor='purple'/>
35+
<Text style={{fontSize: 12, width: 40, textAlign: 'right'}}>{val}%</Text>
36+
</View>
37+
<Spacing />
38+
<Progress progressColor="orange" progress={60}/>
39+
<Spacing />
40+
<Progress progressColor="yellow" progress={80}/>
41+
</Card>
42+
</Body>
43+
</Container>
44+
);
45+
};
46+
47+
export default ProgressDemo;
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
Progress 进度条
2+
---
3+
4+
表明某个任务的当前进度。
5+
6+
### 基础示例
7+
8+
<!--DemoStart-->
9+
```jsx
10+
import { SafeAreaView } from 'react-native';
11+
import { Progress } from '@uiw/react-native';
12+
13+
function Demo() {
14+
return (
15+
<SafeAreaView style={{ flex: 1 }}>
16+
<Progress progress={30} position="fixed"/>
17+
</SafeAreaView>
18+
)
19+
}
20+
```
21+
<!--End-->
22+
23+
24+
## Props
25+
26+
| 参数 | 说明 | 类型 | 默认值 |
27+
|------|------|-----|------|
28+
| `progress` | 进度百分比(可选) | Number | 0 |
29+
| `progressColor` | 颜色(可选) | String | none |
30+
| `position` | 位置,fixed 将浮出固定在最顶层(可选) | String | none |
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import React, {useRef, useState, useEffect} from 'react';
2+
import {
3+
Animated,
4+
View,
5+
StyleSheet,
6+
ViewProps,
7+
LayoutChangeEvent
8+
} from 'react-native'
9+
10+
type PositionType = 'fixed' | 'relative'
11+
12+
// 组件的属性定义
13+
export interface ProgressProps extends ViewProps {
14+
/** 当前进度百分比, 0 - 100, 默认0 */
15+
progress?: number;
16+
/** 颜色 */
17+
progressColor? : string
18+
/** 位置 */
19+
position?: PositionType;
20+
/** 动画持续的时间 */
21+
animation?: { duration?: number; } | boolean;
22+
}
23+
24+
export default (props: ProgressProps) => {
25+
const {
26+
style,
27+
progress = 0,
28+
progressColor = '#108ee9',
29+
position,
30+
animation = { duration: 500 },
31+
} = props;
32+
33+
const progWidth = useRef<any>(new Animated.Value(0)).current;
34+
const [wrapWidth, setWrapWidth] = useState<number>(0);
35+
36+
useEffect(() => {
37+
startAnimation();
38+
}, [wrapWidth, progress])
39+
40+
const startAnimation = () => {
41+
Animated.timing(progWidth, {
42+
toValue: getWidth(),
43+
duration: typeof animation !== 'boolean' ? animation.duration : 1000,
44+
useNativeDriver: false,
45+
}).start();
46+
};
47+
48+
const onLayout = (e: LayoutChangeEvent) => {
49+
setWrapWidth(e.nativeEvent.layout.width);
50+
}
51+
52+
const getWidth = (percent: number = progress) => {
53+
return wrapWidth * (normalPercent(percent) / 100)
54+
}
55+
56+
const normalPercent = (percent?: number) => {
57+
let widthPercent: any = 0
58+
if (percent !== undefined && percent > 0) {
59+
widthPercent = percent > 100 ? 100 : percent
60+
}
61+
return widthPercent
62+
}
63+
64+
return (
65+
<View style={[styles.container, style]}>
66+
<View onLayout={onLayout} style={[
67+
styles.pre,
68+
position === 'fixed' ? { position: 'absolute', top: 0 } : {},
69+
{ borderColor: progressColor }]}>
70+
<Animated.View
71+
style={[styles.preOisn, {
72+
width: progWidth,
73+
backgroundColor: progressColor
74+
}]}></Animated.View>
75+
</View>
76+
</View>
77+
)
78+
}
79+
80+
const styles = StyleSheet.create({
81+
container: {
82+
position: 'relative',
83+
flex: 1,
84+
},
85+
pre: {
86+
borderWidth: 1,
87+
height: 4,
88+
width: '100%',
89+
borderRadius: 20,
90+
marginBottom: 0,
91+
marginTop: 0,
92+
overflow: 'hidden',
93+
},
94+
preOisn: {
95+
position: 'absolute',
96+
height: 4,
97+
left: 0,
98+
top: 0,
99+
},
100+
});

packages/core/src/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ export * from './Stepper';
8181

8282
export { default as SpeedDial } from './SpeedDial'
8383
export * from './SpeedDial'
84+
export { default as Progress } from './Progress'
85+
export * from './Progress'
8486
export { default as Swiper } from './Swiper';
8587
export * from './Swiper';
8688
/**
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import Markdown, { importAll } from '../../../component/Markdown';
2+
3+
export default class Page extends Markdown {
4+
path="/packages/core/src/Progress/README.md"
5+
getMarkdown = async () => {
6+
const md = await import('@uiw/react-native/lib/Progress/README.md');
7+
// 支持 markdown 中,相对于当前 index.tsx 相对路径引入图片资源
8+
importAll((require as any).context('./', true, /\.(png|gif|jpg|svg)$/), this.imageFiles);
9+
return md.default || md;
10+
}
11+
}

website/src/routes/menus.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export const componentMenus: MenuData[] = [
4949
{ path: "/components/stepper", name: "Stepper 步进器" },
5050

5151
{ path: "/components/speeddial", name: "SpeedDial 悬浮标记" },
52+
{ path: "/components/progress", name: "Progress 进度条" },
5253
{ divider: true, name: "其它" },
5354
{ href: "https://github.com/uiwjs/react-native-alipay", name: "Alipay 支付宝", target: '__blank' },
5455
{ href: "https://github.com/uiwjs/react-native-amap-geolocation", name: "AMapGeolocation 高德地图定位", target: '__blank' },

website/src/routes/router.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,9 @@ export const getRouterData = {
183183
'/components/speeddial': {
184184
component: dynamicWrapper([], () => import('../pages/components/speeddial')),
185185
},
186+
'/components/progress': {
187+
component: dynamicWrapper([], () => import('../pages/components/progress')),
188+
},
186189
'/components/card': {
187190
component: dynamicWrapper([], () => import('../pages/components/card')),
188191
},

yarn.lock

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15797,6 +15797,14 @@ react-native-screens@3.5.0:
1579715797
dependencies:
1579815798
warn-once "^0.1.0"
1579915799

15800+
react-native-svg@12.1.0:
15801+
version "12.1.0"
15802+
resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-12.1.0.tgz#acfe48c35cd5fca3d5fd767abae0560c36cfc03d"
15803+
integrity sha512-1g9qBRci7man8QsHoXn6tP3DhCDiypGgc6+AOWq+Sy+PmP6yiyf8VmvKuoqrPam/tf5x+ZaBT2KI0gl7bptZ7w==
15804+
dependencies:
15805+
css-select "^2.1.0"
15806+
css-tree "^1.0.0-alpha.39"
15807+
1580015808
react-native-svg@12.1.1:
1580115809
version "12.1.1"
1580215810
resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-12.1.1.tgz#5f292410b8bcc07bbc52b2da7ceb22caf5bcaaee"

0 commit comments

Comments
 (0)