@bigbinary/neetoui-rn 0.0.125 → 0.0.128

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 (66) hide show
  1. package/assets/fonts/SFProText-Bold.ttf +0 -0
  2. package/assets/fonts/SFProText-Medium.ttf +0 -0
  3. package/assets/fonts/SFProText-Regular.ttf +0 -0
  4. package/assets/fonts/SFProText-Semibold.ttf +0 -0
  5. package/assets/icons/apple-logo.svg +3 -0
  6. package/assets/icons/error.svg +4 -0
  7. package/assets/icons/google-logo.svg +6 -0
  8. package/assets/icons/info.svg +7 -0
  9. package/assets/icons/success.svg +3 -0
  10. package/assets/icons/warning.svg +5 -0
  11. package/lib/components/Alert.js +1 -1
  12. package/lib/components/Avatar.js +1 -1
  13. package/lib/components/Badge.js +1 -1
  14. package/lib/components/BottomSheet.js +1 -1
  15. package/lib/components/Button.js +1 -1
  16. package/lib/components/Carousel.js +1 -0
  17. package/lib/components/CheckBox.js +1 -1
  18. package/lib/components/Chip.js +1 -1
  19. package/lib/components/Input.js +1 -1
  20. package/lib/components/ListItem.js +1 -0
  21. package/lib/components/MultiSelect.js +1 -1
  22. package/lib/components/OnBoarding.js +1 -0
  23. package/lib/components/OtpInputs.js +1 -1
  24. package/lib/components/Popover.js +1 -1
  25. package/lib/components/RadioButton.js +1 -1
  26. package/lib/components/SearchBar.js +1 -0
  27. package/lib/components/SegmentPicker.js +1 -0
  28. package/lib/components/Select.js +1 -1
  29. package/lib/components/SocialButton.js +1 -0
  30. package/lib/components/Toast.js +1 -1
  31. package/lib/components/ToggleSwitch.js +1 -1
  32. package/lib/components/index.js +1 -1
  33. package/lib/config/toasterConfig.js +1 -1
  34. package/lib/hooks/index.js +1 -1
  35. package/lib/hooks/useDebounce.js +1 -0
  36. package/lib/theme/index.js +1 -1
  37. package/package.json +5 -3
  38. package/src/components/Alert.js +5 -5
  39. package/src/components/Avatar.js +1 -1
  40. package/src/components/Badge.js +1 -1
  41. package/src/components/BottomSheet.js +113 -74
  42. package/src/components/Button.js +152 -61
  43. package/src/components/Carousel.js +112 -0
  44. package/src/components/CheckBox.js +87 -81
  45. package/src/components/Chip.js +1 -1
  46. package/src/components/Input.js +147 -241
  47. package/src/components/ListItem.js +66 -0
  48. package/src/components/MultiSelect.js +6 -6
  49. package/src/components/OnBoarding.js +116 -0
  50. package/src/components/OtpInputs.js +1 -1
  51. package/src/components/Popover.js +13 -1
  52. package/src/components/RadioButton.js +88 -114
  53. package/src/components/SearchBar.js +134 -0
  54. package/src/components/SegmentPicker.js +210 -0
  55. package/src/components/Select.js +5 -5
  56. package/src/components/SocialButton.js +89 -0
  57. package/src/components/Toast.js +85 -30
  58. package/src/components/ToggleSwitch.js +49 -97
  59. package/src/components/Typography.js +2 -2
  60. package/src/components/index.js +6 -0
  61. package/src/config/toasterConfig.js +2 -2
  62. package/src/hooks/index.js +1 -0
  63. package/src/hooks/useDebounce.js +16 -0
  64. package/src/theme/index.js +68 -34
  65. package/assets/fonts/Inter-Bold.ttf +0 -0
  66. package/assets/fonts/Inter-Regular.ttf +0 -0
@@ -1,22 +1,22 @@
1
1
  /* eslint-disable react/display-name */
