react-native-boxes 1.0.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 (55) hide show
  1. package/README.md +1 -0
  2. package/dist/Bar.d.ts +26 -0
  3. package/dist/Bar.js +159 -0
  4. package/dist/Bar.js.map +1 -0
  5. package/dist/Box.d.ts +14 -0
  6. package/dist/Box.js +103 -0
  7. package/dist/Box.js.map +1 -0
  8. package/dist/Button.d.ts +20 -0
  9. package/dist/Button.js +220 -0
  10. package/dist/Button.js.map +1 -0
  11. package/dist/Image.d.ts +21 -0
  12. package/dist/Image.js +79 -0
  13. package/dist/Image.js.map +1 -0
  14. package/dist/Input.d.ts +27 -0
  15. package/dist/Input.js +190 -0
  16. package/dist/Input.js.map +1 -0
  17. package/dist/Message.d.ts +7 -0
  18. package/dist/Message.js +97 -0
  19. package/dist/Message.js.map +1 -0
  20. package/dist/Modal.d.ts +22 -0
  21. package/dist/Modal.js +247 -0
  22. package/dist/Modal.js.map +1 -0
  23. package/dist/Styles.d.ts +113 -0
  24. package/dist/Styles.js +105 -0
  25. package/dist/Styles.js.map +1 -0
  26. package/dist/Text.d.ts +5 -0
  27. package/dist/Text.js +49 -0
  28. package/dist/Text.js.map +1 -0
  29. package/dist/ThemeContext.d.ts +93 -0
  30. package/dist/ThemeContext.js +26 -0
  31. package/dist/ThemeContext.js.map +1 -0
  32. package/dist/demo.d.ts +5 -0
  33. package/dist/demo.js +301 -0
  34. package/dist/demo.js.map +1 -0
  35. package/dist/index.d.ts +8 -0
  36. package/dist/index.js +25 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/utils.d.ts +5 -0
  39. package/dist/utils.js +45 -0
  40. package/dist/utils.js.map +1 -0
  41. package/package.json +37 -0
  42. package/src/Bar.tsx +185 -0
  43. package/src/Box.tsx +106 -0
  44. package/src/Button.tsx +282 -0
  45. package/src/Image.tsx +107 -0
  46. package/src/Input.tsx +244 -0
  47. package/src/Message.tsx +90 -0
  48. package/src/Modal.tsx +306 -0
  49. package/src/Styles.tsx +117 -0
  50. package/src/Text.tsx +56 -0
  51. package/src/ThemeContext.ts +25 -0
  52. package/src/demo.tsx +383 -0
  53. package/src/index.tsx +8 -0
  54. package/src/utils.ts +49 -0
  55. package/tsconfig.json +25 -0
