@holper/react-native-holper-storybook 0.7.1 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/index.js +2 -3
  2. package/lib/components/Button/index.js +104 -0
  3. package/lib/components/Button/{style.ts → style.js} +7 -8
  4. package/lib/components/Card/index.js +49 -0
  5. package/lib/components/Card/{style.ts → style.js} +4 -5
  6. package/lib/components/ConfirmationModal/{index.tsx → index.js} +79 -25
  7. package/lib/components/ConfirmationModal/{style.tsx → style.js} +13 -14
  8. package/lib/components/Container/{index.tsx → index.js} +28 -7
  9. package/lib/components/Container/{style.ts → style.js} +5 -6
  10. package/lib/components/CustomChatView/{index.tsx → index.js} +30 -22
  11. package/lib/components/CustomChatView/{style.ts → style.js} +1 -1
  12. package/lib/components/DeckSwiper/index.js +118 -0
  13. package/lib/components/DeckSwiper/{style.ts → style.js} +12 -13
  14. package/lib/components/FlashMessage/index.js +83 -0
  15. package/lib/components/FloatingContainer/index.js +69 -0
  16. package/lib/components/FloatingContainer/{style.ts → style.js} +6 -7
  17. package/lib/components/Footer/index.js +61 -0
  18. package/lib/components/Footer/{style.ts → style.js} +3 -4
  19. package/lib/components/Header/index.js +45 -0
  20. package/lib/components/Header/{style.ts → style.js} +3 -4
  21. package/lib/components/ImagePicker/{index.tsx → index.js} +12 -3
  22. package/lib/components/ImageResponsive/index.js +39 -0
  23. package/lib/components/ImageResponsive/style.js +7 -0
  24. package/lib/components/ImageViewer/index.js +62 -0
  25. package/lib/components/ImageViewer/{style.ts → style.js} +3 -4
  26. package/lib/components/Input/{index.tsx → index.js} +33 -6
  27. package/lib/components/Input/{style.ts → style.js} +18 -7
  28. package/lib/components/InputPin/{index.tsx → index.js} +13 -6
  29. package/lib/components/InputPin/{style.ts → style.js} +6 -7
  30. package/lib/components/MenuItem/index.js +44 -0
  31. package/lib/components/MenuItem/{style.ts → style.js} +7 -9
  32. package/lib/components/NavigationTitle/{index.tsx → index.js} +30 -9
  33. package/lib/components/NavigationTitle/{style.ts → style.js} +11 -12
  34. package/lib/components/Notification/index.js +80 -0
  35. package/lib/components/Notification/{style.ts → style.js} +11 -13
  36. package/lib/components/PreventDoubleClick/index.js +21 -0
  37. package/lib/components/Select/index.js +89 -0
  38. package/lib/components/Select/style.js +81 -0
  39. package/lib/components/SwipeablePanel/{index.tsx → index.js} +85 -58
  40. package/lib/components/SwipeablePanel/{style.ts → style.js} +14 -15
  41. package/lib/components/Switch/index.js +57 -0
  42. package/lib/components/TakePicture/{confirmPictureModal.tsx → confirmPictureModal.js} +33 -9
  43. package/lib/components/TakePicture/index.js +198 -0
  44. package/lib/components/TakePicture/{style.ts → style.js} +4 -4
  45. package/lib/components/Text/index.js +75 -0
  46. package/lib/components/Text/{style.ts → style.js} +2 -4
  47. package/lib/components/Textarea/{index.tsx → index.js} +24 -5
  48. package/lib/components/Textarea/{style.ts → style.js} +4 -5
  49. package/lib/components/TimeOutButton/index.js +104 -0
  50. package/lib/components/TimeOutButton/{style.ts → style.js} +3 -4
  51. package/lib/components/UploadDocument/index.js +222 -0
  52. package/lib/components/UploadDocument/{style.ts → style.js} +15 -16
  53. package/lib/components/VirtualKeyboard/index.js +86 -0
  54. package/lib/components/VirtualKeyboard/{style.ts → style.js} +8 -9
  55. package/lib/components/index.js +28 -0
  56. package/lib/configs/constants.js +276 -0
  57. package/lib/configs/loadFonts.js +11 -0
  58. package/lib/hooks/index.js +1 -0
  59. package/lib/hooks/{useDebounce.tsx → useDebounce.js} +4 -6
  60. package/lib/index.js +2 -3
  61. package/package.json +58 -72
  62. package/{README.md → readme.md} +20 -19
  63. package/LICENSE +0 -21
  64. package/lib/components/Button/index.tsx +0 -66
  65. package/lib/components/Card/index.tsx +0 -33
  66. package/lib/components/DeckSwiper/index.tsx +0 -90
  67. package/lib/components/DonutCountdown/index.tsx +0 -86
  68. package/lib/components/DonutCountdown/style.ts +0 -8
  69. package/lib/components/FloatingContainer/index.tsx +0 -35
  70. package/lib/components/Footer/index.tsx +0 -35
  71. package/lib/components/Header/index.tsx +0 -21
  72. package/lib/components/ImageResponsive/index.tsx +0 -24
  73. package/lib/components/ImageResponsive/style.ts +0 -9
  74. package/lib/components/ImageViewer/index.tsx +0 -36
  75. package/lib/components/MenuItem/index.tsx +0 -25
  76. package/lib/components/Notification/index.tsx +0 -44
  77. package/lib/components/PreventDoubleClick/index.tsx +0 -28
  78. package/lib/components/Select/index.tsx +0 -51
  79. package/lib/components/Select/style.ts +0 -64
  80. package/lib/components/Switch/index.tsx +0 -30
  81. package/lib/components/TakePicture/index.tsx +0 -148
  82. package/lib/components/Text/index.tsx +0 -33
  83. package/lib/components/TimeOutButton/index.tsx +0 -67
  84. package/lib/components/Toast/index.tsx +0 -34
  85. package/lib/components/Toast/style.ts +0 -12
  86. package/lib/components/UploadDocument/index.tsx +0 -179
  87. package/lib/components/VirtualKeyboard/index.tsx +0 -75
  88. package/lib/components/index.ts +0 -29
  89. package/lib/configs/constants.ts +0 -273
  90. package/lib/configs/types.ts +0 -326
  91. package/lib/hooks/index.ts +0 -2
  92. package/lib/hooks/useLoadFonts.tsx +0 -13
