@holper/react-native-holper-storybook 0.6.101 → 0.7.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 (210) hide show
  1. package/.expo/README.md +8 -0
  2. package/.nvmrc +1 -0
  3. package/.prettierignore +5 -0
  4. package/.storybook/index.jsx +11 -0
  5. package/.storybook/main.js +8 -0
  6. package/.storybook/preview.jsx +51 -0
  7. package/.storybook/storybook.requires.js +43 -0
  8. package/.yarn/releases/yarn-4.5.0.cjs +925 -0
  9. package/.yarnrc.yml +3 -0
  10. package/App.jsx +29 -0
  11. package/LICENSE +21 -0
  12. package/{readme.md → README.md} +18 -19
  13. package/app.config.js +77 -0
  14. package/assets/adaptive-icon.png +0 -0
  15. package/assets/favicon.png +0 -0
  16. package/assets/fonts/Poppins-Bold.ttf +0 -0
  17. package/assets/fonts/Poppins-Regular.ttf +0 -0
  18. package/assets/fonts/Poppins-SemiBold.ttf +0 -0
  19. package/assets/icon.png +0 -0
  20. package/assets/splash.png +0 -0
  21. package/babel.config.js +7 -0
  22. package/build.sh +11 -0
  23. package/components/Button/index.tsx +66 -0
  24. package/{lib/components/Button/style.js → components/Button/style.ts} +8 -7
  25. package/components/Card/index.tsx +33 -0
  26. package/{lib/components/Card/style.js → components/Card/style.ts} +5 -4
  27. package/{lib/components/ConfirmationModal/index.js → components/ConfirmationModal/index.tsx} +25 -79
  28. package/{lib/components/ConfirmationModal/style.js → components/ConfirmationModal/style.tsx} +14 -13
  29. package/{lib/components/Container/index.js → components/Container/index.tsx} +7 -28
  30. package/{lib/components/Container/style.js → components/Container/style.ts} +6 -5
  31. package/{lib/components/CustomChatView/index.js → components/CustomChatView/index.tsx} +22 -30
  32. package/{lib/components/CustomChatView/style.js → components/CustomChatView/style.ts} +1 -1
  33. package/components/DeckSwiper/index.tsx +90 -0
  34. package/{lib/components/DeckSwiper/style.js → components/DeckSwiper/style.ts} +13 -12
  35. package/components/DonutCountdown/index.tsx +86 -0
  36. package/components/DonutCountdown/style.ts +8 -0
  37. package/components/FloatingContainer/index.tsx +35 -0
  38. package/{lib/components/FloatingContainer/style.js → components/FloatingContainer/style.ts} +7 -6
  39. package/components/Footer/index.tsx +35 -0
  40. package/{lib/components/Footer/style.js → components/Footer/style.ts} +4 -3
  41. package/components/Header/index.tsx +21 -0
  42. package/{lib/components/Header/style.js → components/Header/style.ts} +4 -3
  43. package/{lib/components/ImagePicker/index.js → components/ImagePicker/index.tsx} +3 -12
  44. package/components/ImageResponsive/index.tsx +24 -0
  45. package/components/ImageResponsive/style.ts +9 -0
  46. package/components/ImageViewer/index.tsx +36 -0
  47. package/{lib/components/ImageViewer/style.js → components/ImageViewer/style.ts} +11 -10
  48. package/{lib/components/Input/index.js → components/Input/index.tsx} +6 -33
  49. package/{lib/components/Input/style.js → components/Input/style.ts} +7 -18
  50. package/{lib/components/InputPin/index.js → components/InputPin/index.tsx} +6 -13
  51. package/{lib/components/InputPin/style.js → components/InputPin/style.ts} +7 -6
  52. package/components/MenuItem/index.tsx +25 -0
  53. package/{lib/components/MenuItem/style.js → components/MenuItem/style.ts} +9 -7
  54. package/{lib/components/NavigationTitle/index.js → components/NavigationTitle/index.tsx} +9 -30
  55. package/{lib/components/NavigationTitle/style.js → components/NavigationTitle/style.ts} +12 -11
  56. package/components/Notification/index.tsx +44 -0
  57. package/{lib/components/Notification/style.js → components/Notification/style.ts} +13 -11
  58. package/components/PreventDoubleClick/index.tsx +28 -0
  59. package/components/Select/index.tsx +51 -0
  60. package/components/Select/style.ts +64 -0
  61. package/{lib/components/SwipeablePanel/index.js → components/SwipeablePanel/index.tsx} +58 -85
  62. package/{lib/components/SwipeablePanel/style.js → components/SwipeablePanel/style.ts} +15 -14
  63. package/components/Switch/index.tsx +30 -0
  64. package/components/TakePicture/confirmPictureModal.tsx +37 -0
  65. package/components/TakePicture/index.tsx +148 -0
  66. package/{lib/components/TakePicture/style.js → components/TakePicture/style.ts} +4 -4
  67. package/components/Text/index.tsx +33 -0
  68. package/{lib/components/Text/style.js → components/Text/style.ts} +4 -2
  69. package/{lib/components/Textarea/index.js → components/Textarea/index.tsx} +5 -24
  70. package/{lib/components/Textarea/style.js → components/Textarea/style.ts} +5 -4
  71. package/components/TimeOutButton/index.tsx +67 -0
  72. package/{lib/components/TimeOutButton/style.js → components/TimeOutButton/style.ts} +4 -3
  73. package/components/Toast/index.tsx +34 -0
  74. package/components/Toast/style.ts +12 -0
  75. package/{lib/components/UploadDocument/index.js → components/UploadDocument/index.tsx} +49 -105
  76. package/{lib/components/UploadDocument/style.js → components/UploadDocument/style.ts} +16 -15
  77. package/components/VirtualKeyboard/index.tsx +75 -0
  78. package/{lib/components/VirtualKeyboard/style.js → components/VirtualKeyboard/style.ts} +9 -8
  79. package/components/index.ts +29 -0
  80. package/{lib/configs/constants.js → configs/constants.ts} +50 -48
  81. package/configs/types.ts +326 -0
  82. package/eas.json +27 -0
  83. package/eslint.config.mjs +205 -0
  84. package/hooks/index.ts +2 -0
  85. package/{lib/hooks/useDebounce.js → hooks/useDebounce.tsx} +6 -4
  86. package/hooks/useLoadFonts.tsx +13 -0
  87. package/index.js +3 -2
  88. package/lib/components/Button/index.tsx +66 -0
  89. package/lib/components/Button/style.ts +111 -0
  90. package/lib/components/Card/index.tsx +33 -0
  91. package/lib/components/Card/style.ts +34 -0
  92. package/lib/components/ConfirmationModal/index.tsx +104 -0
  93. package/lib/components/ConfirmationModal/style.tsx +53 -0
  94. package/lib/components/Container/index.tsx +33 -0
  95. package/lib/components/Container/style.ts +13 -0
  96. package/lib/components/CustomChatView/index.tsx +65 -0
  97. package/lib/components/CustomChatView/style.ts +10 -0
  98. package/lib/components/DeckSwiper/index.tsx +90 -0
  99. package/lib/components/DeckSwiper/style.ts +59 -0
  100. package/lib/components/DonutCountdown/index.tsx +86 -0
  101. package/lib/components/DonutCountdown/style.ts +8 -0
  102. package/lib/components/FloatingContainer/index.tsx +35 -0
  103. package/lib/components/FloatingContainer/style.ts +25 -0
  104. package/lib/components/Footer/index.tsx +35 -0
  105. package/lib/components/Footer/style.ts +40 -0
  106. package/lib/components/Header/index.tsx +21 -0
  107. package/lib/components/Header/style.ts +34 -0
  108. package/lib/components/ImagePicker/index.tsx +18 -0
  109. package/lib/components/ImageResponsive/index.tsx +24 -0
  110. package/lib/components/ImageResponsive/style.ts +9 -0
  111. package/lib/components/ImageViewer/index.tsx +36 -0
  112. package/lib/components/ImageViewer/style.ts +38 -0
  113. package/lib/components/Input/index.tsx +62 -0
  114. package/lib/components/Input/style.ts +91 -0
  115. package/lib/components/InputPin/index.tsx +21 -0
  116. package/lib/components/InputPin/style.ts +22 -0
  117. package/lib/components/MenuItem/index.tsx +25 -0
  118. package/lib/components/MenuItem/style.ts +44 -0
  119. package/lib/components/NavigationTitle/index.tsx +53 -0
  120. package/lib/components/NavigationTitle/style.ts +49 -0
  121. package/lib/components/Notification/index.tsx +44 -0
  122. package/lib/components/Notification/style.ts +50 -0
  123. package/lib/components/PreventDoubleClick/index.tsx +28 -0
  124. package/lib/components/Select/index.tsx +51 -0
  125. package/lib/components/Select/style.ts +64 -0
  126. package/lib/components/SwipeablePanel/index.tsx +208 -0
  127. package/lib/components/SwipeablePanel/style.ts +81 -0
  128. package/lib/components/Switch/index.tsx +30 -0
  129. package/lib/components/TakePicture/confirmPictureModal.tsx +37 -0
  130. package/lib/components/TakePicture/index.tsx +148 -0
  131. package/lib/components/TakePicture/style.ts +95 -0
  132. package/lib/components/Text/index.tsx +33 -0
  133. package/lib/components/Text/style.ts +101 -0
  134. package/lib/components/Textarea/index.tsx +26 -0
  135. package/lib/components/Textarea/style.ts +38 -0
  136. package/lib/components/TimeOutButton/index.tsx +67 -0
  137. package/lib/components/TimeOutButton/style.ts +42 -0
  138. package/lib/components/Toast/index.tsx +34 -0
  139. package/lib/components/Toast/style.ts +12 -0
  140. package/lib/components/UploadDocument/index.tsx +179 -0
  141. package/lib/components/UploadDocument/style.ts +57 -0
  142. package/lib/components/VirtualKeyboard/index.tsx +75 -0
  143. package/lib/components/VirtualKeyboard/style.ts +25 -0
  144. package/lib/components/index.ts +29 -0
  145. package/lib/configs/constants.ts +273 -0
  146. package/lib/configs/types.ts +326 -0
  147. package/lib/hooks/index.ts +2 -0
  148. package/lib/hooks/useDebounce.tsx +24 -0
  149. package/lib/hooks/useLoadFonts.tsx +13 -0
  150. package/lib/index.js +3 -2
  151. package/metro.config.js +11 -0
  152. package/package.json +72 -63
  153. package/prettier.config.mjs +23 -0
  154. package/stories/Button.stories.tsx +181 -0
  155. package/stories/Card.stories.tsx +22 -0
  156. package/stories/Colors.stories.tsx +57 -0
  157. package/stories/ConfirmationModal.stories.tsx +142 -0
  158. package/stories/Container.stories.tsx +105 -0
  159. package/stories/DeckSwiper.stories.tsx +43 -0
  160. package/stories/DonutCountdown.stories.tsx +134 -0
  161. package/stories/FloatingContainer.stories.tsx +139 -0
  162. package/stories/Footer.stories.tsx +65 -0
  163. package/stories/Header.stories.tsx +37 -0
  164. package/stories/ImagePicker.stories.tsx +14 -0
  165. package/stories/ImageResponsive.stories.tsx +18 -0
  166. package/stories/ImageViewer.stories.tsx +24 -0
  167. package/stories/Input.stories.tsx +119 -0
  168. package/stories/InputPin.stories.tsx +40 -0
  169. package/stories/Menu.stories.tsx +53 -0
  170. package/stories/MenuItem.stories.tsx +30 -0
  171. package/stories/NavigationTitle.stories.tsx +51 -0
  172. package/stories/Notification.stories.tsx +58 -0
  173. package/stories/Select.stories.tsx +270 -0
  174. package/stories/SwipeablePanel.stories.tsx +360 -0
  175. package/stories/Switch.stories.tsx +36 -0
  176. package/stories/TakePicture.stories.tsx +59 -0
  177. package/stories/Text.stories.tsx +61 -0
  178. package/stories/Textarea.stories.tsx +48 -0
  179. package/stories/TimeOutButton.stories.tsx +55 -0
  180. package/stories/Toast.stories.tsx +37 -0
  181. package/stories/UploadDocument.stories.tsx +179 -0
  182. package/stories/VirtualKeyboard.stories.tsx +14 -0
  183. package/tsconfig.json +21 -0
  184. package/utilities/ScrollView.tsx +19 -0
  185. package/utilities/index.ts +2 -0
  186. package/utilities/utils.ts +29 -0
  187. package/lib/components/Button/index.js +0 -104
  188. package/lib/components/Card/index.js +0 -49
  189. package/lib/components/DeckSwiper/index.js +0 -118
  190. package/lib/components/FlashMessage/index.js +0 -81
  191. package/lib/components/FloatingContainer/index.js +0 -69
  192. package/lib/components/Footer/index.js +0 -61
  193. package/lib/components/Header/index.js +0 -45
  194. package/lib/components/ImageResponsive/index.js +0 -39
  195. package/lib/components/ImageResponsive/style.js +0 -7
  196. package/lib/components/ImageViewer/index.js +0 -62
  197. package/lib/components/MenuItem/index.js +0 -44
  198. package/lib/components/Notification/index.js +0 -80
  199. package/lib/components/PreventDoubleClick/index.js +0 -21
  200. package/lib/components/Select/index.js +0 -89
  201. package/lib/components/Select/style.js +0 -81
  202. package/lib/components/Switch/index.js +0 -57
  203. package/lib/components/TakePicture/confirmPictureModal.js +0 -64
  204. package/lib/components/TakePicture/index.js +0 -198
  205. package/lib/components/Text/index.js +0 -75
  206. package/lib/components/TimeOutButton/index.js +0 -104
  207. package/lib/components/VirtualKeyboard/index.js +0 -86
  208. package/lib/components/index.js +0 -28
  209. package/lib/configs/loadFonts.js +0 -11
  210. package/lib/hooks/index.js +0 -1
