ripal-ui 1.1.395 → 2.0.2

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 (70) hide show
  1. package/README.md +3 -0
  2. package/components/Alert.jsx +74 -0
  3. package/components/Avatar.jsx +144 -0
  4. package/components/BottomSheet.jsx +187 -0
  5. package/components/Breadcrumb.jsx +48 -0
  6. package/components/Button.jsx +58 -0
  7. package/components/COLORS.js +138 -0
  8. package/components/Card.jsx +33 -0
  9. package/components/Checkbox.jsx +39 -0
  10. package/components/Dialog.jsx +188 -0
  11. package/components/Divider.jsx +62 -0
  12. package/components/Dropdown.jsx +229 -0
  13. package/components/Grid.jsx +26 -0
  14. package/components/Inline.jsx +37 -0
  15. package/components/Input.jsx +89 -0
  16. package/components/ProgressBar.jsx +65 -0
  17. package/components/Rate.jsx +39 -0
  18. package/components/Slider.jsx +219 -0
  19. package/components/Switch.jsx +45 -0
  20. package/components/Table.jsx +67 -0
  21. package/components/Text.jsx +56 -0
  22. package/components/Toggle.jsx +88 -0
  23. package/index.js +21 -2
  24. package/package.json +19 -23
  25. package/babel.config.js +0 -3
  26. package/components/BottomSheet.tsx +0 -197
  27. package/components/Carousel.tsx +0 -61
  28. package/components/Circle.tsx +0 -44
  29. package/components/DatePicker.jsx +0 -181
  30. package/components/Tab.tsx +0 -90
  31. package/components/Table.tsx +0 -95
  32. package/components/index.ts +0 -5
  33. package/config.js +0 -4
  34. package/dist/BottomSheet.js +0 -186
  35. package/dist/Button.js +0 -109
  36. package/dist/Carousel.js +0 -52
  37. package/dist/Circle.js +0 -42
  38. package/dist/DatePicker.js +0 -199
  39. package/dist/Dialog.js +0 -81
  40. package/dist/Dropdown.js +0 -97
  41. package/dist/Inline.js +0 -38
  42. package/dist/Input.js +0 -88
  43. package/dist/ProgressBar.js +0 -64
  44. package/dist/Separator.js +0 -47
  45. package/dist/Skeleton.js +0 -62
  46. package/dist/Switch.js +0 -74
  47. package/dist/Tab.js +0 -85
  48. package/dist/Table.js +0 -96
  49. package/dist/Text.js +0 -78
  50. package/dist/Toast.js +0 -72
  51. package/dist/Toggle.js +0 -54
  52. package/dist/index.js +0 -96
  53. package/elements/Button.tsx +0 -121
  54. package/elements/ColorPicker.tsx +0 -70
  55. package/elements/Dialog.tsx +0 -87
  56. package/elements/Dropdown.tsx +0 -88
  57. package/elements/Inline.tsx +0 -52
  58. package/elements/Input.tsx +0 -83
  59. package/elements/ProgressBar.tsx +0 -52
  60. package/elements/SecureStorage.js +0 -27
  61. package/elements/Separator.tsx +0 -71
  62. package/elements/Skeleton.tsx +0 -64
  63. package/elements/Slider.tsx +0 -133
  64. package/elements/Switch.tsx +0 -63
  65. package/elements/Text.tsx +0 -73
  66. package/elements/Toast.tsx +0 -71
  67. package/elements/Toggle.tsx +0 -59
  68. package/elements/index.js +0 -14
  69. package/index.d.ts +0 -237
  70. package/scripts/generateConfig.js +0 -80
