Skip to content

Commit d035cb8

Browse files
committed
feat: 优化弹窗类组件的显示方式
1 parent 539c123 commit d035cb8

File tree

19 files changed

+231
-283
lines changed

19 files changed

+231
-283
lines changed

.changeset/kind-guests-clap.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
'@td-design/react-native-image-picker': patch
3+
'@td-design/react-native-picker': patch
4+
'@td-design/react-native-share': patch
5+
'@td-design/react-native': patch
6+
---
7+
8+
feat: 优化弹窗类组件的显示方式

packages/react-native-image-picker/src/index.tsx

Lines changed: 6 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import React, { forwardRef, useImperativeHandle } from 'react';
2-
import { Image, TouchableWithoutFeedback } from 'react-native';
2+
import { Image } from 'react-native';
33
import { CameraOptions } from 'react-native-image-picker';
44

5-
import { ActionSheet, Box, helpers, Indicator, Modal, Pressable, Theme, useTheme } from '@td-design/react-native';
5+
import { Box, helpers, Indicator, Pressable, Theme, useTheme } from '@td-design/react-native';
66

77
import { ImagePickerProps, ImagePickerRef } from './type';
88
import useImagePicker from './useImagePicker';
99

10-
const { px, ONE_PIXEL, deviceWidth, deviceHeight } = helpers;
10+
const { px, ONE_PIXEL } = helpers;
1111
const { UIActivityIndicator } = Indicator;
1212