package/src/Box.tsx ADDED
@@ -0,0 +1,106 @@
1
+ import { useContext } from "react";
2
+ import { ScrollViewProps, View, ViewProps } from "react-native";
3
+ import { ThemeContext } from "./ThemeContext";
4
+ import * as React from 'react'
5
+ import { KeyboardAvoidingView, ScrollView } from 'react-native'
6
+ import { useSafeAreaInsets } from "react-native-safe-area-context";
7
+ import { isWeb } from "./utils";
8
+
9
+ export function Box(props: ViewProps) {
10
+ const theme = useContext(ThemeContext)
11
+ return (
12
+ <View
13
+ {...props}
14
+ style={[
15
+ {
16
+ padding: theme.dimens.space.xs,
17
+ backgroundColor: theme.randomColor() || 'transparent'
18
+ },
19
+ props.style
20
+ ]} />
21
+ )
22
+ }
23
+
24
+ export function VBox(props: ViewProps) {
25
+ const theme = useContext(ThemeContext)
26
+ return (
27
+ <Box {...props} style={[
28
+ {
29
+ flexDirection: 'column',
30
+ backgroundColor: theme.randomColor() || 'transparent'
31
+ },
32
+ props.style
33
+ ]} />
34
+ )
35
+ }
36
+
37
+ export function HBox(props: ViewProps) {
38
+
39
+ return (
40
+ <VBox {...props} style={[
41
+ {
42
+ flexDirection: 'row',
43
+ },
44
+ props.style
45
+ ]} />
46
+ )
47
+ }
48
+
49
+ export function Center(props: ViewProps) {
50
+ const theme = useContext(ThemeContext)
51
+ return (
52
+ <Box
53
+ {...props}
54
+ style={[{
55
+ alignItems: 'center',
56
+ justifyContent: 'center',
57
+ backgroundColor: theme.randomColor() || 'transparent'
58
+ },
59
+ props.style]} />
60
+ )
61
+ }
62
+
63
+
64
+ export function VPage(props: ViewProps) {
65
+ const theme = useContext(ThemeContext)
66
+ return (
67
+ <VBox {...props} style={[
68
+ {
69
+ width: '100%',
70
+ height: '100%',
71
+ padding: 0,
72
+ margin: 0,
73
+ },
74
+ props.style
75
+ ]} />
76
+ )
77
+ }
78
+
79
+ /**
80
+ * Must be wrapped with SafeAreaView somewhere in parent tree
81
+ * @param param0
82
+ * @returns
83
+ */
84
+ const KeyboardAvoidingScrollView: React.FC<ScrollViewProps> = (props: ScrollViewProps) => {
85
+
86
+ const insets = useSafeAreaInsets();
87
+ if (isWeb()) {
88
+ return <ScrollView
89
+ showsVerticalScrollIndicator={false}
90
+ {...props} />
91
+ }
92
+ return (
93
+ <KeyboardAvoidingView
94
+ style={props.style}
95
+ behavior="padding" enabled
96
+ keyboardVerticalOffset={insets.top}
97
+ >
98
+ <ScrollView
99
+ showsHorizontalScrollIndicator={false}
100
+ showsVerticalScrollIndicator={false}
101
+ {...props} />
102
+ </KeyboardAvoidingView>
103
+ )
104
+ }
105
+
106
+ export default KeyboardAvoidingScrollView
package/src/Button.tsx ADDED
@@ -0,0 +1,282 @@
1
+ import { useContext, useEffect, useState } from "react";
2
+ import { TextProps, TouchableHighlight, GestureResponderEvent, TouchableHighlightProps, View, ActivityIndicator, LayoutAnimation, PressableProps, Pressable } from "react-native";
3
+ import { ThemeContext } from "./ThemeContext";
4
+ import { Center, HBox } from "./Box";
5
+ import { TextView } from "./Text";
6
+
7
+ export function TransparentButton(props: TextProps & TouchableHighlightProps
8
+ & { icon?: any, text?: string }) {
9
+ const theme = useContext(ThemeContext)
10
+ const tstyle = props.style || {}
11
+ const [isPressed, setIsPressed] = useState(false)
12
+ const onPressIn = (e: GestureResponderEvent) => {
13
+ setIsPressed(true)
14
+ if (props.onPressIn) props.onPressIn(e)
15
+ }
16
+ const onPressOut = (e: GestureResponderEvent) => {
17
+ setIsPressed(false)
18
+ if (props.onPressOut) props.onPressOut(e)
19
+ }
20
+ return (
21
+ <TouchableHighlight
22
+ {...props}
23
+ onPressIn={onPressIn}
24
+ onPressOut={onPressOut}
25
+ underlayColor={theme.colors.transparent}
26
+ style={[{
27
+ justifyContent: 'center',
28
+ alignContent: 'center',
29
+ alignItems: 'center',
30
+ padding: theme.dimens.space.md,
31
+ borderRadius: theme.dimens.space.xl,
32
+ margin: theme.dimens.space.sm,
33
+ backgroundColor: theme.colors.accent,
34
+ }, props.style]}>
35
+ <Center style={{
36
+ padding: 0,
37
+ margin: 0,
38
+ flexDirection: 'row',
39
+ backgroundColor: 'transparent'
40
+ }}>
41
+
42
+ {
43
+ props.icon && (
44
+ <View style={{
45
+ margin: theme.dimens.space.sm
46
+ }}>
47
+ {props.icon}
48
+ </View>
49
+ )
50
+ }
51
+
52
+ {
53
+ (props.text || props.children) && (
54
+ <TextView style={{
55
+ fontWeight: "500",
56
+ justifyContent: 'center',
57
+ alignContent: 'center',
58
+ alignItems: 'center',
59
+ //@ts-ignore
60
+ fontSize: tstyle.fontSize,
61
+ //@ts-ignore
62
+ fontFamily: tstyle.fontFamily,
63
+ //@ts-ignore
64
+ color: isPressed ? (props.underlayColor || theme.colors.accent) : tstyle.color || theme.colors.text,
65
+ }}>
66
+ {props.text || props.children}
67
+ </TextView>
68
+ )
69
+ }
70
+ </Center>
71
+ </TouchableHighlight>
72
+ )
73
+ }
74
+
75
+ export function ButtonView(props: TextProps & TouchableHighlightProps
76
+ & { icon?: any, text?: string }) {
77
+ const theme = useContext(ThemeContext)
78
+ const tstyle = props.style || {}
79
+ const [isPressed, setIsPressed] = useState(false)
80
+ const onPressIn = (e: GestureResponderEvent) => {
81
+ setIsPressed(true)
82
+ if (props.onPressIn) props.onPressIn(e)
83
+ }
84
+ const onPressOut = (e: GestureResponderEvent) => {
85
+ setIsPressed(false)
86
+ if (props.onPressOut) props.onPressOut(e)
87
+ }
88
+ return (
89
+ <TouchableHighlight
90
+ {...props}
91
+ onPressIn={onPressIn}
92
+ onPressOut={onPressOut}
93
+ underlayColor={props.underlayColor || theme.colors.accentLight}
94
+ style={[{
95
+ justifyContent: 'center',
96
+ alignContent: 'center',
97
+ alignItems: 'center',
98
+ padding: theme.dimens.space.md,
99
+ borderRadius: theme.dimens.space.xl,
100
+ margin: theme.dimens.space.sm,
101
+ backgroundColor: theme.colors.accent,
102
+ }, props.style]}>
103
+ <Center style={{
104
+ padding: 0,
105
+ margin: 0,
106
+ flexDirection: 'row',
107
+ backgroundColor: 'transparent'
108
+ }}>
109
+
110
+ {
111
+ props.icon && (
112
+ <View style={{
113
+ margin: theme.dimens.space.sm
114
+ }}>
115
+ {props.icon}
116
+ </View>
117
+ )
118
+ }
119
+
120
+ {
121
+ (props.text || props.children) && (
122
+ <TextView style={{
123
+ opacity: isPressed ? .7 : 1,
124
+ fontWeight: "500",
125
+ justifyContent: 'center',
126
+ alignContent: 'center',
127
+ alignItems: 'center',
128
+ //@ts-ignore
129
+ fontSize: tstyle.fontSize,
130
+ //@ts-ignore
131
+ fontFamily: tstyle.fontFamily,
132
+ //@ts-ignore
133
+ color: tstyle.color || theme.colors.invert.text,
134
+ }}>
135
+ {props.text || props.children}
136
+ </TextView>
137
+ )
138
+ }
139
+ </Center>
140
+ </TouchableHighlight>
141
+ )
142
+ }
143
+
144
+
145
+ export function RightIconButton(props: TextProps & TouchableHighlightProps
146
+ & { icon?: any, text?: string }) {
147
+
148
+ const theme = useContext(ThemeContext)
149
+ const tstyle = props.style || {}
150
+ const [isPressed, setIsPressed] = useState(false)
151
+ const onPressIn = (e: GestureResponderEvent) => {
152
+ setIsPressed(true)
153
+ if (props.onPressIn) props.onPressIn(e)
154
+ }
155
+ const onPressOut = (e: GestureResponderEvent) => {
156
+ setIsPressed(false)
157
+ if (props.onPressOut) props.onPressOut(e)
158
+ }
159
+ return (
160
+ <TouchableHighlight
161
+ {...props}
162
+ onPressIn={onPressIn}
163
+ onPressOut={onPressOut}
164
+ underlayColor={props.underlayColor || theme.colors.accentLight}
165
+ style={[{
166
+ justifyContent: 'center',
167
+ alignContent: 'center',
168
+ alignItems: 'center',
169
+ padding: theme.dimens.space.md,
170
+ borderRadius: theme.dimens.space.xl,
171
+ margin: theme.dimens.space.sm,
172
+ backgroundColor: theme.colors.accent,
173
+ }, props.style]}>
174
+
175
+ <HBox style={{
176
+ padding: 0,
177
+ margin: 0,
178
+ alignItems: 'center',
179
+ backgroundColor: 'transparent',
180
+ width: '100%',
181
+ paddingLeft: theme.dimens.space.sm,
182
+ paddingRight: theme.dimens.space.sm,
183
+ }}>
184
+ <Center style={{
185
+ padding: 0,
186
+ margin: 0,
187
+ flexDirection: 'row',
188
+ backgroundColor: 'transparent'
189
+ }}>
190
+
191
+ {
192
+ (props.text) && (
193
+ <TextView style={{
194
+ marginRight: theme.dimens.space.lg,
195
+ justifyContent: 'center',
196
+ alignContent: 'center',
197
+ alignItems: 'center',
198
+ //@ts-ignore
199
+ fontSize: tstyle.fontSize,
200
+ //@ts-ignore
201
+ fontFamily: tstyle.fontFamily,
202
+ //@ts-ignore
203
+ color: tstyle.color || theme.colors.invert.text,
204
+ }}>
205
+ {props.text}
206
+ </TextView>
207
+ )
208
+ }
209
+ {props.children}
210
+
211
+ </Center>
212
+ {
213
+ props.icon && (
214
+ <View style={{
215
+ position: 'absolute',
216
+ right: 0,
217
+ margin: theme.dimens.space.sm
218
+ }}>
219
+ {props.icon}
220
+ </View>
221
+ )
222
+ }
223
+
224
+ </HBox>
225
+ </TouchableHighlight>
226
+ )
227
+
228
+ }
229
+
230
+
231
+ export function LoadingButton(props: TextProps & TouchableHighlightProps
232
+ & {
233
+ loading: boolean,
234
+ icon?: any,
235
+ text?: string,
236
+ loaderStyle?: 'normal' | 'transparent'
237
+ }) {
238
+ const theme = useContext(ThemeContext)
239
+ const [_loading, _setIsLoading] = useState(props.loading)
240
+ useEffect(() => {
241
+ LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
242
+ if (props.loading != _loading)
243
+ _setIsLoading(props.loading)
244
+ }, [props.loading]);
245
+ let loaderColor = theme.colors.invert.text
246
+ let loaderSize = theme.dimens.icon.md
247
+ let btnBg = theme.colors.accent
248
+ let btnBgPressed = theme.colors.accentLight
249
+
250
+ if (_loading && props.loaderStyle == 'transparent') {
251
+ loaderColor = theme.colors.accent
252
+ btnBg = theme.colors.transparent
253
+ btnBgPressed = theme.colors.transparent
254
+ loaderSize = theme.dimens.icon.lg
255
+ }
256
+ return (
257
+ <ButtonView
258
+ {...props}
259
+ underlayColor={btnBgPressed}
260
+ style={[{
261
+ width: _loading ? '100%' : '100%',
262
+ backgroundColor: btnBg,
263
+ padding: _loading && props.loaderStyle == 'transparent' ?
264
+ theme.dimens.space.sm : theme.dimens.space.md
265
+ }, props.style]}
266
+ icon={_loading ?
267
+ <ActivityIndicator
268
+ size={loaderSize}
269
+ color={loaderColor} />
270
+ : undefined
271
+ }
272
+ text={!_loading ? props.text : undefined} />
273
+ )
274
+ }
275
+
276
+
277
+
278
+ export function PressableView(props: PressableProps) {
279
+
280
+ //@ts-ignore
281
+ return (<Pressable {...props} style={({ pressed }) => [{ opacity: pressed ? 0.7 : 1.0 }, props.style]} />)
282
+ }
package/src/Image.tsx ADDED
@@ -0,0 +1,107 @@
1
+ import { Image, Pressable, ViewProps } from "react-native";
2
+ import FontAwesome from '@expo/vector-icons/FontAwesome';
3
+ import { useContext } from "react";
4
+ import { ThemeContext } from "./ThemeContext";
5
+ import { Center } from "./Box";
6
+ import { Subtitle } from "./Text";
7
+
8
+ export type IconProps = {
9
+ name: any,
10
+ size?: number,
11
+ color?: string
12
+ }
13
+ export function Icon(props: ViewProps & IconProps) {
14
+ const theme = useContext(ThemeContext)
15
+ return (
16
+ <FontAwesome {...props}
17
+ size={props.size || theme.dimens?.icon?.md}
18
+ color={props.color || theme.colors?.text}
19
+ />
20
+ )
21
+ }
22
+
23
+
24
+ /**
25
+ *
26
+ * @param props provide one of iconUrl , iconName , iconText
27
+ * @returns
28
+ */
29
+ export function Avatar(props: ViewProps & {
30
+ onPress?: Function,
31
+ iconUrl?: string,
32
+ iconName?: string,
33
+ iconText?: string,
34
+ iconNameProps?: IconProps,
35
+ style?: any
36
+ }) {
37
+ const theme = useContext(ThemeContext)
38
+ const view = <Center style={[{
39
+ margin: theme.dimens.space.sm,
40
+ overflow: 'hidden',
41
+ borderRadius: 100,
42
+ width: theme.dimens.icon.xl,
43
+ height: theme.dimens.icon.xl,
44
+ borderWidth: theme.dimens.space.xs * 2,
45
+ borderStyle: 'solid',
46
+ borderColor: theme.colors.accentLight,
47
+ backgroundColor: theme.colors.forground,
48
+ }, props.style]}>
49
+ <Center style={{
50
+ width: '110%',
51
+ height: '110%',
52
+ }}>
53
+ {
54
+ (() => {
55
+ if (props.iconUrl)
56
+ return (
57
+ <Image
58
+ style={{
59
+ width: '120%',
60
+ height: '120%',
61
+ }}
62
+ source={{
63
+ uri: props.iconUrl,
64
+ }}
65
+ />)
66
+ if (props.iconName || props.iconNameProps?.name)
67
+ return (
68
+ <Icon
69
+ name={props.iconName || props.iconNameProps?.name}
70
+ {...props.iconNameProps} />
71
+ )
72
+ if (props.iconText)
73
+ return (
74
+ <Subtitle style={{
75
+ color: props.style?.color || theme.colors.accentLight,
76
+ }}>{props.iconText?.substring(0, 2)}</Subtitle>
77
+ )
78
+ })()
79
+ }
80
+ </Center>
81
+ </Center>
82
+ if (props.onPress)
83
+ return (
84
+ <Pressable onPress={() => {
85
+ if (props.onPress)
86
+ props.onPress()
87
+ }}>
88
+ {view}
89
+ </Pressable>
90
+ )
91
+ return view
92
+ }
93
+
94
+
95
+ export function getIcon(input: any) {
96
+ if (input == undefined) {
97
+ return undefined
98
+ }
99
+ if (typeof input == 'string') {
100
+ return (props: IconProps) => {
101
+ return (
102
+ <Icon {...props} name={props.name || input} />
103
+ )
104
+ }
105
+ }
106
+ return input
107
+ }