2
- import React, { useContext, useState } from "react";
2
+ import React, { useCallback, useContext, useEffect, useRef } from "react";
3
3
  import {
4
4
  flexbox,
5
5
  space,
6
6
  border,
7
7
  buttonStyle,
8
8
  typography,
9
+ textStyle,
9
10
  color,
10
11
  layout,
12
+ system,
13
+ position,
11
14
  } from "styled-system";
12
- import Icon from "react-native-remix-icon";
13
- import { Platform } from "react-native";
15
+ import { Animated } from "react-native";
14
16
  import styled, { ThemeContext } from "styled-components/native";
15
- import propTypes from "@styled-system/prop-types";
16
17
  import PropTypes from "prop-types";
17
- import { Typography, Container } from "@components";
18
18
 
19
- export const TextInput = styled.TextInput`
19
+ const TextInput = styled.TextInput`
20
20
  ${flexbox}
21
21
  ${space}
22
22
  ${border}
@@ -33,6 +33,23 @@ const View = styled.View`
33
33
  ${layout}
34
34
  `;
35
35
 
36
+ const Typography = styled.Text`
37
+ ${textStyle}
38
+ ${space}
39
+ ${layout}
40
+ ${flexbox}
41
+ ${typography}
42
+ ${color}
43
+ ${position}
44
+ ${system({
45
+ textDecoration: {
46
+ property: "textDecoration",
47
+ cssProperty: "textDecoration",
48
+ },
49
+ textTransform: { property: "textTransform", cssProperty: "textTransform" },
50
+ })}
51
+ `;
52
+
36
53
  /**
37
54
  *
38
55
  * This component supports below props categories from [styled-system ](/styled-system).
@@ -53,7 +70,7 @@ const View = styled.View`
53
70
  * export default function Main() {
54
71
  * return (
55
72
  * <Container>
56
- * <Input brandLeft="example" error={true} message="example error" />
73
+ * <Input value="Oliver Smith" onChangeHandle={()=>{}} label="Name" />
57
74
  * </Container>
58
75
  * );
59
76
  * }
@@ -61,282 +78,171 @@ const View = styled.View`
61
78
  *
62
79
  */
63
80
 