@@ -0,0 +1,205 @@
1
+ import { default as eslintJs } from '@eslint/js';
2
+ import importPlugin from 'eslint-plugin-import';
3
+ import perfectionistPlugin from 'eslint-plugin-perfectionist';
4
+ import reactPlugin from 'eslint-plugin-react';
5
+ import reactHooksPlugin from 'eslint-plugin-react-hooks';
6
+ import unusedImportsPlugin from 'eslint-plugin-unused-imports';
7
+ import globals from 'globals';
8
+ import eslintTs from 'typescript-eslint';
9
+ import { defineConfig, globalIgnores } from 'eslint/config';
10
+
11
+ /**
12
+ * @rules common
13
+ * from 'react', 'eslint-plugin-react-hooks'...
14
+ */
15
+ const commonRules = () => ({
16
+ ...reactHooksPlugin.configs.recommended.rules,
17
+ 'arrow-body-style': [2, 'as-needed', { requireReturnForObjectLiteral: false }],
18
+ 'class-methods-use-this': 0,
19
+ 'consistent-return': 2,
20
+ 'default-case-last': 2,
21
+ 'default-case': [2, { commentPattern: '^no default$' }],
22
+ 'func-names': 1,
23
+ 'jsx-a11y/anchor-is-valid': 0,
24
+ 'jsx-a11y/control-has-associated-label': 0,
25
+ 'lines-around-directive': [2, { before: 'always', after: 'always' }],
26
+ 'no-alert': 0,
27
+ 'no-bitwise': 2,
28
+ 'no-console': 0,
29
+ 'no-constant-condition': 1,
30
+ 'no-param-reassign': 0,
31
+ 'no-promise-executor-return': 0,
32
+ 'no-restricted-exports': 0,
33
+ 'no-restricted-syntax': ['error', 'WithStatement'],
34
+ 'no-underscore-dangle': 0,
35
+ 'no-unused-vars': 0,
36
+ 'no-useless-rename': 1,
37
+ 'object-shorthand': 1,
38
+ 'prefer-destructuring': [1, { object: true, array: false }],
39
+
40
+ camelcase: 0,
41
+ // react
42
+ 'react/display-name': 0,
43
+ 'react/function-component-definition': 0,
44
+ 'react/jsx-boolean-value': 2,
45
+ 'react/jsx-curly-brace-presence': [2, { props: 'never', children: 'never' }],
46
+ 'react/jsx-key': 0,
47
+ 'react/jsx-no-duplicate-props': [1, { ignoreCase: false }],
48
+ 'react/jsx-no-useless-fragment': [1, { allowExpressions: true }],
49
+ 'react/jsx-props-no-spreading': 0,
50
+ 'react/no-array-index-key': 0,
51
+ 'react/no-children-prop': 0,
52
+ 'react/no-unstable-nested-components': [1, { allowAsProps: true }],
53
+ 'react/prop-types': 0,
54
+ 'react/react-in-jsx-scope': 0,
55
+ 'react/require-default-props': 0,
56
+ 'react/self-closing-comp': 2,
57
+ // typescript
58
+ '@typescript-eslint/await-thenable': 0,
59
+ '@typescript-eslint/consistent-type-imports': 1,
60
+ '@typescript-eslint/naming-convention': 0,
61
+ '@typescript-eslint/no-empty-object-type': 0,
62
+ '@typescript-eslint/no-explicit-any': 0,
63
+ '@typescript-eslint/no-floating-promises': 0,
64
+ '@typescript-eslint/no-require-imports': 0,
65
+ '@typescript-eslint/no-shadow': 2,
66
+ '@typescript-eslint/no-unused-vars': [1, { args: 'none' }],
67
+ '@typescript-eslint/no-use-before-define': 0,
68
+ '@typescript-eslint/no-duplicate-enum-values': 0,
69
+ });
70
+
71
+ /**
72
+ * @rules import
73
+ * from 'eslint-plugin-import'.
74
+ */
75
+ const importRules = () => ({
76
+ ...importPlugin.configs.recommended.rules,
77
+ 'import/named': 0,
78
+ 'import/export': 0,
79
+ 'import/default': 0,
80
+ 'import/namespace': 0,
81
+ 'import/no-named-as-default': 0,
82
+ 'import/newline-after-import': 2,
83
+ 'import/no-named-as-default-member': 0,
84
+ 'import/prefer-default-export': 0,
85
+ 'import/no-cycle': [
86
+ 0, // disabled if slow
87
+ { maxDepth: '∞', ignoreExternal: false, allowUnsafeDynamicCyclicDependency: false },
88
+ ],
89
+ });
90
+
91
+ /**
92
+ * @rules unused imports
93
+ * from 'eslint-plugin-unused-imports'.
94
+ */
95
+ const unusedImportsRules = () => ({
96
+ 'unused-imports/no-unused-imports': 0,
97
+ 'unused-imports/no-unused-vars': [
98
+ 0,
99
+ { vars: 'all', varsIgnorePattern: '^_', args: 'after-used', argsIgnorePattern: '^_' },
100
+ ],
101
+ });
102
+
103
+ /**
104
+ * @rules sort or imports/exports
105
+ * from 'eslint-plugin-perfectionist'.
106
+ */
107
+ const sortImportsRules = () => {
108
+ return {
109
+ 'perfectionist/sort-named-imports': [1, { order: 'asc' }],
110
+ 'perfectionist/sort-named-exports': [1, { order: 'asc' }],
111
+ 'perfectionist/sort-exports': [
112
+ 1,
113
+ {
114
+ order: 'asc',
115
+
116
+ groupKind: 'values-first',
117
+ },
118
+ ],
119
+ 'perfectionist/sort-imports': [
120
+ 2,
121
+ {
122
+ order: 'asc',
123
+ ignoreCase: true,
124
+ environment: 'node',
125
+ maxLineLength: undefined,
126
+ newlinesBetween: 'always',
127
+ groups: [
128
+ 'style',
129
+ 'side-effect',
130
+ 'type',
131
+ ['builtin', 'external'],
132
+ 'internal',
133
+ ['parent', 'sibling', 'index'],
134
+ ['parent-type', 'sibling-type', 'index-type'],
135
+ 'object',
136
+ 'unknown',
137
+ ],
138
+ },
139
+ ],
140
+ };
141
+ };
142
+
143
+ /**
144
+ * Custom ESLint configuration.
145
+ */
146
+ export const customConfig = {
147
+ plugins: {
148
+ 'react-hooks': reactHooksPlugin,
149
+ 'unused-imports': unusedImportsPlugin,
150
+ perfectionist: perfectionistPlugin,
151
+ import: importPlugin,
152
+ },
153
+ settings: {
154
+ // https://www.npmjs.com/package/eslint-import-resolver-typescript
155
+ ...importPlugin.configs.typescript.settings,
156
+ 'import/resolver': {
157
+ typescript: { project: './tsconfig.json', alwaysTryTypes: true },
158
+ ...importPlugin.configs.typescript.settings['import/resolver'],
159
+ },
160
+ react: {
161
+ version: 'detect',
162
+ },
163
+ },
164
+ rules: { ...commonRules(), ...importRules(), ...unusedImportsRules(), ...sortImportsRules() },
165
+ };
166
+
167
+ // ----------------------------------------------------------------------
168
+
169
+ const eslintIgnore = globalIgnores([
170
+ '.expo/',
171
+ '.storybook/',
172
+ '.yarn/',
173
+ '**/*.d.ts',
174
+ '**/node_modules',
175
+ 'dist/',
176
+ 'eslint.config.mjs',
177
+ 'prettier.config.mjs',
178
+ ]);
179
+
180
+ export default defineConfig([
181
+ { files: ['**/*.{ts,tsx}'] },
182
+ eslintIgnore,
183
+ {
184
+ languageOptions: {
185
+ globals: { ...globals.browser, ...globals.node },
186
+ parserOptions: {
187
+ ecmaFeatures: { jsx: true },
188
+ project: './tsconfig.json',
189
+ warnOnUnsupportedTypeScriptVersion: true,
190
+ },
191
+ },
192
+ settings: {
193
+ 'import/resolver': {
194
+ node: {
195
+ extensions: ['.js', '.jsx', '.ts', '.tsx'],
196
+ },
197
+ },
198
+ },
199
+ },
200
+ eslintJs.configs.recommended,
201
+ ...eslintTs.configs.recommended,
202
+ reactPlugin.configs.flat.recommended,
203
+ customConfig,
204
+ { files: ['*.tsx'], rules: { '@typescript-eslint/no-floating-promises': 0 } },
205
+ ]);
package/hooks/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { default as useDebounce } from './useDebounce';
2
+ export { default as useLoadFonts } from './useLoadFonts';
@@ -1,8 +1,8 @@
1
1
  import { useEffect, useRef } from 'react';