@@ -0,0 +1,118 @@
1
+ import React, { useRef, useState } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { View, Image } from 'react-native';
4
+ import Swiper from 'react-native-deck-swiper';
5
+ import Entypo from 'react-native-vector-icons/Entypo';
6
+ import Text from '../Text';
7
+ import Button from '../Button';
8
+ import { Colors } from '../../configs/constants';
9
+ import style from './style';
10
+
11
+ const DeckSwiper = ({ data, inverted, nextText, onChange, onFinish }) => {
12
+ const swiper = useRef(null);
13
+ const [finished, setFinished] = useState(false);
14
+ const [index, setIndex] = useState(0);
15
+
16
+ const renderDots = () =>
17
+ data.map((d, i) => (
18
+ <Entypo
19
+ name='dot-single'
20
+ size={36}
21
+ key={`dot-${i}`}
22
+ style={style[index === i ? 'dotSelected' : 'dot']}
23
+ />
24
+ ));
25
+
26
+ return (
27
+ <>
28
+ <Swiper
29
+ ref={swiper}
30
+ cards={data}
31
+ renderCard={(card) => {
32
+ if (!card) {
33
+ return null;
34
+ }
35
+ return (
36
+ <View style={style.card}>
37
+ <View style={style.imageContainer}>
38
+ <Image
39
+ style={style.imageResponsive}
40
+ source={card.image}
41
+ progressiveRenderingEnabled
42
+ resizeMode='contain'
43
+ />
44
+ </View>
45
+ <View style={style.textContainer}>
46
+ <Text size='extra-large' style={style.title}>
47
+ {card.title}
48
+ </Text>
49
+ <Text size='large' align='center'>
50
+ {card.description}
51
+ </Text>
52
+ </View>
53
+ </View>
54
+ );
55
+ }}
56
+ onSwipedAll={() => {
57
+ setFinished(true);
58
+ onFinish();
59
+ }}
60
+ onSwipedRight={(index) => {
61
+ setIndex(index - 1);
62
+ onChange(index - 1);
63
+ }}
64
+ onSwipedLeft={(index) => {
65
+ setIndex(index + 1);
66
+ onChange(index + 1);
67
+ }}
68
+ cardIndex={index}
69
+ backgroundColor={Colors.white}
70
+ stackSize={2}
71
+ verticalSwipe={false}
72
+ showSecondCard={true}
73
+ disableRightSwipe={index === 0}
74
+ goBackToPreviousCardOnSwipeRight={true}
75
+ childrenOnTop
76
+ >
77
+ {!finished && (
78
+ <>
79
+ <View style={style.dotsContainer}>{renderDots()}</View>
80
+ <View style={style.container}>
81
+ <Button
82
+ variant={inverted ? 'inverted' : 'primary'}
83
+ onPress={() => swiper.current.swipeLeft()}
84
+ >
85
+ <Text color='white'>{nextText}</Text>
86
+ </Button>
87
+ </View>
88
+ </>
89
+ )}
90
+ </Swiper>
91
+ </>
92
+ );
93
+ };
94
+
95
+ DeckSwiper.defaultProps = {
96
+ data: [],
97
+ inverted: false,
98
+ nextText: ' ',
99
+ useUri: false,
100
+ onChange: () => {},
101
+ onfinish: () => {},
102
+ };
103
+
104
+ DeckSwiper.propTypes = {
105
+ data: PropTypes.arrayOf(
106
+ PropTypes.shape({
107
+ image: PropTypes.string,
108
+ title: PropTypes.string,
109
+ description: PropTypes.string,
110
+ })
111
+ ),
112
+ inverted: PropTypes.bool,
113
+ nextText: PropTypes.string,
114
+ onChange: PropTypes.func,
115
+ onFinish: PropTypes.func,
116
+ };
117
+
118
+ export default DeckSwiper;
@@ -1,10 +1,9 @@
1
- import { Dimensions, StyleSheet } from 'react-native';
1
+ import {Dimensions} from 'react-native';
2
+ import {Colors} from '../../configs/constants';
2
3
 
