Skip to content

Commit 884a94c

Browse files
ChenlingasMxhy
authored andcommitted
fix(ImagePicker): 增加使用试例
1 parent 1e05b97 commit 884a94c

File tree

7 files changed

+173
-109
lines changed

7 files changed

+173
-109
lines changed

example/examples/src/routes/ImagePicker/index.tsx

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,12 @@
11
import React from 'react';
2-
import {ImagePicker} from '@uiw/react-native-image-picker';
2+
import ImagePicker, {File} from '@uiw/react-native-image-picker';
33
import Layout, {Container} from '../../Layout';
44
import {ComProps} from '../../routes';
55

66
const {Header, Body, Card, Footer} = Layout;
77

88
export interface ImagePickerProps extends ComProps {}
99

10-
interface fileProps {
11-
fileName: string;
12-
fileType: string;
13-
uri: string;
14-
fileSize?: number;
15-
}
16-
1710
export default function MenuDropdownView(props: ImagePickerProps) {
1811
const {route} = props || {};
1912
const description = route.params.description;
@@ -25,14 +18,61 @@ export default function MenuDropdownView(props: ImagePickerProps) {
2518
<Body>
2619
<Card title="基础实例">
2720
<ImagePicker
28-
upload={(file: fileProps[]) => {
21+
upload={(file: File[]) => {
2922
let imageList: string[] = [];
3023
file.forEach(file => imageList.push(file.uri));
3124
return imageList;
3225
}}
3326
selectionLimit={2}
3427
/>
3528
</Card>
29+
<Card title="文件预览">
30+
<ImagePicker
31+
value={[
32+
'https://iknow-pic.cdn.bcebos.com/810a19d8bc3eb135828572d2ab1ea8d3fd1f441d',
33+
'https://iknow-pic.cdn.bcebos.com/810a19d8bc3eb135828572d2ab1ea8d3fd1f441d',
34+
]}
35+
readOnly={true}
36+
/>
37+
</Card>
38+
<Card title="自定义图片大小">
39+
<ImagePicker
40+
value={[
41+
'https://iknow-pic.cdn.bcebos.com/810a19d8bc3eb135828572d2ab1ea8d3fd1f441d',
42+
'https://iknow-pic.cdn.bcebos.com/810a19d8bc3eb135828572d2ab1ea8d3fd1f441d',
43+
]}
44+
readOnly={true}
45+
height={50}
46+
width={50}
47+
/>
48+
</Card>
49+
<Card title="限制上传数量">
50+
<ImagePicker
51+
value={['https://iknow-pic.cdn.bcebos.com/810a19d8bc3eb135828572d2ab1ea8d3fd1f441d']}
52+
maxCount={2}
53+
upload={(file: File[]) => {
54+
let imageList: string[] = [];
55+
file.forEach(file => imageList.push(file.uri));
56+
return imageList;
57+
}}
58+
/>
59+
</Card>
60+
<Card title="禁用图片上传">
61+
<ImagePicker disabled={true} />
62+
</Card>
63+
<Card title="上传前置处理">
64+
<ImagePicker
65+
upload={(file: File[]) => {
66+
let imageList: string[] = [];
67+
file.forEach(file => imageList.push(file.uri));
68+
return imageList;
69+
}}
70+
beforeUpload={(file: File[]) => {
71+
console.log('file', file);
72+
return true;
73+
}}
74+
/>
75+
</Card>
3676
</Body>
3777
<Footer />
3878
</Layout>

packages/core/src/theme/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const palette = {
2727
primary200: '#005DFF',
2828
primary300: 'rgba(0, 93, 255, 0.7)',
2929
primary400: 'rgba(0, 93, 255, 0.4)',
30-
primary500: 'transparent',
30+
primary500: '#ebedf0',
3131
primary600: 'transparent',
3232
primary700: 'transparent',
3333
primary800: 'transparent',
@@ -211,7 +211,7 @@ const darkPalette = {
211211
primary200: '#005DFF',
212212
primary300: 'rgba(0, 93, 255, 0.7)',
213213
primary400: 'rgba(0, 93, 255, 0.4)',
214-
primary500: 'transparent', // 苹果暗模式背景色
214+
primary500: '#1E1E28', // 苹果暗模式背景色
215215
primary600: 'transparent',
216216
primary700: 'transparent',
217217
primary800: 'transparent',

packages/react-native-image-picker/src/ImagePicker/README.md

Whitespace-only changes.

packages/react-native-image-picker/src/ImagePicker/index.tsx renamed to packages/react-native-image-picker/src/ImagePicker/image-picker.tsx

Lines changed: 40 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,10 @@
1-
import React, { PropsWithChildren, useMemo, ComponentType } from 'react';
2-
import {
3-
View,
4-
StyleSheet,
5-
Rationale,
6-
TouchableOpacity,
7-
ModalProps,
8-
ImageURISource,
9-
ImageRequireSource,
10-
} from 'react-native';
11-
import { CameraOptions, ImagePickerResponse } from 'react-native-image-picker';
1+
import React, { useMemo } from 'react';
2+
import { View, StyleSheet, TouchableOpacity } from 'react-native';
123
import { Theme, Flex, ActionSheet, ActionSheetItem, TransitionImage, Icon } from '@uiw/react-native';
134
import ImageView from 'react-native-image-viewing';
145
import { useTheme } from '@shopify/restyle';
156
import useImagePicker from './useImagePicker';
16-
17-
export type ImageSource = ImageURISource | ImageRequireSource;
18-
export interface File {
19-
fileName: string;
20-
fileType: string;
21-
uri: string;
22-
fileSize?: number;
23-
}
24-
25-
export type ImagePickerProps = PropsWithChildren<{
26-
/** 宽度 */
27-
width?: number;
28-
/** 高度 */
29-
height?: number;
30-
/** 当前选择的图片uri */
31-
value?: string[];
32-
/** 其他图片自定义配置,详细参考react-native-image-picker的option配置 */
33-
options?: CameraOptions;
34-
/** 上传图片后是否在背景图展示,如果为 true 上传后会自动展示上传图片(此时只能上传一张) */
35-
showUploadImg?: boolean;
36-
/** 上传文件之前的钩子,参数为上传的文件,若返回 false 则停止上传,同时可以在里面执行一些上传提示操作 */
37-
beforeUpload?: (file: File[]) => boolean | ((file: File) => Promise<boolean>);
38-
/** 上传 */
39-
upload?: (file: File[]) => string[];
40-
/** 上传完成 */
41-
uploadFinish?: (result?: string[] | undefined) => void;
42-
/** 取消上传事件回调 */
43-
onCancel?: (response: ImagePickerResponse) => void;
44-
/** 上传失败事件回调 */
45-
onFail?: (response: ImagePickerResponse) => void;
46-
/** 授权失败的回调 */
47-
onGrantFail?: () => void;
48-
/** 预览时长按图片保存回调 */
49-
onSave?: ((image: any) => void) | undefined;
50-
/** 打开相册授权的文本 */
51-
libraryRationale?: Rationale;
52-
/** 打开摄像头授权的文本 */
53-
cameraRationale?: Rationale;
54-
/** 打开相册文本 */
55-
launchLibraryText?: string;
56-
/** 打开摄像头文本 */
57-
launchCameraText?: string;
58-
/** 从相册选择多少张图片 */
59-
selectionLimit?: number;
60-
// ImageViewProps
61-
onLongPress?: (image: ImageSource) => void;
62-
onImageIndexChange?: (imageIndex: number) => void;
63-
presentationStyle?: ModalProps['presentationStyle'];
64-
animationType?: ModalProps['animationType'];
65-
backgroundColor?: string;
66-
swipeToCloseEnabled?: boolean;
67-
doubleTapToZoomEnabled?: boolean;
68-
delayLongPress?: number;
69-
HeaderComponent?: ComponentType<{
70-
imageIndex: number;
71-
}>;
72-
FooterComponent?: ComponentType<{
73-
imageIndex: number;
74-
}>;
75-
}>;
7+
import { ImagePickerProps } from './types';
768

779
const ImagePicker = ({
7810
width = 100,
@@ -81,6 +13,9 @@ const ImagePicker = ({
8113
value = [],
8214
options,
8315
showUploadImg = true,
16+
disabled = false,
17+
readOnly = false,
18+
maxCount = undefined,
8419
beforeUpload,
8520
upload,
8621
uploadFinish,
@@ -109,8 +44,6 @@ const ImagePicker = ({
10944
const styles = createStyles({
11045
width: width,
11146
height: height,
112-
borderColor: theme.colors.border,
113-
backgroundColor: theme.colors.mask,
11447
});
11548

11649
const {
@@ -153,11 +86,13 @@ const ImagePicker = ({
15386
disabled={loading}
15487
onPress={() => previewImage(index)}
15588
/>
156-
<View style={styles.deleteBox}>
157-
<TouchableOpacity disabled={loading} onPress={() => deleteImage(index)}>
158-
<Icon name="close" color="#fff" size={10} />
159-
</TouchableOpacity>
160-
</View>
89+
{!readOnly && (
90+
<View style={styles.deleteBox}>
91+
<TouchableOpacity disabled={loading} onPress={() => deleteImage(index)}>
92+
<Icon name="close" color="#fff" size={10} />
93+
</TouchableOpacity>
94+
</View>
95+
)}
16196
</View>
16297
</View>
16398
</Flex.Item>
@@ -166,6 +101,31 @@ const ImagePicker = ({
166101
return null;
167102
}, [showUploadImg, JSON.stringify(currentImgSource)]);
168103

104+
const uploader = useMemo(() => {
105+
if (readOnly || currentImgSource.length === maxCount) {
106+
return null;
107+
}
108+
return (
109+
<Flex.Item>
110+
<View
111+
style={[
112+
styles.box,
113+
{ backgroundColor: disabled ? theme.colors.disabled : theme.colors.primary500 || '#eff2f5' },
114+
]}
115+
>
116+
<TouchableOpacity
117+
activeOpacity={0.5}
118+
onPress={handlePress}
119+
disabled={disabled || loading}
120+
style={{ justifyContent: 'center', alignItems: 'center', width, height }}
121+
>
122+
<Icon name="camera-o" color="#dcdee0" size={24} />
123+
</TouchableOpacity>
124+
</View>
125+
</Flex.Item>
126+
);
127+
}, [readOnly, maxCount, JSON.stringify(currentImgSource), disabled]);
128+
169129
const previewImages = useMemo(() => {
170130
return currentImgSource.map((item) => ({ uri: item }));
171131
}, [JSON.stringify(currentImgSource), current]);
@@ -174,18 +134,7 @@ const ImagePicker = ({
174134
<View>
175135
<Flex justify="start" wrap="wrap">
176136
{pictureList}
177-
<Flex.Item>
178-
<View style={styles.box}>
179-
<TouchableOpacity
180-
activeOpacity={0.5}
181-
onPress={handlePress}
182-
disabled={loading}
183-
style={{ justifyContent: 'center', alignItems: 'center', width, height }}
184-
>
185-
<Icon name="camera-o" color={theme.colors.gray300 || '#ccc'} size={24} />
186-
</TouchableOpacity>
187-
</View>
188-
</Flex.Item>
137+
{uploader}
189138
</Flex>
190139
<ActionSheet onCancel={setLaunchVisibleFalse} visible={launchVisible}>
191140
<ActionSheetItem disabled={loading} onPress={launchLibrary}>
@@ -206,18 +155,14 @@ const ImagePicker = ({
206155
);
207156
};
208157

209-
function createStyles({ width = 100, height = 100, borderColor = '#CCCCCC', backgroundColor = '#fff' }) {
158+
function createStyles({ width = 100, height = 100 }) {
210159
return StyleSheet.create({
211160
box: {
212161
width: width,
213162
height: height,
214-
borderWidth: 1,
215-
borderStyle: 'solid',
216-
borderColor: borderColor,
217163
borderRadius: 2,
218164
justifyContent: 'center',
219165
alignItems: 'center',
220-
backgroundColor: backgroundColor,
221166
margin: 4,
222167
},
223168
deleteBox: {
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { PropsWithChildren, ComponentType } from 'react';
2+
import { Rationale, ModalProps, ImageURISource, ImageRequireSource } from 'react-native';
3+
import { CameraOptions, ImagePickerResponse } from 'react-native-image-picker';
4+
export declare type ImageSource = ImageURISource | ImageRequireSource;
5+
export interface File {
6+
fileName: string;
7+
fileType: string;
8+
uri: string;
9+
fileSize?: number;
10+
}
11+
export declare type ImagePickerProps = PropsWithChildren<{
12+
/** 宽度 */
13+
width?: number;
14+
/** 高度 */
15+
height?: number;
16+
/** 当前选择的图片uri */
17+
value?: string[];
18+
/** 其他图片自定义配置,详细参考react-native-image-picker的option配置 */
19+
options?: CameraOptions;
20+
/** 上传图片后是否在背景图展示,如果为 true 上传后会自动展示上传图片(此时只能上传一张) */
21+
showUploadImg?: boolean;
22+
/** 上传文件之前的钩子,参数为上传的文件,若返回 false 则停止上传,同时可以在里面执行一些上传提示操作 */
23+
beforeUpload?: (file: File[]) => boolean | ((file: File) => Promise<boolean>);
24+
/** 上传 */
25+
upload?: (file: File[]) => string[];
26+
/** 上传完成 */
27+
uploadFinish?: (result?: string[] | undefined) => void;
28+
/** 取消上传事件回调 */
29+
onCancel?: (response: ImagePickerResponse) => void;
30+
/** 上传失败事件回调 */
31+
onFail?: (response: ImagePickerResponse) => void;
32+
/** 授权失败的回调 */
33+
onGrantFail?: () => void;
34+
/** 预览时长按图片保存回调 */
35+
onSave?: ((image: any) => void) | undefined;
36+
/** 打开相册授权的文本 */
37+
libraryRationale?: Rationale;
38+
/** 打开摄像头授权的文本 */
39+
cameraRationale?: Rationale;
40+
/** 打开相册文本 */
41+
launchLibraryText?: string;
42+
/** 打开摄像头文本 */
43+
launchCameraText?: string;
44+
/** 从相册选择多少张图片 */
45+
selectionLimit?: number;
46+
/** 是否禁用 */
47+
disabled?: boolean;
48+
/** 是否只读 */
49+
readOnly?: boolean;
50+
/** 上传数量限制 */
51+
maxCount?: number | undefined;
52+
/** 预览图片,长按时调用的函数 */
53+
onLongPress?: (image: ImageSource) => void;
54+
/** 预览图片,更改图像索引时调用的函数 */
55+
onImageIndexChange?: (imageIndex: number) => void;
56+
/** 预览图片,Modal presentation style: default: fullScreen Android:用于overFullScreen隐藏StatusBar */
57+
presentationStyle?: ModalProps['presentationStyle'];
58+
/** 预览图片,动画模态呈现:默认fade */
59+
animationType?: ModalProps['animationType'];
60+
/** 预览图片,背景色(#000000EE) */
61+
backgroundColor?: string;
62+
/** 预览图片,向上或向下滑动关闭模式:默认true */
63+
swipeToCloseEnabled?: boolean;
64+
/** 预览图片,通过双击缩放图像:默认true */
65+
doubleTapToZoomEnabled?: boolean;
66+
/** 预览图片,在调用 onLongPress 之前以毫秒为单位的延迟:默认800 */
67+
delayLongPress?: number;
68+
/** 预览图片,标头组件,imageIndex作为道具获取当前 */
69+
HeaderComponent?: ComponentType<{
70+
imageIndex: number;
71+
}>;
72+
/** 预览图片,页脚组件,imageIndex作为道具获取当前 */
73+
FooterComponent?: ComponentType<{
74+
imageIndex: number;
75+
}>;
76+
}>;

packages/react-native-image-picker/src/ImagePicker/useImagePicker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
launchCamera as launchRNCamera,
88
} from 'react-native-image-picker';
99
import { useBoolean, useSafeState } from 'ahooks';
10-
import type { File, ImagePickerProps } from '.';
10+
import type { File, ImagePickerProps } from './types';
1111

1212
function getSource(value?: string) {
1313
if (value && (value.startsWith('http') || value.startsWith('file:'))) {
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1-
export { default as ImagePicker } from './ImagePicker';
2-
export * from './ImagePicker';
1+
import ImagePicker from './ImagePicker/image-picker';
2+
3+
export type { ImageSource, File, ImagePickerProps } from './ImagePicker/types';
4+
5+
export default ImagePicker;

0 commit comments

Comments
 (0)