64
- export const Input = React.forwardRef((props, ref) => {
81
+ const AnimatedLabel = Animated.createAnimatedComponent(Typography);
82
+
83
+ export const Input = props => {
65
84
  const {
66
- label = "",
67
- labelStyles,
68
- containerStyles,
69
- message = "",
70
- error = false,
71
- onFocus,
72
- onBlur,
73
- inline = false,
74
- LeftIcon,
75
- RightIcon,
76
- brandRight,
77
- brandLeft,
78
- brandColor = "font.grey600",
79
- brandBackground = "background.menubackground",
85
+ label,
86
+ value = "",
87
+ onChangeHandle = () => {},
88
+ errorMessage = null,
89
+ PrefixIcon,
90
+ SuffixIcon,
91
+ autoFocus = false,
80
92
  disabled = false,
81
- secureTextEntry = false,
82
- textAlignVertical = "top",
83
- enableFocusStyle = false,
84
93
  ...rest
85
94
  } = props;
86
95
 
87
- const theme = useContext(ThemeContext);
88
- const [isPasswordVisible, setIsPasswordVisible] = useState(false);
89
- const [height, setHeight] = useState(0);
90
- const [isFocus, setIsFocus] = useState(false);
91
- const borderColor = error
92
- ? theme.colors.border.danger
93
- : theme.colors.border.primary;
94
-
95
- const handleFocus = e => {
96
- onFocus && onFocus(e);
97
- setIsFocus(true);
96
+ const colors = useContext(ThemeContext).colors;
97
+ const inputRef = useRef();
98
+ const containerRef = useRef();
99
+ const animatedController = new Animated.Value(0);
100
+
101
+ useEffect(() => {
102
+ if (autoFocus || value) {
103
+ handleLabelAnimation(true);
104
+ } else {
105
+ handleLabelAnimation(false);
106
+ }
107
+ // eslint-disable-next-line react-hooks/exhaustive-deps
108
+ }, []);
109
+
110
+ const handleLabelAnimation = isFocused => {
111
+ Animated.timing(animatedController, {
112
+ toValue: !!isFocused || !!value ? 1 : 0,
113
+ duration: 300,
114
+ useNativeDriver: false,
115
+ }).start();
116
+
117
+ inputRef.current &&
118
+ inputRef.current.setNativeProps({
119
+ style: {
120
+ top: isFocused ? 10 : 0,
121
+ },
122
+ });
98
123
  };
99
124
 
100
- const handleBlur = e => {
101
- onBlur && onBlur(e);
102
- setIsFocus(false);
125
+ const handleStyles = useCallback(isFocused => {
126
+ containerRef.current &&
127
+ containerRef.current.setNativeProps({
128
+ borderColor: errorMessage
129
+ ? colors.border.danger
130
+ : isFocused
131
+ ? colors.border.purple700
132
+ : colors.border.grey300,
133
+ borderWidth: errorMessage || isFocused ? 2 : 1,
134
+ });
135
+ // eslint-disable-next-line react-hooks/exhaustive-deps
136
+ }, []);
137
+
138
+ const labelStyles = {
139
+ fontSize: animatedController.interpolate({
140
+ inputRange: [0, 1],
141
+ outputRange: [18, 14],
142
+ }),
143
+ top: animatedController.interpolate({
144
+ inputRange: [0, 1],
145
+ outputRange: [16, 6],
146
+ }),
103
147
  };
104
148
 
105
- const focusStyles = enableFocusStyle &&
106
- isFocus && {
107
- borderRadius: 4,
108
- borderColor: error
109
- ? "rgba(255, 105, 105, 0.3)"
110
- : theme.colors.border.grey400,
111
- borderWidth: inline ? "0px" : "3px",
112
- borderStyle: "solid",
113
- };
114
-
115
- const disabledStyles = disabled && {
116
- opacity: 0.5,
117
- bg: theme.colors.background.secondary,
149
+ const handleFocusBlur = isFocused => {
150
+ if (!value) handleLabelAnimation(isFocused);
151
+ handleStyles(isFocused);
118
152
  };
119
153
 
120
- const inlineInputStyles = enableFocusStyle &&
121
- isFocus && {
122
- backgroundColor: error
123
- ? theme.colors.border.danger
124
- : theme.colors.border.base,
125
- };
126
-
127
154
  return (
128
- <Container>
129
- {!inline && !!label && (
130
- <LabelText labelStyles={labelStyles} inline={inline} label={label} />
131
- )}
132
- <Container
133
- border={!inline ? "1px" : "0"}
134
- borderColor={borderColor}
135
- borderRadius={2}
136
- {...focusStyles}
137
- {...disabledStyles}
138
- flexDirection={inline ? "row" : "column"}
139
- onBlur={handleBlur}
140
- onFocus={handleFocus}
141
- position="relative"
142
- {...containerStyles}
155
+ <View>
156
+ <View
157
+ borderRadius={5}
158
+ borderWidth={1}
159
+ borderColor={errorMessage ? "border.danger" : "border.grey300"}
160
+ ref={containerRef}
161
+ alignItems="center"
162
+ flexDirection="row"
163
+ justifyContent="space-between"
143
164
  >
144
- {inline && (
145
- <Container alignSelf="flex-end" maxWidth={100}>
146
- <LabelText
147
- labelStyles={labelStyles}
148
- inline={inline}
149
- label={label}
150
- />
151
- </Container>
165
+ {!!PrefixIcon && (
166
+ <View pl={2}>
167
+ <PrefixIcon />
168
+ </View>
152
169
  )}
153
- <Container flexDirection="row" width="100%">
154
- {LeftIcon && (
155
- <Container alignSelf="center" mx="4px">
156
- <LeftIcon />
157
- </Container>
158
- )}
159
- {brandLeft && (
160
- <InputText
161
- text={brandLeft}
162
- brandColor={brandColor}
163
- brandBackground={brandBackground}
164
- />
165
- )}
170
+ <View flex={1} left={10}>
171
+ <AnimatedLabel
172
+ color={disabled ? "font.grey400" : "font.grey600"}
173
+ position="absolute"
174
+ zIndex={1}
175
+ style={labelStyles}
176
+ >
177
+ {label}
178
+ </AnimatedLabel>
166
179
  <TextInput
167
- ref={ref}
168
- flex={1}
169
- {...Platform.select({
170
- ios: {},
171
- android: {
172
- height,
173
- onContentSizeChange: event => {
174
- setHeight(event.nativeEvent.contentSize.height);
175
- },
176
- },
177
- })}
178
- textStyle="subtext"
180
+ ref={inputRef}
181
+ value={value}
182
+ onChangeText={onChangeHandle}
183
+ autoFocus={autoFocus}
179
184
  editable={!disabled}
180
- color={error ? theme.colors.font.danger : theme.colors.font.primary}
181
- secureTextEntry={secureTextEntry && !isPasswordVisible}
182
- textAlignVertical={textAlignVertical}
183
- {...rest}
185
+ onFocus={() => {
186
+ handleFocusBlur(true);
187
+ }}
188
+ onBlur={() => {
189
+ handleFocusBlur(false);
190
+ }}
191
+ color={disabled ? "font.grey500" : "font.grey800"}
192
+ fontSize={18}
193
+ py={3}
194
+ px={0}
195
+ top={0}
196
+ zIndex={2}
197
+ {...rest.inputProps}
184
198
  />
185
-
186
- {brandRight && (
187
- <InputText
188
- text={brandRight}
189
- brandColor={brandColor}
190
- brandBackground={brandBackground}
191
- />
192
- )}
193
-
194
- {RightIcon && (
195
- <Container alignSelf="center" mx="4px">
196
- <RightIcon />
197
- </Container>
198
- )}
199
-
200
- {secureTextEntry && (
201
- <Container justifyContent="center" mx="4px">
202
- <Icon
203
- name={isPasswordVisible ? "eye-line" : "eye-off-line"}
204
- color={theme.colors.background.grey500}
205
- onPress={() => setIsPasswordVisible(!isPasswordVisible)}
206
- />
207
- </Container>
208
- )}
209
- </Container>
210
- </Container>
211
- {inline && (
212
- <View
213
- backgroundColor={theme.colors.border.primary}
214
- height={1}
215
- {...inlineInputStyles}
216
- />
199
+ </View>
200
+ {!!SuffixIcon && (
201
+ <View px={2}>
202
+ <SuffixIcon />
203
+ </View>
204
+ )}
205
+ </View>
206
+ {!!errorMessage && (
207
+ <Typography py={2} color="font.danger">
208
+ {errorMessage}
209
+ </Typography>
217
210
  )}
218
- <ErrorMessage theme={theme} error={error} message={message} />
219
- </Container>
211
+ </View>
220
212
  );
221
- });
222
-
223
- const InputText = ({ text, brandColor, brandBackground }) => (
224
- <Container bg={brandBackground} justifyContent="center" px={2}>
225
- {text && <Typography color={brandColor}>{text}</Typography>}
226
- </Container>
227
- );
228
-
229
- const LabelText = ({ inline, label, labelStyles }) => (
230
- <Typography
231
- numberOfLines={1}
232
- textStyle="subtext"
233
- mb={inline ? "12px" : "7px"}
234
- {...labelStyles}
235
- >
236
- {label}
237
- </Typography>
238
- );
239
-
240
- const ErrorMessage = ({ error, message, theme }) => {
241
- if (error) {
242
- return (
243
- <Typography textStyle="subtext" color={theme.colors.font.danger}>
244
- {message}
245
- </Typography>
246
- );
247
- }
248
- return null;
249
213
  };
250
214
 
251
215
  Input.propTypes = {
252
- ...propTypes.flexbox,
253
- ...propTypes.space,
254
- ...propTypes.border,
255
- ...propTypes.buttonStyle,
256
216
  /**
257
217
  * The text to use for the floating label.
258
218
  */
259
219
  label: PropTypes.string,
260
220
  /**
261
- * To change the styles of label.
221
+ * Holds the current value of the Input.
262
222
  */
263
- labelStyles: PropTypes.object,
223
+ value: PropTypes.string.isRequired,
264
224
  /**
265
- * To change the styles of input text container.
225
+ * Func to set the current value.
266
226
  */
267
- containerStyles: PropTypes.object,
227
+ onChangeHandle: PropTypes.func.isRequired,
268
228
  /**
269
229
  * To display error/info messages
270
230
  */
271
- message: PropTypes.string,
272
- /**
273
- * Whether to style the TextInput with error style.
274
- */
275
- error: PropTypes.bool,
276
- /**
277
- * Changes input layout to inline.
278
- */
279
- inline: PropTypes.bool,
280
- /**
281
- * Display brand to the right of input.
282
- */
283
- brandRight: PropTypes.string,
284
- /**
285
- * Display brand to the left of input.
286
- */
287
- brandLeft: PropTypes.string,
231
+ errorMessage: PropTypes.string,
288
232
  /**
289
233
  * If true, user won't be able to interact with the component.
290
234
  */
291
235
  disabled: PropTypes.bool,
292
- /**
293
- * To change the color of brand text.
294
- */
295
- brandColor: PropTypes.string,
296
- /**
297
- * To change the color of brand text.
298
- */
299
- brandBackground: PropTypes.string,
300
- /**
301
- * To hide and show password and enable secure text entry.
302
- */
303
- secureTextEntry: PropTypes.bool,
304
236
  /**
305
237
  * If true, shows border on focus.
306
238
  */
307
- enableFocusStyle: PropTypes.bool,
239
+ autoFocus: PropTypes.bool,
308
240
  /**
309
- * Display Icon to the left of input.
241
+ * Display Icon component to the left of input.
310
242
  */
311
- LeftIcon: PropTypes.func,
243
+ PrefixIcon: PropTypes.elementType,
312
244
  /**
313
- * Display Icon to the Right of input.
245
+ * Display Icon component to the Right of input.
314
246
  */
315
- RightIcon: PropTypes.func,
316
- children: PropTypes.node,
317
- };
318
-
319
- InputText.propTypes = {
320
- text: PropTypes.string,
321
- borderColor: PropTypes.string,
322
- brandColor: PropTypes.string,
323
- brandBackground: PropTypes.string,
324
- };
325
-
326
- LabelText.propTypes = {
327
- inline: PropTypes.bool,
328
- label: PropTypes.string,
329
- labelStyles: PropTypes.object,
330
- };
331
-
332
- ErrorMessage.propTypes = {
333
- error: PropTypes.bool,
334
- message: PropTypes.string,
335
- };
336
-
337
- TextInput.defaultProps = {
338
- px: 2,
339
- minHeight: 45,
340
- fontFamily: "inter400",
341
- fontSize: "16px",
247
+ SuffixIcon: PropTypes.elementType,
342
248
  };
@@ -0,0 +1,66 @@
1
+ import * as React from "react";
2
+ import PropTypes from "prop-types";
3
+ import propTypes from "@styled-system/prop-types";
4
+
5
+ import { Typography, Container } from "@components";
6
+
7
+ /**
8
+ * ListItems are components that displays a label with different values like string, toggle, button etc.
9
+ *
10
+ * <div class="screenshots">
11
+ * <img src="screenshots/listitem/listItemStyles.png" />
12
+ * </div>
13
+ *
14
+ * ## Usage
15
+ * ```js
16
+ * import * as React from 'react';
17
+ * import { Container, ListItem, Typography } from '@bigbinary/neetoui-rn';
18
+ *
19
+ * export default function Main() {
20
+ * return (
21
+ * <Container>
22
+ * <ListItem
23
+ * LeftComponent={() => <Typography mr={2}>📣</Typography>}
24
+ * label="Organization"
25
+ * value={() => <Typography>Bigbinary</Typography>}
26
+ * />
27
+ * </Container>
28
+ * );
29
+ * }
30
+ * ```
31
+ */
32
+
33
+ export const ListItem = ({ LeftComponent, label, RightComponent, ...rest }) => {
34
+ return (
35
+ <Container
36
+ flexDirection="row"
37
+ bg="background.secondary"
38
+ width="100%"
39
+ px={12}
40
+ height={52}
41
+ borderRadius={6}
42
+ alignItems="center"
43
+ justifyContent="space-between"
44
+ {...rest}
45
+ >
46
+ <Container flexDirection="row" alignItems="center">
47
+ {LeftComponent && <LeftComponent />}
48
+ <Typography color="font.grey800" fontSize="l" fontFamily="sf400">
49
+ {label}
50
+ </Typography>
51
+ </Container>
52
+ <RightComponent />
53
+ </Container>
54
+ );
55
+ };
56
+
57
+ ListItem.propTypes = {
58
+ ...propTypes.flexbox,
59
+ ...propTypes.space,
60
+ ...propTypes.border,
61
+ ...propTypes.color,
62
+ ...propTypes.layout,
63
+ LeftComponent: PropTypes.elementType,
64
+ label: PropTypes.string.isRequired,
65
+ RightComponent: PropTypes.elementType.isRequired,
66
+ };
@@ -37,7 +37,7 @@ const MultiSelectItem = ({
37
37
  {...multiSelectedItemContainerStyle}
38
38
  >
39
39
  <Typography
40
- fontFamily="inter400"
40
+ fontFamily="sf400"
41
41
  fontSize="s"
42
42
  mr={2}
43
43
  maxWidth="90%"
@@ -73,7 +73,7 @@ const DropdownItem = ({
73
73
  {...itemContainerStyle}
74
74
  >
75
75
  <Typography
76
- fontFamily="inter400"
76
+ fontFamily="sf400"
77
77
  fontSize="s"
78
78
  color="font.grey"
79
79
  {...itemLabelStyle}
@@ -261,7 +261,7 @@ export const MultiSelect = ({
261
261
  return (
262
262
  <Container {...containerStyle}>
263
263
  <Typography
264
- fontFamily="inter400"
264
+ fontFamily="sf400"
265
265
  mb={1}
266
266
  fontSize="s"
267
267
  color="font.base"
@@ -286,7 +286,7 @@ export const MultiSelect = ({
286
286
  {...rest}
287
287
  >
288
288
  {!multipleOptionsSelected && (
289
- <Typography fontFamily="inter400" fontSize="s" color="font.grey">
289
+ <Typography fontFamily="sf400" fontSize="s" color="font.grey">
290
290
  {!multipleOptionsSelected && placeholder}
291
291
  </Typography>
292
292
  )}
@@ -362,7 +362,7 @@ export const MultiSelect = ({
362
362
  {...emptyOptionsContainerStyle}
363
363
  >
364
364
  <Typography
365
- fontFamily="inter400"
365
+ fontFamily="sf400"
366
366
  fontSize="s"
367
367
  color="font.grey"
368
368
  {...emptyOptionsLabelStyle}
@@ -387,7 +387,7 @@ export const MultiSelect = ({
387
387
  />
388
388
  ) : (
389
389
  <Typography
390
- fontFamily="inter400"
390
+ fontFamily="sf400"
391
391
  fontSize="s"
392
392
  color="font.grey"
393
393
  {...createSearchedOptionLabelStyle}
@@ -0,0 +1,116 @@
1
+ import React, { useRef, useState } from "react";
2
+ import PropTypes from "prop-types";
3
+
4
+ import { Button, Carousel, Container, Typography } from "@components";
5
+
6
+ /**
7
+ *
8
+ * <div class="screenshots">
9
+ * <img src="screenshots/carousel/carousel.png" />
10
+ * </div>
11
+ *
12
+ * This component supports below props categories from [styled-system ](/styled-system).
13
+ * <ul>
14
+ * <li>flexbox</li>
15
+ * <li>space</li>
16
+ * <li>border</li>
17
+ * <li>layout</li>
18
+ * <li>color</li>
19
+ * <li>buttonStyle</li>
20
+ * </ul>
21
+ *
22
+ * ## Usage
23
+ * ```js
24
+ * import * as React from "react";
25
+ * import { OnBoarding } from "@bigbinary/neetoui-rn";
26
+ *
27
+ * export default function Main() {
28
+ *
29
+ * return (
30
+ * <OnBoarding
31
+ * appLogo={Neeto}
32
+ * slides={[
33
+ * {title: "Welcome to neetoInovice", description: "Enter your daily ...", illustration:""},
34
+ * {title: "", description: "", illustration:""}
35
+ * ]}
36
+ * onComplete={() =>{ console.log("Completed");}}
37
+ * />
38
+ * );
39
+ * }
40
+ * ```
41
+ *
42
+ */
43
+
44
+ export const OnBoarding = ({
45
+ appLogo: AppLogo,
46
+ slides,
47
+ onComplete,
48
+ logoWidth = 150,
49
+ }) => {
50
+ const [activeIndex, setActiveIndex] = useState(0);
51
+ const onBoardingRef = useRef();
52
+
53
+ const handleOnPress = () => {
54
+ if (activeIndex !== slides.length - 1) {
55
+ onBoardingRef.current.snapToNext();
56
+ setActiveIndex(onBoardingRef.current._activeItem);
57
+ } else onComplete();
58
+ };
59
+
60
+ const renderItem = ({ item }) => {
61
+ return (
62
+ <Container flex={1} justifyContent="space-between">
63
+ <Container />
64
+ <Container alignItems="center" mx={24} my={12}>
65
+ {item.illustration}
66
+ </Container>
67
+ <Container alignItems="center" mx={24} my={12}>
68
+ <Typography fontFamily="sf700" fontSize="4xl" color="font.grey800">
69
+ {item.title}
70
+ </Typography>
71
+ <Typography
72
+ fontFamily="sf400"
73
+ fontSize="l"
74
+ color="font.grey500"
75
+ textAlign="center"
76
+ >
77
+ {item.description}
78
+ </Typography>
79
+ </Container>
80
+ </Container>
81
+ );
82
+ };
83
+
84
+ return (
85
+ <Container flex={1} mb={52} mt={27}>
86
+ <Container alignItems="center">
87
+ <AppLogo width={logoWidth} />
88
+ </Container>
89
+
90
+ <Container flex={1} justifyContent="center" alignItems="center">
91
+ <Carousel
92
+ carouselRef={onBoardingRef}
93
+ itemArray={slides}
94
+ onSnapToItem={index => {
95
+ setActiveIndex(index);
96
+ }}
97
+ renderItem={renderItem}
98
+ />
99
+ </Container>
100
+
101
+ <Container mx={24}>
102
+ <Button
103
+ label={activeIndex !== slides.length - 1 ? "Next" : "Get Started"}
104
+ onPress={handleOnPress}
105
+ />
106
+ </Container>
107
+ </Container>
108
+ );
109
+ };
110
+
111
+ OnBoarding.propTypes = {
112
+ appLogo: PropTypes.func.isRequired,
113
+ slides: PropTypes.array.isRequired,
114
+ onComplete: PropTypes.func.isRequired,
115
+ logoWidth: PropTypes.number,
116
+ };