3
- import { Colors } from '../../configs/constants';
4
+ const {height, width} = Dimensions.get('window');
4
5
 
5
- const { height, width } = Dimensions.get('window');
6
-
7
- export default StyleSheet.create({
6
+ export default {
8
7
  container: {
9
8
  position: 'absolute',
10
9
  bottom: 0,
@@ -14,7 +13,7 @@ export default StyleSheet.create({
14
13
  paddingVertical: 30,
15
14
  paddingHorizontal: 15,
16
15
  marginBottom: 10,
17
- width,
16
+ width
18
17
  },
19
18
  card: {
20
19
  flex: 1,
@@ -29,17 +28,17 @@ export default StyleSheet.create({
29
28
  imageResponsive: {
30
29
  height: undefined,
31
30
  width: undefined,
32
- flex: 1,
31
+ flex: 1
33
32
  },
34
33
  textContainer: {
35
34
  display: 'flex',
36
35
  flexDirection: 'column',
37
36
  justifyContent: 'center',
38
37
  alignItems: 'center',
39
- width: width - 100,
38
+ width: width - 100
40
39
  },
41
40
  title: {
42
- marginVertical: 10,
41
+ marginVertical: 10
43
42
  },
44
43
  dotsContainer: {
45
44
  width,
@@ -51,9 +50,9 @@ export default StyleSheet.create({
51
50
  bottom: 130,
52
51
  },
53
52
  dot: {
54
- color: Colors.gray,
53
+ color: Colors.gray
55
54
  },
56
55
  dotSelected: {
57
- color: Colors.green,
58
- },
59
- });
56
+ color: Colors.green
57
+ }
58
+ };
@@ -0,0 +1,83 @@
1
+ import React from "react";
2
+ import { Platform } from "react-native";
3
+ import PropTypes from "prop-types";
4
+ import Ionicons from "react-native-vector-icons/Ionicons";
5
+ import RNFlashMessage, {
6
+ showMessage,
7
+ renderFlashMessageIcon,
8
+ } from "react-native-flash-message";
9
+ import { Colors } from "../../configs/constants";
10
+
11
+ export const customRenderFlashMessageIcon = (
12
+ icon = "success",
13
+ style = {},
14
+ customProps = {}
15
+ ) => {
16
+ switch (icon) {
17
+ case "success":
18
+ return (
19
+ <Ionicons
20
+ name="checkmark-circle-outline"
21
+ color={Colors.darkergreen}
22
+ size={30}
23
+ />
24
+ );
25
+ case "error":
26
+ return (
27
+ <Ionicons
28
+ name="alert-circle-outline"
29
+ color={Colors.darkerred}
30
+ size={30}
31
+ />
32
+ );
33
+ }
34
+
35
+ // it's good to inherit the original method...
36
+ return renderFlashMessageIcon(icon, style, customProps);
37
+ };
38
+
39
+ const statusBarHeight = Platform.OS === "android" ? { statusBarHeight: 5 } : {};
40
+
41
+ export const sendMessage = ({ variant, message, description }) => {
42
+ return showMessage({
43
+ position: "top",
44
+ message,
45
+ description,
46
+ icon: variant,
47
+ type: variant,
48
+ backgroundColor:
49
+ variant === "success" ? Colors.lightergreen : Colors.lightertred,
50
+ color: variant === "success" ? Colors.darkergreen : Colors.darkerred,
51
+ hideOnPress: true,
52
+ duration: 5000,
53
+ ...statusBarHeight,
54
+ });
55
+ };
56
+
57
+ sendMessage.defaultProps = {
58
+ options: {
59
+ variant: "success",
60
+ message: " ",
61
+ description: " ",
62
+ },
63
+ };
64
+
65
+ sendMessage.propTypes = {
66
+ options: PropTypes.shape({
67
+ variant: PropTypes.oneOf(["success", "error"]),
68
+ message: PropTypes.string,
69
+ description: PropTypes.string,
70
+ }),
71
+ };
72
+
73
+ const FlashMessage = () => {
74
+ return (
75
+ <RNFlashMessage
76
+ renderFlashMessageIcon={customRenderFlashMessageIcon}
77
+ titleStyle={{ fontFamily: "poppins_bold" }}
78
+ textStyle={{ fontFamily: "poppins_regular" }}
79
+ />
80
+ );
81
+ };
82
+
83
+ export default FlashMessage;
@@ -0,0 +1,69 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import {
4
+ View,
5
+ ScrollView,
6
+ RefreshControl,
7
+ KeyboardAvoidingView,
8
+ Platform,
9
+ } from 'react-native';
10
+ import style from './style';
11
+
12
+ const FloatingContainer = ({
13
+ useRefreshControl,
14
+ onRefresh,
15
+ isRefreshing,
16
+ children,
17
+ floatingComponent,
18
+ centered,
19
+ floatingContainerStyle,
20
+ disableScroll,
21
+ }) => (
22
+ <KeyboardAvoidingView
23
+ style={style.floatingContainer}
24
+ behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
25
+ >
26
+ <ScrollView
27
+ contentContainerStyle={centered ? style.centered : {}}
28
+ fadingEdgeLength={150}
29
+ keyboardShouldPersistTaps='handled'
30
+ showsVerticalScrollIndicator={false}
31
+ scrollEnabled={!disableScroll}
32
+ keyboardDismissMode='on-drag'
33
+ refreshControl={
34
+ useRefreshControl ? (
35
+ <RefreshControl refreshing={isRefreshing} onRefresh={onRefresh} />
36
+ ) : null
37
+ }
38
+ >
39
+ {children}
40
+ </ScrollView>
41
+ <View style={[style.container, floatingContainerStyle]}>
42
+ {floatingComponent}
43
+ </View>
44
+ </KeyboardAvoidingView>
45
+ );
46
+
47
+ FloatingContainer.defaultProps = {
48
+ useRefreshControl: false,
49
+ isRefreshing: false,
50
+ centered: false,
51
+ onRefresh: () => {},
52
+ children: null,
53
+ floatingComponent: null,
54
+ disableScroll: false,
55
+ floatingContainerStyle: {},
56
+ };
57
+
58
+ FloatingContainer.propTypes = {
59
+ useRefreshControl: PropTypes.bool,
60
+ isRefreshing: PropTypes.bool,
61
+ centered: PropTypes.bool,
62
+ onRefresh: PropTypes.func,
63
+ children: PropTypes.node,
64
+ floatingComponent: PropTypes.node,
65
+ disableScroll: PropTypes.bool,
66
+ floatingContainerStyle: PropTypes.any,
67
+ };
68
+
69
+ export default FloatingContainer;
@@ -1,12 +1,11 @@
1
- import { Dimensions, StyleSheet } from 'react-native';
2
-
1
+ import { Dimensions } from 'react-native';
3
2
  import { Colors } from '../../configs/constants';
4
3
 
5
4
  const { width } = Dimensions.get('window');
6
5
 
7
- export default StyleSheet.create({
6
+ export default {
8
7
  floatingContainer: {
9
- flex: 1,
8
+ flex: 1
10
9
  },
11
10
  container: {
12
11
  minHeight: 50,
@@ -20,6 +19,6 @@ export default StyleSheet.create({
20
19
  alignSelf: 'center',
21
20
  },
22
21
  centered: {
23
- alignItems: 'center',
24
- },
25
- });
22
+ alignItems: 'center'
23
+ }
24
+ };
@@ -0,0 +1,61 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { View, TouchableOpacity } from 'react-native';
4
+ import Ionicons from 'react-native-vector-icons/Ionicons';
5
+ import { Colors } from '../../configs/constants';
6
+ import Text from '../Text';
7
+ import style from './style';
8
+
9
+ const Footer = ({ inverted, tabs }) => {
10
+ const renderTab = () =>
11
+ tabs.map((tab, index) => (
12
+ <TouchableOpacity
13
+ key={`tab-${index}`}
14
+ style={style.tab}
15
+ onPress={tab.onPress}
16
+ >
17
+ <Ionicons
18
+ name={tab.icon}
19
+ size={20}
20
+ color={inverted ? Colors.white : Colors.darkblue}
21
+ />
22
+ <Text color={inverted ? 'white' : 'dark'} size='small'>
23
+ {tab.text}
24
+ </Text>
25
+ {tab.badge && tab.badge > 0 && (
26
+ <View style={style.badge}>
27
+ <Text color='white' size='tiny' weight='semiBold' align='center'>
28
+ {tab.badge > 9 ? '+9' : tab.badge}
29
+ </Text>
30
+ </View>
31
+ )}
32
+ </TouchableOpacity>
33
+ ));
34
+
35
+ return (
36
+ <View
37
+ style={[style.footerContainer, style[inverted ? 'inverted' : 'default']]}
38
+ >
39
+ {renderTab()}
40
+ </View>
41
+ );
42
+ };
43
+
44
+ Footer.defaultProps = {
45
+ inverted: false,
46
+ tabs: [],
47
+ };
48
+
49
+ Footer.propTypes = {
50
+ inverted: PropTypes.bool,
51
+ tabs: PropTypes.arrayOf(
52
+ PropTypes.shape({
53
+ onPress: PropTypes.func,
54
+ text: PropTypes.string,
55
+ icon: PropTypes.string,
56
+ badge: PropTypes.number,
57
+ })
58
+ ),
59
+ };
60
+
61
+ export default Footer;
@@ -1,10 +1,9 @@
1
- import { Dimensions, StyleSheet } from 'react-native';
2
-
1
+ import { Dimensions } from 'react-native';
3
2
  import { Colors } from '../../configs/constants';
4
3
 
5
4
  const { width } = Dimensions.get('window');
6
5
 
7
- export default StyleSheet.create({
6
+ export default {
8
7
  footerContainer: {
9
8
  width,
10
9
  height: 70,
@@ -37,4 +36,4 @@ export default StyleSheet.create({
37
36
  borderRadius: 9,
38
37
  justifyContent: 'center',
39
38
  },
40
- });
39
+ };
@@ -0,0 +1,45 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { View, TouchableOpacity, Image } from 'react-native';
4
+ import Ionicons from 'react-native-vector-icons/Ionicons';
5
+ import { Colors } from '../../configs/constants';
6
+ import style from './style';
7
+
8
+ const Header = ({ inverted, logo, right, onMenuPress }) => (
9
+ <View
10
+ style={[style.headerContainer, style[inverted ? 'inverted' : 'default']]}
11
+ >
12
+ <TouchableOpacity onPress={onMenuPress}>
13
+ <Ionicons
14
+ name='menu-outline'
15
+ size={30}
16
+ color={inverted ? Colors.white : Colors.darkblue}
17
+ />
18
+ </TouchableOpacity>
19
+ <View style={style.imageContainer}>
20
+ <Image
21
+ style={style.imageResponsive}
22
+ source={logo}
23
+ progressiveRenderingEnabled
24
+ resizeMode='contain'
25
+ />
26
+ </View>
27
+ {right}
28
+ </View>
29
+ );
30
+
31
+ Header.defaultProps = {
32
+ inverted: false,
33
+ logo: null,
34
+ right: null,
35
+ onMenuPress: () => {},
36
+ };
37
+
38
+ Header.propTypes = {
39
+ inverted: PropTypes.bool,
40
+ logo: PropTypes.any.isRequired,
41
+ right: PropTypes.node,
42
+ onMenuPress: PropTypes.func,
43
+ };
44
+
45
+ export default Header;
@@ -1,10 +1,9 @@
1
- import { Dimensions, StyleSheet } from 'react-native';
2
-
1
+ import { Dimensions } from 'react-native';
3
2
  import { Colors } from '../../configs/constants';
4
3
 
5
4
  const { width } = Dimensions.get('window');
6
5
 
7
- export default StyleSheet.create({
6
+ export default {
8
7
  headerContainer: {
9
8
  width,
10
9
  height: 70,
@@ -31,4 +30,4 @@ export default StyleSheet.create({
31
30
  width: undefined,
32
31
  flex: 1,
33
32
  },
34
- });
33
+ };
@@ -1,6 +1,7 @@
1
+ import PropTypes from 'prop-types';
1
2
  import * as ExpoImagePicker from 'expo-image-picker';
2
3
 
3
- const ImagePicker = async (avatar: boolean = false) => {
4
+ const ImagePicker = async (avatar) => {
4
5
  const image = await ExpoImagePicker.launchImageLibraryAsync({
5
6
  mediaTypes: ['images'],
6
7
  allowsEditing: avatar,
@@ -9,10 +10,18 @@ const ImagePicker = async (avatar: boolean = false) => {
9
10
  });
10
11
 
11
12
  if (image.canceled) {
12
- return undefined;
13
+ return;
13
14
  }
14
15
 
15
- return image.assets && image.assets.length > 0 ? image.assets[0].uri : undefined;
16
+ return image.assets[0].uri;
17
+ };
18
+
19
+ ImagePicker.defaultProps = {
20
+ avatar: false,
21
+ };
22
+
23
+ ImagePicker.propTypes = {
24
+ avatar: PropTypes.bool,
16
25
  };
17
26
 
18
27
  export default ImagePicker;
@@ -0,0 +1,39 @@
1
+ import React, { useState } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { Image, View } from 'react-native';
4
+ import style from './style';
5
+
6
+ const ImageResponsive = ({ source, style: customStyle, avatar, ...props }) => {
7
+ const [width, setWidth] = useState(100);
8
+
9
+ return (
10
+ <View
11
+ style={[
12
+ customStyle,
13
+ avatar ? { borderRadius: width / 2, overflow: 'hidden' } : {},
14
+ ]}
15
+ >
16
+ <Image
17
+ style={style.responsiveImage}
18
+ source={source}
19
+ resizeMode={avatar ? 'cover' : 'contain'}
20
+ onLayout={({ nativeEvent }) => setWidth(nativeEvent.layout.width)}
21
+ {...props}
22
+ />
23
+ </View>
24
+ );
25
+ };
26
+
27
+ ImageResponsive.defaultProps = {
28
+ style: {},
29
+ source: null,
30
+ avatar: false,
31
+ };
32
+
33
+ ImageResponsive.propTypes = {
34
+ style: PropTypes.any,
35
+ source: PropTypes.any.isRequired,
36
+ avatar: PropTypes.bool,
37
+ };
38
+
39
+ export default ImageResponsive;
@@ -0,0 +1,7 @@
1
+ export default {
2
+ responsiveImage: {
3
+ height: undefined,
4
+ width: undefined,
5
+ flex: 1
6
+ }
7
+ };
@@ -0,0 +1,62 @@
1
+ import React, { useState } from 'react';
2
+ import {
3
+ View,
4
+ Modal,
5
+ TouchableOpacity,
6
+ ActivityIndicator,
7
+ Image,
8
+ } from 'react-native';
9
+ import Ionicons from 'react-native-vector-icons/Ionicons';
10
+ import ImageResponsive from '../ImageResponsive';
11
+ import { Colors } from '../../configs/constants';
12
+ import style from './style';
13
+ import PropTypes from 'prop-types';
14
+
15
+ const ImageViewer = ({ source, style: imageStyle, ...props }) => {
16
+ const [loading, setLoading] = useState(true);
17
+ const [visible, setVisible] = useState(false);
18
+
19
+ return (
20
+ <>
21
+ <TouchableOpacity onPress={() => setVisible(true)}>
22
+ <ImageResponsive source={source} style={imageStyle} {...props} />
23
+ </TouchableOpacity>
24
+
25
+ <Modal
26
+ animationType='slide'
27
+ transparent={true}
28
+ visible={visible}
29
+ onRequestClose={() => {}}
30
+ >
31
+ <View style={style.container}>
32
+ <TouchableOpacity
33
+ onPress={() => setVisible(false)}
34
+ style={style.closeIcon}
35
+ >
36
+ <Ionicons name='close-outline' size={24} color={Colors.darkblue} />
37
+ </TouchableOpacity>
38
+
39
+ <ImageResponsive
40
+ source={source}
41
+ style={style.body}
42
+ onLoadEnd={() => setLoading(false)}
43
+ />
44
+
45
+ {loading && <ActivityIndicator style={style.activityIndicator} />}
46
+ </View>
47
+ </Modal>
48
+ </>
49
+ );
50
+ };
51
+
52
+ ImageViewer.defaultProps = {
53
+ source: null,
54
+ style: {},
55
+ };
56
+
57
+ ImageViewer.propTypes = {
58
+ source: PropTypes.any.isRequired,
59
+ style: PropTypes.any,
60
+ };
61
+
62
+ export default ImageViewer;
@@ -1,10 +1,9 @@
1
- import { Dimensions, StyleSheet } from 'react-native';
2
-
1
+ import { Dimensions } from 'react-native';
3
2
  import { Colors } from '../../configs/constants';
4
3
 
5
4
  const { width, height } = Dimensions.get('window');
6
5
 
7
- export default StyleSheet.create({
6
+ export default {
8
7
  container: {
9
8
  backgroundColor: 'rgba(0,0,0,0.9)',
10
9
  flex: 1,
@@ -35,4 +34,4 @@ export default StyleSheet.create({
35
34
  left: width / 2 - 20,
36
35
  position: 'absolute',
37
36
  },
38
- });
37
+ };