package/README.md CHANGED
@@ -0,0 +1,3 @@
1
+ # Ripal UI
2
+
3
+ The doc is working in progress (still)
@@ -0,0 +1,74 @@
1
+ import React from "react";
2
+ import { StyleSheet, View } from "react-native";
3
+ import Inline from "./Inline";
4
+ import Text from "./Text";
5
+ import COLORS from "./COLORS";
6
+
7
+ /**
8
+ * @typedef {Object} AlertProps
9
+ * @property {string} title - Alert title text
10
+ * @property {string|null} [body] - Optional body text
11
+ * @property {string} [color] - Accent color
12
+ * @property {React.ReactNode|null} [icon] - Icon element
13
+ * @property {number} [iconSize] - Icon size
14
+ * @property {import("react-native").StyleProp<import("react-native").ViewStyle>} [iconStyle]
15
+ * @property {import("react-native").StyleProp<import("react-native").ViewStyle>} [contentStyle]
16
+ */
17
+
18
+ /**
19
+ * @param {AlertProps} props
20
+ */
21
+ const Alert = ({title, body = null, color = COLORS.primary, icon = null, iconSize = 42, iconStyle, contentStyle}) => {
22
+ return (
23
+ <Inline style={[
24
+ styles.container
25
+ ]} gap={15} alignItems={body === null ? 'center' : 'flex-start'}>
26
+ {
27
+ icon !== null &&
28
+ <View style={[
29
+ styles.icon,
30
+ {
31
+ height: iconSize,
32
+ aspectRatio: 1,
33
+ backgroundColor: color,
34
+ },
35
+ iconStyle
36
+ ]}>
37
+ {icon}
38
+ </View>
39
+ }
40
+ <View style={[
41
+ styles.content,
42
+ contentStyle,
43
+ ]}>
44
+ <Text style={{fontWeight: '700'}} color={COLORS.slate[800]}>{title}</Text>
45
+ {
46
+ body &&
47
+ <Text size={12}>{body}</Text>
48
+ }
49
+ </View>
50
+ </Inline>
51
+ )
52
+ }
53
+
54
+ const styles = StyleSheet.create({
55
+ container: {
56
+ borderWidth: 1,
57
+ borderColor: COLORS.slate[200],
58
+ borderRadius: 20,
59
+ padding: 10,
60
+ },
61
+ icon: {
62
+ alignItems: 'center',
63
+ justifyContent: 'center',
64
+ borderRadius: 15,
65
+ },
66
+ content: {
67
+ gap: 10,
68
+ flexGrow: 1,
69
+ flexBasis: 20,
70
+ flexShrink: 1,
71
+ }
72
+ });
73
+
74
+ export default Alert;
@@ -0,0 +1,144 @@
1
+ import React from "react";
2
+ import Inline from "./Inline";
3
+ import { Image, StyleSheet, View } from "react-native";
4
+ import Text from "./Text";
5
+
6
+ const Avatar = ({
7
+ images,
8
+ size = 48,
9
+ radius = 999,
10
+ borderColor = '#fff',
11
+ borderWidth = 4,
12
+ limit = 3
13
+ }) => {
14
+ const theImages = Array.isArray(images) ? images : images ? [images] : [];
15
+
16
+ const visibleImages = theImages.slice(0, limit);
17
+ const remainingImages = theImages.slice(limit);
18
+ const remaining = remainingImages.length;
19
+
20
+ // only render max 4 in grid
21
+ const gridImages = remainingImages.slice(0, 4);
22
+ const gridCount = gridImages.length;
23
+
24
+ const avatarStyle = {
25
+ height: size,
26
+ width: size,
27
+ borderRadius: radius,
28
+ borderColor,
29
+ borderWidth,
30
+ };
31
+
32
+ const getGridLayout = (count) => {
33
+ switch (count) {
34
+ case 1:
35
+ return [{ width: '100%', height: '100%' }];
36
+
37
+ case 2:
38
+ return [
39
+ { width: '50%', height: '100%' },
40
+ { width: '50%', height: '100%' }
41
+ ];
42
+
43
+ case 3:
44
+ return [
45
+ { width: '50%', height: '50%' },
46
+ { width: '50%', height: '50%' },
47
+ { width: '100%', height: '50%' }
48
+ ];
49
+
50
+ default: // 4
51
+ return [
52
+ { width: '50%', height: '50%' },
53
+ { width: '50%', height: '50%' },
54
+ { width: '50%', height: '50%' },
55
+ { width: '50%', height: '50%' }
56
+ ];
57
+ }
58
+ };
59
+
60
+ const gridLayout = getGridLayout(gridCount);
61
+
62
+ return (
63
+ <Inline gap={0}>
64
+ {visibleImages.map((img, i) => (
65
+ <Image
66
+ key={i}
67
+ source={{ uri: img }}
68
+ style={[
69
+ styles.img,
70
+ avatarStyle,
71
+ {
72
+ marginLeft: i === 0 ? 0 : -(size / 2.25),
73
+ }
74
+ ]}
75
+ />
76
+ ))}
77
+
78
+ {remaining > 0 && (
79
+ <View
80
+ style={[
81
+ styles.img,
82
+ avatarStyle,
83
+ {
84
+ marginLeft: -(size / 2.25),
85
+ overflow: 'hidden',
86
+ }
87
+ ]}
88
+ >
89
+ <View style={styles.grid}>
90
+ {gridImages.map((img, i) => (
91
+ <Image
92
+ key={i}
93
+ source={{ uri: img }}
94
+ style={[
95
+ styles.gridImg,
96
+ gridLayout[i]
97
+ ]}
98
+ />
99
+ ))}
100
+ </View>
101
+
102
+ <View style={styles.overlay}>
103
+ <Text style={[styles.overlayText, { fontSize: size * 0.28 }]}>
104
+ +{remaining}
105
+ </Text>
106
+ </View>
107
+ </View>
108
+ )}
109
+ </Inline>
110
+ );
111
+ };
112
+
113
+ const styles = StyleSheet.create({
114
+ img: {
115
+ backgroundColor: '#ddd',
116
+ },
117
+
118
+ grid: {
119
+ flex: 1,
120
+ flexDirection: 'row',
121
+ flexWrap: 'wrap',
122
+ },
123
+
124
+ gridImg: {
125
+ },
126
+
127
+ overlay: {
128
+ position: 'absolute',
129
+ top: 0,
130
+ right: 0,
131
+ bottom: 0,
132
+ left: 0,
133
+ backgroundColor: 'rgba(0,0,0,0.45)',
134
+ justifyContent: 'center',
135
+ alignItems: 'center',
136
+ },
137
+
138
+ overlayText: {
139
+ color: '#fff',
140
+ fontWeight: '700',
141
+ }
142
+ });
143
+
144
+ export default Avatar;
@@ -0,0 +1,187 @@
1
+ // BottomSheet.jsx
2
+ import React, { useEffect, useRef, useState } from "react";
3
+ import {
4
+ Animated, ScrollView, StyleSheet, TouchableWithoutFeedback, Platform, Pressable,
5
+ KeyboardAvoidingView,
6
+ Keyboard,
7
+ } from "react-native";
8
+
9
+ const OFFSCREEN = 1500;
10
+ const CLOSE_THRESHOLD = -100;
11
+
12
+ const BottomSheet = ({ visible = false, setVisible = null, onClose = null, children, style = null }) => {
13
+ const [isClosing, setClosing] = useState(false);
14
+ const [isVisible, setIsVisible] = useState(visible);
15
+
16
+ useEffect(() => {
17
+ if (!visible) return;
18
+
19
+ translateY.setValue(OFFSCREEN);
20
+
21
+ Animated.timing(translateY, {
22
+ toValue: 0,
23
+ duration: 300,
24
+ useNativeDriver: true,
25
+ }).start();
26
+
27
+ setClosing(false);
28
+
29
+ }, [visible]);
30
+
31
+ const translateY = useRef(new Animated.Value(OFFSCREEN)).current;
32
+ const keyboardShowEvent = Platform.OS === "ios" ? "keyboardWillShow" : "keyboardDidShow";
33
+ const keyboardHideEvent = Platform.OS === "ios" ? "keyboardWillHide" : "keyboardDidHide";
34
+
35
+ const backdropOpacity = translateY.interpolate({
36
+ inputRange: [0, 300],
37
+ outputRange: [0.4, 0],
38
+ extrapolate: "clamp",
39
+ });
40
+
41
+ useEffect(() => {
42
+ const keyboardDidShowListener = Keyboard.addListener(keyboardShowEvent, event => {
43
+ let keyboardHeight = event.endCoordinates.height - 81;
44
+
45
+ Animated.timing(translateY, {
46
+ toValue: -keyboardHeight,
47
+ duration: 300,
48
+ useNativeDriver: true,
49
+ }).start();
50
+ });
51
+ const keyboardDidHideListener = Keyboard.addListener(keyboardHideEvent, event => {
52
+ Animated.timing(translateY, {
53
+ toValue: 0,
54
+ duration: 300,
55
+ useNativeDriver: true,
56
+ }).start();
57
+ });
58
+
59
+ return () => {
60
+ keyboardDidShowListener.remove();
61
+ keyboardDidHideListener.remove();
62
+ }
63
+ }, []);
64
+
65
+ useEffect(() => {
66
+ translateY.setValue(OFFSCREEN);
67
+ Animated.timing(translateY, {
68
+ toValue: 0,
69
+ duration: 300,
70
+ useNativeDriver: true,
71
+ }).start();
72
+
73
+ setClosing(false);
74
+ }, []);
75
+
76
+ // animate out when isClosing turns true
77
+ useEffect(() => {
78
+ if (!isClosing) return;
79
+
80
+ Animated.timing(translateY, {
81
+ toValue: OFFSCREEN,
82
+ duration: 300,
83
+ useNativeDriver: true,
84
+ }).start(() => {
85
+ // after closing animation: tell parent to remove this component
86
+ if (typeof onClose === "function") {
87
+ onClose();
88
+ }
89
+ if (setVisible) {
90
+ setVisible(false);
91
+ }
92
+ // just in case it's not unmounted immediately, reset state/value
93
+ setClosing(false);
94
+ translateY.setValue(OFFSCREEN);
95
+ });
96
+ }, [isClosing]);
97
+
98
+ // handle backdrop press
99
+ const handleBackdropPress = () => {
100
+
101
+ if (!isClosing) {
102
+ setClosing(true);
103
+ };
104
+ };
105
+
106
+ if (!visible) return null;
107
+
108
+ return (
109
+ <Pressable style={styles.wrapper} pointerEvents="box-none" onPress={handleBackdropPress}>
110
+ {/* Animated backdrop */}
111
+ <TouchableWithoutFeedback onPress={handleBackdropPress}>
112
+ <Animated.View
113
+ style={[
114
+ styles.backdrop,
115
+ { opacity: backdropOpacity },
116
+ ]}
117
+ />
118
+ </TouchableWithoutFeedback>
119
+
120
+ <KeyboardAvoidingView
121
+ behavior={Platform.OS === "ios" ? "padding" : undefined}
122
+ keyboardVerticalOffset={Platform.OS === "ios" ? 60 : 0} // tweak if needed
123
+ style={{ flex: 1, justifyContent: "flex-end" }}
124
+ >
125
+ <Animated.View
126
+ style={[
127
+ styles.container_outer,
128
+ { transform: [
129
+ { translateY },
130
+ ] },
131
+ ]}
132
+ >
133
+ <ScrollView
134
+ contentContainerStyle={{ flexGrow: 1, justifyContent: 'flex-end', borderRadius: 12 }}
135
+ scrollEventThrottle={16}
136
+ // allow bigger overscroll on Android/iOS
137
+ bounces={true}
138
+ overScrollMode={Platform.OS === "android" ? "always" : undefined}
139
+ onScroll={(event) => {
140
+ const pos = event.nativeEvent.contentOffset.y;
141
+ // if user pulls down far enough, start closing
142
+ if (pos < CLOSE_THRESHOLD && !isClosing) {
143
+ setClosing(true);
144
+ }
145
+ }}
146
+ nestedScrollEnabled
147
+ >
148
+ <Pressable style={[styles.container, style]}>
149
+ {children}
150
+ </Pressable>
151
+ </ScrollView>
152
+ </Animated.View>
153
+ </KeyboardAvoidingView>
154
+ </Pressable>
155
+ );
156
+ };
157
+
158
+ const styles = StyleSheet.create({
159
+ wrapper: {
160
+ ...StyleSheet.absoluteFillObject,
161
+ zIndex: 999,
162
+ justifyContent: "flex-end",
163
+ },
164
+ backdrop: {
165
+ ...StyleSheet.absoluteFillObject,
166
+ backgroundColor: "#000",
167
+ },
168
+ container_outer: {
169
+ position: "absolute",
170
+ left: 0,
171
+ right: 0,
172
+ bottom: 0,
173
+ top: 0,
174
+ paddingTop: 90, // same as your earlier paddingTop
175
+ justifyContent: "flex-end",
176
+ alignContent: "flex-end",
177
+ },
178
+ container: {
179
+ backgroundColor: "#fff",
180
+ padding: 20,
181
+ paddingVertical: 30,
182
+ borderTopLeftRadius: 12,
183
+ borderTopRightRadius: 12,
184
+ },
185
+ });
186
+
187
+ export default BottomSheet;
@@ -0,0 +1,48 @@
1
+ import React from "react";
2
+ import { StyleSheet, TouchableOpacity } from "react-native";
3
+ import Inline from "./Inline";
4
+ import Text from "./Text";
5
+ import MaterialIcons from "@react-native-vector-icons/material-icons";
6
+ import COLORS from "./COLORS";
7
+
8
+ const Breadcrumb = ({items, gap = 5, icon = null}) => {
9
+ const isLast = (index) => index === items.length - 1;
10
+ return (
11
+ <Inline gap={gap}>
12
+ { items.map((item, i) => (
13
+ <Inline key={i} gap={gap}>
14
+ <TouchableOpacity key={i} style={[styles.item, isLast(i) ? styles.item_active : null]} onPress={() => {
15
+ if (item.hasOwnProperty('onPress')) {
16
+ item.onPress(item);
17
+ }
18
+ }}>
19
+ <Text
20
+ size={13}
21
+ color={isLast(i) ? COLORS.primary : COLORS.slate[700]}
22
+ style={{ fontWeight: isLast(i) ? '600' : '400' }}
23
+ >{item.text}</Text>
24
+ </TouchableOpacity>
25
+ {
26
+ i !== items.length - 1 &&
27
+ <>
28
+ {icon ? icon : <MaterialIcons name="chevron-right" size={14} />}
29
+ </>
30
+ }
31
+ </Inline>
32
+ )) }
33
+ </Inline>
34
+ )
35
+ }
36
+
37
+ const styles = StyleSheet.create({
38
+ item: {
39
+ borderRadius: 8,
40
+ },
41
+ item_active: {
42
+ padding: 8,
43
+ paddingHorizontal: 12,
44
+ backgroundColor: `${COLORS.primary}20`,
45
+ }
46
+ })
47
+
48
+ export default Breadcrumb;
@@ -0,0 +1,58 @@
1
+ import React, { useEffect } from "react";
2
+ import { StyleSheet, TouchableOpacity, View } from "react-native";
3
+ import Inline from "./Inline";
4
+ import Text from "./Text";
5
+ import COLORS from "./COLORS";
6
+
7
+ const Button = ({children, full = false, circle = false, color = COLORS.primary, size = 36, style, onPress, onLongPress, accent = 'primary', align = "center"}) => {
8
+ let computedStyles = {
9
+ flexGrow: full ? 1 : 0,
10
+ };
11
+
12
+ if (accent === "primary") {
13
+ computedStyles['backgroundColor'] = color;
14
+ computedStyles['textColor'] = COLORS.white;
15
+ } else if (accent === "secondary") {
16
+ computedStyles['backgroundColor'] = `${color}30`;
17
+ computedStyles['textColor'] = color;
18
+ } else if (accent == "tertiary") {
19
+ computedStyles['backgroundColor'] = `${color}00`,
20
+ computedStyles['textColor'] = color;
21
+ }
22
+
23
+ computedStyles['justifyContent'] = align === "left" ? "flex-start" : align === "right" ? "flex-end" : align;
24
+
25
+ return (
26
+ <Inline>
27
+ <Inline style={[
28
+ styles.button,
29
+ computedStyles,
30
+ circle ? {...styles.circle_button, height: size } : null,
31
+ style
32
+ ]} onPress={onPress} onLongPress={onLongPress}>
33
+ {typeof children === "string" ?
34
+ <Text color={computedStyles.textColor} style={{fontWeight: '700'}}>{children}</Text>
35
+ :
36
+ children
37
+ }
38
+ </Inline>
39
+ </Inline>
40
+ )
41
+ }
42
+
43
+ const styles = StyleSheet.create({
44
+ button: {
45
+ justifyContent: 'center',
46
+ alignItems: 'center',
47
+ backgroundColor: COLORS.primary,
48
+ borderRadius: 99,
49
+ padding: 12,
50
+ paddingHorizontal: 20,
51
+ },
52
+ circle_button: {
53
+ padding: 0,paddingHorizontal: 0,
54
+ aspectRatio: 1,
55
+ }
56
+ });
57
+
58
+ export default Button;
@@ -0,0 +1,138 @@
1
+ const COLORS = {
2
+ black: "#000",
3
+ white: "#fff",
4
+ primary: "#2196f3",
5
+
6
+ amber: {
7
+ 50: "#fffbeb",
8
+ 100: "#fef3c6", 200: "#fee685", 300: "#ffd230", 400: "#ffb900", 500: "#fe9a00",
9
+ 600: "#e17100", 700: "#bb4d00", 800: "#973c00", 900: "#7b3306", 950: "#461901"
10
+ },
11
+ blue: {
12
+ 50: "#eff6ff",
13
+ 100: "#dbeafe", 200: "#bedbff", 300: "#8ec5ff", 400: "#51a2ff", 500: "#2b7fff",
14
+ 600: "#155dfc", 700: "#1447e6", 800: "#193cb8", 900: "#1c398e", 950: "#162456"
15
+ },
16
+ cyan: {
17
+ 50: "#ecfeff",
18
+ 100: "#cefafe", 200: "#a2f4fd", 300: "#53eafd", 400: "#00d3f2", 500: "#00b8db",
19
+ 600: "#0092b8", 700: "#007595", 800: "#005f78", 900: "#104e64", 950: "#053345"
20
+ },
21
+ emerald: {
22
+ 50: "#ecfdf5",
23
+ 100: "#d0fae5", 200: "#a4f4cf", 300: "#5ee9b5", 400: "#00d492", 500: "#00bc7d",
24
+ 600: "#009966", 700: "#007a55", 800: "#006045", 900: "#004f3b", 950: "#002c22"
25
+ },
26
+ fuchsia: {
27
+ 50: "#fdf4ff",
28
+ 100: "#fae8ff", 200: "#f6cfff", 300: "#f4a8ff", 400: "#ed6aff", 500: "#e12afb",
29
+ 600: "#c800de", 700: "#a800b7", 800: "#8a0194", 900: "#721378", 950: "#4b004f"
30
+ },
31
+ gray: {
32
+ 50: "#f9fafb",
33
+ 100: "#f3f4f6", 200: "#e5e7eb", 300: "#d1d5dc", 400: "#99a1af", 500: "#6a7282",
34
+ 600: "#4a5565", 700: "#364153", 800: "#1e2939", 900: "#101828", 950: "#030712"
35
+ },
36
+ green: {
37
+ 50: "#f0fdf4",
38
+ 100: "#dcfce7", 200: "#b9f8cf", 300: "#7bf1a8", 400: "#05df72", 500: "#00c950",
39
+ 600: "#00a63e", 700: "#008236", 800: "#016630", 900: "#0d542b", 950: "#032e15"
40
+ },
41
+ indigo: {
42
+ 50: "#eef2ff",
43
+ 100: "#e0e7ff", 200: "#c6d2ff", 300: "#a3b3ff", 400: "#7c86ff", 500: "#615fff",
44
+ 600: "#4f39f6", 700: "#432dd7", 800: "#372aac", 900: "#312c85", 950: "#1e1a4d"
45
+ },
46
+ lime: {
47
+ 50: "#f7fee7",
48
+ 100: "#ecfcca", 200: "#d8f999", 300: "#bbf451", 400: "#9ae600", 500: "#7ccf00",
49
+ 600: "#5ea500", 700: "#497d00", 800: "#3c6300", 900: "#35530e", 950: "#192e03"
50
+ },
51
+ mauve: {
52
+ 50: "#fafafa",
53
+ 100: "#f3f1f3", 200: "#e7e4e7", 300: "#d7d0d7", 400: "#a89ea9", 500: "#79697b",
54
+ 600: "#594c5b", 700: "#463947", 800: "#2a212c", 900: "#1d161e", 950: "#0c090c"
55
+ },
56
+ mist: {
57
+ 50: "#f9fbfb",
58
+ 100: "#f1f3f3", 200: "#e3e7e8", 300: "#d0d6d8", 400: "#9ca8ab", 500: "#67787c",
59
+ 600: "#4b585b", 700: "#394447", 800: "#22292b", 900: "#161b1d", 950: "#090b0c"
60
+ },
61
+ neutral: {
62
+ 50: "#fafafa",
63
+ 100: "#f5f5f5", 200: "#e5e5e5", 300: "#d4d4d4", 400: "#a1a1a1", 500: "#737373",
64
+ 600: "#525252", 700: "#404040", 800: "#262626", 900: "#171717", 950: "#0a0a0a"
65
+ },
66
+ olive: {
67
+ 50: "#fbfbf9",
68
+ 100: "#f4f4f0", 200: "#e8e8e3", 300: "#d8d8d0", 400: "#abab9c", 500: "#7c7c67",
69
+ 600: "#5b5b4b", 700: "#474739", 800: "#2b2b22", 900: "#1d1d16", 950: "#0c0c09"
70
+ },
71
+ orange: {
72
+ 50: "#fff7ed",
73
+ 100: "#ffedd4", 200: "#ffd6a7", 300: "#ffb86a", 400: "#ff8904", 500: "#ff6900",
74
+ 600: "#f54900", 700: "#ca3500", 800: "#9f2d00", 900: "#7e2a0c", 950: "#441306"
75
+ },
76
+ pink: {
77
+ 50: "#fdf2f8",
78
+ 100: "#fce7f3", 200: "#fccee8", 300: "#fda5d5", 400: "#fb64b6", 500: "#f6339a",
79
+ 600: "#e60076", 700: "#c6005c", 800: "#a3004c", 900: "#861043", 950: "#510424"
80
+ },
81
+ purple: {
82
+ 50: "#faf5ff",
83
+ 100: "#f3e8ff", 200: "#e9d4ff", 300: "#dab2ff", 400: "#c27aff", 500: "#ad46ff",
84
+ 600: "#9810fa", 700: "#8200db", 800: "#6e11b0", 900: "#59168b", 950: "#3c0366"
85
+ },
86
+ red: {
87
+ 50: "#fef2f2",
88
+ 100: "#ffe2e2", 200: "#ffc9c9", 300: "#ffa2a2", 400: "#ff6467", 500: "#fb2c36",
89
+ 600: "#e7000b", 700: "#c10007", 800: "#9f0712", 900: "#82181a", 950: "#460809"
90
+ },
91
+ rose: {
92
+ 50: "#fff1f2",
93
+ 100: "#ffe4e6", 200: "#ffccd3", 300: "#ffa1ad", 400: "#ff637e", 500: "#ff2056",
94
+ 600: "#ec003f", 700: "#c70036", 800: "#a50036", 900: "#8b0836", 950: "#4d0218"
95
+ },
96
+ sky: {
97
+ 50: "#f0f9ff",
98
+ 100: "#dff2fe", 200: "#b8e6fe", 300: "#74d4ff", 400: "#00bcff", 500: "#00a6f4",
99
+ 600: "#0084d1", 700: "#0069a8", 800: "#00598a", 900: "#024a70", 950: "#052f4a"
100
+ },
101
+ slate: {
102
+ 50: "#f8fafc",
103
+ 100: "#f1f5f9", 200: "#e2e8f0", 300: "#cad5e2", 400: "#90a1b9", 500: "#62748e",
104
+ 600: "#45556c", 700: "#314158", 800: "#1d293d", 900: "#0f172b", 950: "#020618"
105
+ },
106
+ stone: {
107
+ 50: "#fafaf9",
108
+ 100: "#f5f5f4", 200: "#e7e5e4", 300: "#d6d3d1", 400: "#a6a09b", 500: "#79716b",
109
+ 600: "#57534d", 700: "#44403b", 800: "#292524", 900: "#1c1917", 950: "#0c0a09"
110
+ },
111
+ taupe: {
112
+ 50: "#fbfaf9",
113
+ 100: "#f3f1f1", 200: "#e8e4e3", 300: "#d8d2d0", 400: "#aba09c", 500: "#7c6d67",
114
+ 600: "#5b4f4b", 700: "#473c39", 800: "#2b2422", 900: "#1d1816", 950: "#0c0a09"
115
+ },
116
+ teal: {
117
+ 50: "#f0fdfa",
118
+ 100: "#cbfbf1", 200: "#96f7e4", 300: "#46ecd5", 400: "#00d5be", 500: "#00bba7",
119
+ 600: "#009689", 700: "#00786f", 800: "#005f5a", 900: "#0b4f4a", 950: "#022f2e"
120
+ },
121
+ violet: {
122
+ 50: "#f5f3ff",
123
+ 100: "#ede9fe", 200: "#ddd6ff", 300: "#c4b4ff", 400: "#a684ff", 500: "#8e51ff",
124
+ 600: "#7f22fe", 700: "#7008e7", 800: "#5d0ec0", 900: "#4d179a", 950: "#2f0d68"
125
+ },
126
+ yellow: {
127
+ 50: "#fefce8",
128
+ 100: "#fef9c2", 200: "#fff085", 300: "#ffdf20", 400: "#fdc700", 500: "#f0b100",
129
+ 600: "#d08700", 700: "#a65f00", 800: "#894b00", 900: "#733e0a", 950: "#432004"
130
+ },
131
+ zinc: {
132
+ 50: "#fafafa",
133
+ 100: "#f4f4f5", 200: "#e4e4e7", 300: "#d4d4d8", 400: "#9f9fa9", 500: "#71717b",
134
+ 600: "#52525c", 700: "#3f3f46", 800: "#27272a", 900: "#18181b", 950: "#09090b"
135
+ }
136
+ };
137
+
138
+ export default COLORS;
@@ -0,0 +1,33 @@
1
+ import React from "react";
2
+ import { ImageBackground, StyleSheet, View } from "react-native";
3
+ import Text from "./Text";
4
+ import COLORS from "./COLORS";
5
+
6
+ const Card = ({children, image = null, radius = 15, style, imageStyle}) => {
7
+ return (
8
+ <ImageBackground source={{uri: image}} imageStyle={[
9
+ {
10
+ borderRadius: radius,
11
+ },
12
+ imageStyle
13
+ ]} style={[
14
+ styles.card,
15
+ {
16
+ borderRadius: radius,
17
+ },
18
+ style
19
+ ]}>
20
+ {children}
21
+ </ImageBackground>
22
+ )
23
+ }
24
+
25
+ const styles = StyleSheet.create({
26
+ card: {
27
+ padding: 20,
28
+ borderWidth: 1,
29
+ borderColor: COLORS.slate[200]
30
+ }
31
+ })
32
+
33
+ export default Card;