1313
const cameraOptions: CameraOptions = {
@@ -28,8 +28,6 @@ const ImagePicker = forwardRef<ImagePickerRef, ImagePickerProps>(
2828
showUploadImg = true,
2929
launchLibraryText = '打开相册',
3030
launchCameraText = '打开摄像头',
31-
previewImgText = '预览图片',
32-
deleteImgText = '删除图片',
3331
children,
3432
onBeforeUpload,
3533
onUpload,
@@ -43,22 +41,7 @@ const ImagePicker = forwardRef<ImagePickerRef, ImagePickerProps>(
4341
) => {
4442
const theme = useTheme<Theme>();
4543

46-
const {
47-
currentImgSource,
48-
loading,
49-
launchLibrary,
50-
launchCamera,
51-
launchVisible,
52-
previewImage,
53-
deleteImage,
54-
handlePress,
55-
handleLongPress,
56-
previewVisible,
57-
visible,
58-
setVisibleFalse,
59-
setLaunchVisibleFalse,
60-
setPreviewVisibleFalse,
61-
} = useImagePicker({
44+
const { currentImgSource, loading, handlePress } = useImagePicker({
6245
value,
6346
showUploadImg,
6447
options,
@@ -68,6 +51,8 @@ const ImagePicker = forwardRef<ImagePickerRef, ImagePickerProps>(
6851
onCancel,
6952
onFail,
7053
onGrantFail,
54+
launchLibraryText,
55+
launchCameraText,
7156
});
7257

7358
useImperativeHandle(ref, () => ({}));
@@ -77,7 +62,6 @@ const ImagePicker = forwardRef<ImagePickerRef, ImagePickerProps>(
7762
<Pressable
7863
activeOpacity={activeOpacity}
7964
onPress={handlePress}
80-
onLongPress={handleLongPress}
8165
disabled={loading}
8266
style={{ justifyContent: 'center', alignItems: 'flex-start', width, height }}
8367
>
@@ -110,37 +94,6 @@ const ImagePicker = forwardRef<ImagePickerRef, ImagePickerProps>(
11094
<UIActivityIndicator size={px(24)} color={theme.colors.primary200} />
11195
</Box>
11296
)}
113-
{/* 打开相册或者打开相机 */}
114-
<ActionSheet
115-
items={[
116-
{ text: launchLibraryText, onPress: launchLibrary },
117-
{ text: launchCameraText, onPress: launchCamera },
118-
]}
119-
onCancel={setLaunchVisibleFalse}
120-
visible={launchVisible}
121-
/>
122-
{/* 预览图片或者删除图片 */}
123-
<ActionSheet
124-
items={[
125-
{ text: previewImgText, onPress: previewImage },
126-
{ text: deleteImgText, onPress: deleteImage, type: 'danger' },
127-
]}
128-
onCancel={setVisibleFalse}
129-
visible={visible}
130-
/>
131-
{/* 弹窗预览图片 */}
132-
<Modal visible={previewVisible} onClose={setPreviewVisibleFalse} position="fullscreen">
133-
<TouchableWithoutFeedback onPress={setPreviewVisibleFalse}>
134-
<Image
135-
source={{ uri: currentImgSource }}
136-
style={{
137-
width: deviceWidth,
138-
height: deviceHeight,
139-
}}
140-
resizeMode="contain"
141-
/>
142-
</TouchableWithoutFeedback>
143-
</Modal>
14497
</Box>
14598
);
14699
}

packages/react-native-image-picker/src/type.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,20 @@ export type ImagePickerProps = PropsWithChildren<{
3737
launchLibraryText?: string;
3838
/** 打开摄像头文本 */
3939
launchCameraText?: string;
40-
/** 预览图片文本 */
41-
previewImgText?: string;
42-
/** 删除图片文本 */
43-
deleteImgText?: string;
4440
/** 按下时的不透明度 */
4541
activeOpacity?: number;
4642
}>;
4743

4844
export type HookProps = Pick<
4945
ImagePickerProps,
50-
'value' | 'onBeforeUpload' | 'onUpload' | 'onAfterUpload' | 'onCancel' | 'onFail' | 'onGrantFail'
46+
| 'value'
47+
| 'onBeforeUpload'
48+
| 'onUpload'
49+
| 'onAfterUpload'
50+
| 'onCancel'
51+
| 'onFail'
52+
| 'onGrantFail'
53+
| 'launchLibraryText'
54+
| 'launchCameraText'
5155
> &
5256
Required<Pick<ImagePickerProps, 'options' | 'showUploadImg'>>;

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

Lines changed: 10 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ import { useEffect } from 'react';
22
import { Keyboard, PermissionsAndroid, Platform } from 'react-native';
33
import { ImagePickerResponse, launchImageLibrary, launchCamera as launchRNCamera } from 'react-native-image-picker';
44

5+
import { ActionSheet } from '@td-design/react-native';
56
import type { File } from '@td-design/react-native';
6-
import { useBoolean, useSafeState } from '@td-design/rn-hooks';
7+
import { useSafeState } from '@td-design/rn-hooks';
78

89
import { HookProps } from './type';
910

@@ -24,14 +25,9 @@ export default function useImagePicker({
2425
onCancel,
2526
onFail,
2627
onGrantFail,
28+
launchLibraryText,
29+
launchCameraText,
2730
}: HookProps) {
28-
/** 打开相册或者摄像头的ActionSheet */
29-
const [launchVisible, { setTrue: setLaunchVisibleTrue, setFalse: setLaunchVisibleFalse }] = useBoolean(false);
30-
/** 打开预览或者删除的ActionSheet */
31-
const [visible, { setTrue: setVisibleTrue, setFalse: setVisibleFalse }] = useBoolean(false);
32-
/** 打开预览图片的弹窗 */
33-
const [previewVisible, { setTrue: setPreviewVisibleTrue, setFalse: setPreviewVisibleFalse }] = useBoolean(false);
34-
3531
const [currentImgSource, setCurrentImgSource] = useSafeState<string | undefined>(getSource(value));
3632
const [loading, setLoading] = useSafeState(false);
3733

@@ -95,43 +91,19 @@ export default function useImagePicker({
9591
}
9692
};
9793

98-
const previewImage = () => {
99-
setVisibleFalse();
100-
setPreviewVisibleTrue();
101-
};
102-
103-
const deleteImage = () => {
104-
onAfterUpload?.(undefined);
105-
setCurrentImgSource(undefined);
106-
setVisibleFalse();
107-
};
108-
10994
const handlePress = () => {
11095
Keyboard.dismiss();
111-
setLaunchVisibleTrue();
112-
};
113-
114-
const handleLongPress = () => {
115-
Keyboard.dismiss();
116-
if (showUploadImg && currentImgSource) {
117-
setVisibleTrue();
118-
}
96+
ActionSheet.show({
97+
items: [
98+
{ text: launchLibraryText!, onPress: launchLibrary },
99+
{ text: launchCameraText!, onPress: launchCamera },
100+
],
101+
});
119102
};
120103

121104
return {
122105
currentImgSource,
123106
loading,
124-
launchLibrary,
125-
launchCamera,
126-
launchVisible,
127-
previewImage,
128-
deleteImage,
129107
handlePress,
130-
handleLongPress,
131-
previewVisible,
132-
visible,
133-
setVisibleFalse,
134-
setLaunchVisibleFalse,
135-
setPreviewVisibleFalse,
136108
};
137109
}

packages/react-native-share/src/index.tsx

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import React, { FC, ReactNode } from 'react';
1+
import React, { FC, ReactNode, useState } from 'react';
22
import { Linking, ScrollView, StyleSheet } from 'react-native';
33

4-
import { Box, helpers, Modal, Pressable, Text, Theme, useTheme } from '@td-design/react-native';
4+
import { Box, helpers, Modal, Portal, Pressable, Text, Theme, useTheme } from '@td-design/react-native';
55

66
import Alipay from './svg/alipay';
77
import Dingding from './svg/dingding';
@@ -29,12 +29,8 @@ export interface ShareAction {
2929
onPress: () => void;
3030
}
3131
interface ShareProps {
32-
/** 是否显示操作面板 */
33-
visible: boolean;
3432
/** 按下时的不透明度 */
3533
activeOpacity?: number;
36-
/** 关闭操作面板 */
37-
onCancel: () => void;
3834
/** 关闭文字 */
3935
cancelText?: string;
4036
/** 刷新文字 */
@@ -56,12 +52,11 @@ interface ShareProps {
5652
onShareQQMail?: () => void;
5753
}
5854

59-
const Share: FC<ShareProps> = ({
60-
visible,
55+
const ShareContent: FC<ShareProps & { onAnimationEnd: (visible: boolean) => void }> = ({
6156
activeOpacity = 0.6,
62-
onCancel,
6357
cancelText = '取消',
6458
refreshText = '刷新',
59+
onAnimationEnd,
6560
onRefresh,
6661
extraShares = [],
6762
extraActions = [],
@@ -75,6 +70,8 @@ const Share: FC<ShareProps> = ({
7570
onShareZhihu,
7671
onShareQQMail,
7772
}) => {
73+
const [visible, setVisible] = useState(true);
74+
7875
const theme = useTheme<Theme>();
7976
const styles = StyleSheet.create({
8077
action: {
@@ -202,19 +199,50 @@ const Share: FC<ShareProps> = ({
202199
};
203200

204201
return (
205-
<Modal visible={visible} onClose={onCancel}>
202+
<Modal.Content
203+
position="bottom"
204+
maskVisible
205+
maskClosable
206+
animationType="slide"
207+
onAnimationEnd={onAnimationEnd}
208+
visible={visible}
209+
onClose={() => setVisible(false)}
210+
>
206211
<ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={styles.content1}>
207212
{_actions.map(renderShareItem)}
208213
</ScrollView>
209214
<ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={styles.content2}>
210215
{secondaryActions.map(renderActionItem)}
211216
</ScrollView>
212-
<Pressable activeOpacity={activeOpacity} onPress={onCancel} style={styles.action}>
217+
<Pressable
218+
activeOpacity={activeOpacity}
219+
onPress={() => {
220+
setVisible(false);
221+
}}
222+
style={styles.action}
223+
>
213224
<Text variant="p0" color="text">
214225
{cancelText}
215226
</Text>
216227
</Pressable>
217-
</Modal>
228+
</Modal.Content>
229+
);
230+
};
231+
232+
const Share = () => null;
233+
234+
Share.displayName = 'Share';
235+
236+
Share.show = (props: ShareProps) => {
237+
const key = Portal.add(
238+
<ShareContent
239+
{...props}
240+
onAnimationEnd={visible => {
241+
if (!visible) {
242+
Portal.remove(key);
243+
}
244+
}}
245+
/>
218246
);
219247
};
220248

0 commit comments

Comments
 (0)