2
2
 
3
- const useDebounce = (callback, delay) => {
4
- const latestCallback = useRef();
5
- const latestTimeout = useRef();
3
+ const useDebounce = (callback: () => void, delay: number | undefined) => {
4
+ const latestCallback = useRef<() => void>(null);
5
+ const latestTimeout = useRef<ReturnType<typeof setTimeout>>(null);
6
6
 
7
7
  useEffect(() => {
8
8
  latestCallback.current = callback;
@@ -14,7 +14,9 @@ const useDebounce = (callback, delay) => {
14
14
  }
15
15
 
16
16
  latestTimeout.current = setTimeout(() => {
17
- latestCallback.current();
17
+ if (latestCallback.current) {
18
+ latestCallback.current();
19
+ }
18
20
  }, delay);
19
21
  };
20
22
  };
@@ -0,0 +1,13 @@
1
+ import { useFonts } from 'expo-font';
2
+
3
+ const useLoadFonts = () => {
4
+ const [loaded, error] = useFonts({
5
+ poppins_bold: require('../assets/fonts/Poppins-Bold.ttf'),
6
+ poppins_regular: require('../assets/fonts/Poppins-Regular.ttf'),
7
+ poppins_semiBold: require('../assets/fonts/Poppins-SemiBold.ttf'),
8
+ });
9
+
10
+ return { error, loaded };
11
+ };
12
+
13
+ export default useLoadFonts;
package/index.js CHANGED
@@ -1,3 +1,4 @@
1
- export {asyncLoadFont} from './configs/loadFonts';
2
- export {Colors, MapStyle, ConstantsWS, HiringStatus, CouponStatus, NotificationsTypes} from './configs/constants';
3
1
  export * from './components';
2
+ export { Colors, ConstantsWS, CouponStatus, HiringStatus, MapStyle, NotificationsTypes } from './configs/constants';
3
+ export * from './configs/types';
4
+ export { useDebounce, useLoadFonts } from './hooks';
@@ -0,0 +1,66 @@
1
+ import { useEffect, useState } from 'react';
2
+ import { ActivityIndicator, TouchableOpacity } from 'react-native';
3
+
4
+ import { Colors } from '../../configs/constants';
5
+ import withPreventDoubleClick from './../PreventDoubleClick';
6
+ import style from './style';
7
+
8
+ import type { ButtonProps } from '../../configs/types';
9
+
10
+ const Button = ({
11
+ onPress,
12
+ disabled,
13
+ isLoading,
14
+ bordered,
15
+ variant = 'primary',
16
+ size = 'medium',
17
+ noShadow,
18
+ style: customStyle,
19
+ debounceDelay = 0,
20
+ children,
21
+ }: ButtonProps) => {
22
+ const [isDisabled, setIsDisabled] = useState<boolean>(disabled || false);
23
+
24
+ useEffect(() => setIsDisabled(disabled || false), [disabled]);
25
+
26
+ const getSpinnerColor = () => {
27
+ switch (variant) {
28
+ case 'primary':
29
+ case 'inverted':
30
+ case 'error':
31
+ return Colors.white;
32
+ default:
33
+ return Colors.darkblue;
34
+ }
35
+ };
36
+
37
+ const handleTap = () => {
38
+ if (onPress) {
39
+ onPress();
40
+ }
41
+ setIsDisabled(true);
42
+ setTimeout(() => {
43
+ setIsDisabled(false);
44
+ }, debounceDelay);
45
+ };
46
+
47
+ return (
48
+ <TouchableOpacity
49
+ style={[
50
+ style.button,
51
+ style[variant],
52
+ style[size],
53
+ bordered ? style.bordered : {},
54
+ isDisabled ? style.disabled : {},
55
+ noShadow ? style.noShadow : {},
56
+ customStyle,
57
+ ]}
58
+ disabled={isLoading || isDisabled}
59
+ onPress={handleTap}
60
+ >
61
+ {isLoading ? <ActivityIndicator color={getSpinnerColor()} size={28} /> : children}
62
+ </TouchableOpacity>
63
+ );
64
+ };
65
+
66
+ export default withPreventDoubleClick(Button);
@@ -0,0 +1,111 @@
1
+ import { Dimensions, StyleSheet } from 'react-native';
2
+
3
+ import { borderRadius, Colors } from '../../configs/constants';
4
+
5
+ const { width } = Dimensions.get('window');
6
+
7
+ export default StyleSheet.create({
8
+ // Default button shape
9
+ button: {
10
+ height: 50,
11
+ marginVertical: 8,
12
+ paddingVertical: 6,
13
+ paddingHorizontal: 8,
14
+ borderRadius,
15
+ flexDirection: 'row',
16
+ justifyContent: 'center',
17
+ alignItems: 'center',
18
+ borderWidth: 1,
19
+ shadowOffset: { width: 0, height: 4 },
20
+ shadowOpacity: 0.4,
21
+ shadowRadius: 3,
22
+ elevation: 5,
23
+ },
24
+ // Variants
25
+ primary: {
26
+ borderColor: Colors.darkgray,
27
+ backgroundColor: Colors.darkgray,
28
+ shadowColor: Colors.darkgray,
29
+ },
30
+ secondary: {
31
+ borderColor: Colors.lightblue,
32
+ backgroundColor: Colors.white,
33
+ shadowColor: Colors.lightblue,
34
+ },
35
+ dim: {
36
+ borderColor: Colors.dimgray,
37
+ backgroundColor: Colors.dimgray,
38
+ shadowColor: Colors.dimgray,
39
+ },
40
+ light: {
41
+ borderColor: Colors.gray,
42
+ backgroundColor: Colors.gray,
43
+ shadowColor: Colors.gray,
44
+ },
45
+ brightblue: {
46
+ borderColor: Colors.brightblue,
47
+ backgroundColor: Colors.brightblue,
48
+ shadowColor: Colors.brightblue,
49
+ },
50
+ lightgreen: {
51
+ borderColor: Colors.lightgreen,
52
+ backgroundColor: Colors.lightgreen,
53
+ shadowColor: Colors.lightgreen,
54
+ },
55
+ inverted: {
56
+ borderColor: Colors.violet,
57
+ backgroundColor: Colors.violet,
58
+ shadowColor: Colors.violet,
59
+ },
60
+ darkyellow: {
61
+ borderColor: Colors.darkyellow,
62
+ backgroundColor: Colors.darkyellow,
63
+ shadowColor: Colors.darkyellow,
64
+ },
65
+ brightviolet: {
66
+ borderColor: Colors.brightviolet,
67
+ backgroundColor: Colors.brightviolet,
68
+ shadowColor: Colors.brightviolet,
69
+ },
70
+ electricblue: {
71
+ borderColor: Colors.electricblue,
72
+ backgroundColor: Colors.electricblue,
73
+ shadowColor: Colors.electricblue,
74
+ },
75
+ error: {
76
+ borderColor: Colors.red,
77
+ backgroundColor: Colors.red,
78
+ shadowColor: Colors.red,
79
+ },
80
+ // Bordered
81
+ bordered: {
82
+ shadowColor: Colors.transparent,
83
+ backgroundColor: Colors.white,
84
+ elevation: 0,
85
+ },
86
+ // Sizes
87
+ tiny: {
88
+ width: width * 0.25,
89
+ },
90
+ small: {
91
+ width: width * 0.35,
92
+ },
93
+ medium: {
94
+ width: width * 0.6,
95
+ },
96
+ fit: {
97
+ width: '100%',
98
+ },
99
+ icon: {
100
+ width: 55,
101
+ },
102
+ // Disabled
103
+ disabled: {
104
+ opacity: 0.5,
105
+ },
106
+ // NoShadow
107
+ noShadow: {
108
+ shadowColor: Colors.transparent,
109
+ elevation: 0,
110
+ },
111
+ });
@@ -0,0 +1,33 @@
1
+ import type { TouchableOpacityProps, ViewProps } from 'react-native';
2
+
3
+ import { TouchableOpacity, View } from 'react-native';
4
+
5
+ import withPreventDoubleClick from '../PreventDoubleClick';
6
+ import style from './style';
7
+
8
+ import type { CardProps } from '../../configs/types';
9
+
10
+ const TappedTouchableOpacity = withPreventDoubleClick(TouchableOpacity);
11
+
12
+ const Card = (
13
+ { children, isButton, onPress, noShadow, style: customStyle }: CardProps,
14
+ ...props: (TouchableOpacityProps & ViewProps)[]
15
+ ) => (
16
+ <>
17
+ {isButton ? (
18
+ <TappedTouchableOpacity
19
+ onPress={onPress}
20
+ style={[style.card, customStyle, noShadow ? style.noShadow : {}]}
21
+ {...props}
22
+ >
23
+ {children}
24
+ </TappedTouchableOpacity>
25
+ ) : (
26
+ <View style={[style.card, customStyle, noShadow ? style.noShadow : {}]} {...props}>
27
+ {children}
28
+ </View>
29
+ )}
30
+ </>
31
+ );
32
+
33
+ export default Card;
@@ -0,0 +1,34 @@
1
+ import { Dimensions, Platform, StyleSheet } from 'react-native';
2
+
3
+ import { borderRadius, Colors } from '../../configs/constants';
4
+
5
+ const { width } = Dimensions.get('window');
6
+ const isAndroid = Platform.OS === 'android';
7
+
8
+ export default StyleSheet.create({
9
+ card: {
10
+ margin: 8,
11
+ minHeight: 50,
12
+ width: width - 60,
13
+ backgroundColor: Colors.white,
14
+ minWidth: 220,
15
+ paddingVertical: 6,
16
+ paddingHorizontal: 8,
17
+ borderRadius,
18
+ justifyContent: 'center',
19
+ alignItems: 'center',
20
+ alignSelf: 'center',
21
+ borderColor: isAndroid ? Colors.transparent : Colors.lightblue,
22
+ borderWidth: 1,
23
+ shadowOffset: { width: 2, height: 4 },
24
+ shadowOpacity: 0.4,
25
+ shadowRadius: 3,
26
+ shadowColor: Colors.gray,
27
+ elevation: 5,
28
+ },
29
+ noShadow: {
30
+ shadowColor: Colors.transparent,
31
+ elevation: 0,
32
+ borderColor: Colors.lightblue,
33
+ },
34
+ });
@@ -0,0 +1,104 @@
1
+ import { Ionicons } from '@expo/vector-icons';
2
+ import {
3
+ Keyboard,
4
+ KeyboardAvoidingView,
5
+ Modal,
6
+ Platform,
7
+ TouchableOpacity,
8
+ TouchableWithoutFeedback,
9
+ View,
10
+ } from 'react-native';
11
+
12
+ import { Colors } from '../../configs/constants';
13
+ import Button from '../Button';
14
+ import Text from '../Text';
15
+ import style from './style';
16
+
17
+ import type { ConfirmationModalProps } from '../../configs/types';
18
+
19
+ const ConfirmationModal = ({
20
+ visible,
21
+ title,
22
+ confirmText,
23
+ cancelText,
24
+ onConfirm,
25
+ onCancel,
26
+ closeButton,
27
+ onClose,
28
+ alertMode,
29
+ infoMode,
30
+ inverted,
31
+ isPrime,
32
+ children,
33
+ }: ConfirmationModalProps) => (
34
+ <Modal animationType="slide" transparent visible={visible} onRequestClose={() => {}}>
35
+ <KeyboardAvoidingView behavior={Platform.OS === 'ios' ? 'padding' : 'height'}>
36
+ <TouchableWithoutFeedback onPress={() => Keyboard.dismiss()}>
37
+ <View style={style.container}>
38
+ <View style={style.content}>
39
+ <View style={alertMode && !closeButton ? {} : style.title}>
40
+ <Text
41
+ style={alertMode && !closeButton ? {} : style.titleText}
42
+ size="large"
43
+ align={alertMode && !closeButton ? 'center' : 'left'}
44
+ weight="semiBold"
45
+ numberOfLines={1}
46
+ >
47
+ {title}
48
+ </Text>
49
+ {(!alertMode || closeButton) && (
50
+ <TouchableOpacity
51
+ onPress={() => {
52
+ if (onClose) {
53
+ onClose();
54
+ } else {
55
+ if (onCancel) {
56
+ onCancel();
57
+ }
58
+ }
59
+ }}
60
+ style={style.button}
61
+ >
62
+ <Ionicons name="close-outline" size={24} color={Colors.darkblue} />
63
+ </TouchableOpacity>
64
+ )}
65
+ </View>
66
+
67
+ <View style={infoMode ? style.bodyInfo : style.body}>{children}</View>
68
+
69
+ {!infoMode && (
70
+ <>
71
+ {alertMode ? (
72
+ <Button size="fit" variant={inverted ? 'inverted' : 'primary'} onPress={onConfirm}>
73
+ <Text size="large" color={isPrime ? 'lightgold' : 'white'}>
74
+ {confirmText}
75
+ </Text>
76
+ </Button>
77
+ ) : (
78
+ <View style={style.buttons}>
79
+ {onCancel && (
80
+ <Button size="small" bordered variant={inverted ? 'inverted' : 'primary'} onPress={onCancel}>
81
+ <Text size="large">{cancelText}</Text>
82
+ </Button>
83
+ )}
84
+ <Button
85
+ variant={inverted ? 'inverted' : 'primary'}
86
+ size={onCancel ? 'small' : 'fit'}
87
+ onPress={onConfirm}
88
+ >
89
+ <Text size="large" color={isPrime ? 'lightgold' : 'white'}>
90
+ {confirmText}
91
+ </Text>
92
+ </Button>
93
+ </View>
94
+ )}
95
+ </>
96
+ )}
97
+ </View>
98
+ </View>
99
+ </TouchableWithoutFeedback>
100
+ </KeyboardAvoidingView>
101
+ </Modal>
102
+ );
103
+
104
+ export default ConfirmationModal;
@@ -0,0 +1,53 @@
1
+ import { Dimensions, StyleSheet } from 'react-native';
2
+
3
+ import { Colors } from '../../configs/constants';
4
+
5
+ const { width, height } = Dimensions.get('window');
6
+
7
+ export default StyleSheet.create({
8
+ container: {
9
+ backgroundColor: 'rgba(0,0,0,0.3)',
10
+ height,
11
+ justifyContent: 'center',
12
+ alignItems: 'center',
13
+ },
14
+ content: {
15
+ width: width - 60,
16
+ backgroundColor: Colors.white,
17
+ padding: 20,
18
+ borderRadius: 20,
19
+ shadowOffset: { width: 0, height: 4 },
20
+ shadowOpacity: 0.4,
21
+ shadowRadius: 3,
22
+ elevation: 5,
23
+ shadowColor: Colors.gray,
24
+ },
25
+ title: {
26
+ flexDirection: 'row',
27
+ justifyContent: 'space-between',
28
+ alignItems: 'center',
29
+ },
30
+ titleText: {
31
+ width: '90%',
32
+ },
33
+ body: {
34
+ marginTop: 20,
35
+ marginBottom: 35,
36
+ },
37
+ bodyInfo: {
38
+ marginTop: 20,
39
+ },
40
+ buttons: {
41
+ flexDirection: 'row',
42
+ justifyContent: 'space-between',
43
+ alignItems: 'center',
44
+ },
45
+ button: {
46
+ height: 30,
47
+ width: 30,
48
+ borderRadius: 15,
49
+ backgroundColor: Colors.lightblue,
50
+ alignItems: 'center',
51
+ justifyContent: 'center',
52
+ },
53
+ });
@@ -0,0 +1,33 @@
1
+ import { Keyboard, ScrollView, TouchableWithoutFeedback, View } from 'react-native';
2
+ import { SafeAreaView } from 'react-native-safe-area-context';
3
+
4
+ import style from './style';
5
+
6
+ import type { ContainerProps } from '../../configs/types';
7
+
8
+ const Container = ({
9
+ fullScreen = true,
10
+ enableScroll,
11
+ style: customStyle,
12
+ scrollStyle,
13
+ children,
14
+ ...props
15
+ }: ContainerProps) => (
16
+ <SafeAreaView {...props} style={[fullScreen ? style.fullScreen : {}, customStyle]}>
17
+ {enableScroll ? (
18
+ <ScrollView
19
+ contentContainerStyle={scrollStyle}
20
+ showsVerticalScrollIndicator={false}
21
+ keyboardDismissMode="on-drag"
22
+ >
23
+ {children}
24
+ </ScrollView>
25
+ ) : (
26
+ <TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
27
+ <View style={customStyle}>{children}</View>
28
+ </TouchableWithoutFeedback>
29
+ )}
30
+ </SafeAreaView>
31
+ );
32
+
33
+ export default Container;