@modhamanish/rn-mm-template 1.0.3 → 1.0.5
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.
- package/MMTemplate/.eslintrc.js +95 -1
- package/MMTemplate/.husky/pre-commit +2 -0
- package/MMTemplate/.prettierrc.js +2 -0
- package/MMTemplate/App.tsx +27 -21
- package/MMTemplate/README.md +117 -23
- package/MMTemplate/__tests__/App.test.tsx +5 -3
- package/MMTemplate/babel.config.js +24 -1
- package/MMTemplate/index.js +1 -0
- package/MMTemplate/package.json +24 -4
- package/MMTemplate/src/components/AnimationView.tsx +54 -69
- package/MMTemplate/src/components/AppText.tsx +7 -4
- package/MMTemplate/src/components/CustomAlert.tsx +203 -0
- package/MMTemplate/src/components/CustomToast.tsx +2 -1
- package/MMTemplate/src/components/ErrorBoundaryFallback.tsx +127 -0
- package/MMTemplate/src/components/FeatureItem.tsx +8 -6
- package/MMTemplate/src/components/FullScreenContainer.tsx +9 -7
- package/MMTemplate/src/components/InfoCard.tsx +8 -6
- package/MMTemplate/src/components/LanguageSwitcher.tsx +8 -6
- package/MMTemplate/src/components/TextInput.tsx +25 -15
- package/MMTemplate/src/components/ThemeSwitcher.tsx +4 -3
- package/MMTemplate/src/context/AuthContext.tsx +5 -4
- package/MMTemplate/src/context/ThemeContext.tsx +10 -19
- package/MMTemplate/src/locales/en.json +4 -1
- package/MMTemplate/src/locales/hi.json +4 -1
- package/MMTemplate/src/navigation/AppNavigator.tsx +7 -8
- package/MMTemplate/src/navigation/AppStack.tsx +6 -6
- package/MMTemplate/src/navigation/AuthCheck.tsx +11 -10
- package/MMTemplate/src/navigation/AuthStack.tsx +6 -4
- package/MMTemplate/src/navigation/MainTab.tsx +19 -13
- package/MMTemplate/src/screens/AddNoteScreen.tsx +20 -14
- package/MMTemplate/src/screens/HomeScreen.tsx +21 -15
- package/MMTemplate/src/screens/LoginScreen.tsx +21 -18
- package/MMTemplate/src/screens/NoteScreen.tsx +18 -16
- package/MMTemplate/src/screens/ProfileScreen.tsx +16 -13
- package/MMTemplate/src/screens/SettingsScreen.tsx +14 -11
- package/MMTemplate/src/screens/WelcomeScreen.tsx +19 -13
- package/MMTemplate/src/services/axiosInstance.ts +7 -5
- package/MMTemplate/src/services/note.query.ts +7 -5
- package/MMTemplate/src/theme/{Colors.ts → colors.ts} +6 -0
- package/MMTemplate/src/types/components.types.ts +38 -0
- package/MMTemplate/src/types/navigation.types.ts +1 -1
- package/MMTemplate/src/utils/i18n.ts +8 -6
- package/MMTemplate/src/utils/navigationUtils.ts +2 -1
- package/MMTemplate/src/utils/storageHelper.ts +8 -8
- package/MMTemplate/src/utils/utilsHelper.ts +1 -0
- package/MMTemplate/tsconfig.json +27 -0
- package/README.md +37 -1
- package/package.json +1 -1
package/MMTemplate/.eslintrc.js
CHANGED
|
@@ -1,4 +1,98 @@
|
|
|
1
1
|
module.exports = {
|
|
2
2
|
root: true,
|
|
3
|
-
extends:
|
|
3
|
+
extends: [
|
|
4
|
+
'@react-native',
|
|
5
|
+
'plugin:import/recommended',
|
|
6
|
+
'plugin:import/typescript',
|
|
7
|
+
'plugin:prettier/recommended',
|
|
8
|
+
],
|
|
9
|
+
plugins: ['import', 'prettier'],
|
|
10
|
+
settings: {
|
|
11
|
+
'import/resolver': {
|
|
12
|
+
typescript: {
|
|
13
|
+
alwaysTryTypes: true,
|
|
14
|
+
project: './tsconfig.json',
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
rules: {
|
|
19
|
+
'prettier/prettier': 'error',
|
|
20
|
+
'import/order': [
|
|
21
|
+
'error',
|
|
22
|
+
{
|
|
23
|
+
groups: [
|
|
24
|
+
'builtin',
|
|
25
|
+
'external',
|
|
26
|
+
'internal',
|
|
27
|
+
['parent', 'sibling', 'index'],
|
|
28
|
+
'object',
|
|
29
|
+
'type',
|
|
30
|
+
],
|
|
31
|
+
pathGroups: [
|
|
32
|
+
{
|
|
33
|
+
pattern: 'react+(|-native)',
|
|
34
|
+
group: 'external',
|
|
35
|
+
position: 'before',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
pattern: '@src/**',
|
|
39
|
+
group: 'internal',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
pattern: '@assets/**',
|
|
43
|
+
group: 'internal',
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
pattern: '@components/**',
|
|
47
|
+
group: 'internal',
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
pattern: '@context/**',
|
|
51
|
+
group: 'internal',
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
pattern: '@locales/**',
|
|
55
|
+
group: 'internal',
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
pattern: '@mock/**',
|
|
59
|
+
group: 'internal',
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
pattern: '@navigation/**',
|
|
63
|
+
group: 'internal',
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
pattern: '@screens/**',
|
|
67
|
+
group: 'internal',
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
pattern: '@services/**',
|
|
71
|
+
group: 'internal',
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
pattern: '@theme/**',
|
|
75
|
+
group: 'internal',
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
pattern: '@app-types/**',
|
|
79
|
+
group: 'internal',
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
pattern: '@utils/**',
|
|
83
|
+
group: 'internal',
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
pathGroupsExcludedImportTypes: ['react'],
|
|
87
|
+
'newlines-between': 'always',
|
|
88
|
+
alphabetize: {
|
|
89
|
+
order: 'asc',
|
|
90
|
+
caseInsensitive: true,
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
'import/no-unresolved': 'error',
|
|
95
|
+
'no-console': 'error',
|
|
96
|
+
'@typescript-eslint/no-explicit-any': 'error',
|
|
97
|
+
},
|
|
4
98
|
};
|
package/MMTemplate/App.tsx
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
|
3
|
-
import { KeyboardProvider } from 'react-native-keyboard-controller';
|
|
4
|
-
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
5
|
-
|
|
6
|
-
import { ThemeProvider } from './src/context/ThemeContext';
|
|
7
|
-
import AppNavigator from './src/navigation/AppNavigator';
|
|
8
2
|
|
|
3
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
4
|
+
import ErrorBoundary from 'react-native-error-boundary';
|
|
5
|
+
import { KeyboardProvider } from 'react-native-keyboard-controller';
|
|
6
|
+
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
|
9
7
|
import Toast, { ToastConfigParams } from 'react-native-toast-message';
|
|
10
|
-
|
|
11
|
-
import {
|
|
12
|
-
import '
|
|
8
|
+
|
|
9
|
+
import { CustomToast } from '@components/CustomToast';
|
|
10
|
+
import ErrorBoundaryFallback from '@components/ErrorBoundaryFallback';
|
|
11
|
+
import { AuthProvider } from '@context/AuthContext';
|
|
12
|
+
import { ThemeProvider } from '@context/ThemeContext';
|
|
13
|
+
import AppNavigator from '@navigation/AppNavigator';
|
|
14
|
+
import CustomAlert from '@src/components/CustomAlert';
|
|
15
|
+
import '@utils/i18n';
|
|
13
16
|
|
|
14
17
|
const queryClient = new QueryClient({
|
|
15
18
|
defaultOptions: {
|
|
@@ -36,18 +39,21 @@ const toastConfig = {
|
|
|
36
39
|
|
|
37
40
|
const App = () => {
|
|
38
41
|
return (
|
|
39
|
-
<
|
|
40
|
-
<
|
|
41
|
-
<
|
|
42
|
-
<
|
|
43
|
-
<
|
|
44
|
-
<
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
42
|
+
<ErrorBoundary FallbackComponent={ErrorBoundaryFallback}>
|
|
43
|
+
<KeyboardProvider>
|
|
44
|
+
<SafeAreaProvider>
|
|
45
|
+
<ThemeProvider>
|
|
46
|
+
<AuthProvider>
|
|
47
|
+
<QueryClientProvider client={queryClient}>
|
|
48
|
+
<AppNavigator />
|
|
49
|
+
<CustomAlert />
|
|
50
|
+
<Toast config={toastConfig} />
|
|
51
|
+
</QueryClientProvider>
|
|
52
|
+
</AuthProvider>
|
|
53
|
+
</ThemeProvider>
|
|
54
|
+
</SafeAreaProvider>
|
|
55
|
+
</KeyboardProvider>
|
|
56
|
+
</ErrorBoundary>
|
|
51
57
|
);
|
|
52
58
|
};
|
|
53
59
|
|
package/MMTemplate/README.md
CHANGED
|
@@ -6,19 +6,21 @@ Welcome to **MMTemplate**! This is a robust and modern React Native template bui
|
|
|
6
6
|
|
|
7
7
|
This template includes the following key libraries and configurations:
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
9
|
+
- **Core**: React Native (0.83.1), React (19.2.0)
|
|
10
|
+
- **Language**: TypeScript (v5) for static type checking
|
|
11
|
+
- **Navigation**: [React Navigation v7](https://reactnavigation.org/) (Native Stack & Bottom Tabs)
|
|
12
|
+
- **Internationalization**: [react-i18next](https://react.i18next.com/) with multi-language support (English/Hindi)
|
|
13
|
+
- **Storage**: [react-native-mmkv](https://github.com/mrousavy/react-native-mmkv) for high-performance persistence
|
|
14
|
+
- **Forms**: [Formik](https://formik.org/) & [Yup](https://github.com/jquense/yup) for form state management and validation
|
|
15
|
+
- **Animations**: [React Native Reanimated v4](https://docs.swmansion.com/react-native-reanimated/) & Worklets
|
|
16
|
+
- **UI/UX**:
|
|
17
|
+
- **Theme Support**: Light/Dark mode with persistence
|
|
18
|
+
- **Authentication**: Pre-configured login and profile flow
|
|
19
|
+
- [React Native Safe Area Context](https://github.com/th3rdwave/react-native-safe-area-context) for handling safe areas
|
|
20
|
+
- [React Native Keyboard Controller](https://github.com/kirillzyusko/react-native-keyboard-controller) for advanced keyboard handling
|
|
21
|
+
- [React Native Toast Message](https://github.com/calintamas/react-native-toast-message) for in-app notifications
|
|
22
|
+
- **Error Handling**: [react-native-error-boundary](https://github.com/cawfree/react-native-error-boundary) for robust error catching
|
|
23
|
+
- **Testing**: Jest & React Test Renderer
|
|
22
24
|
|
|
23
25
|
## 📂 Project Structure
|
|
24
26
|
|
|
@@ -33,26 +35,112 @@ src/
|
|
|
33
35
|
├── mock/ # Mock data for testing and development
|
|
34
36
|
├── navigation/ # Navigation configuration (Stacks, Stacks, etc.)
|
|
35
37
|
├── screens/ # Screen components (Views)
|
|
38
|
+
├── services/ # Data fetching and API services (React Query)
|
|
36
39
|
├── theme/ # Theme configuration (Colors, Typography, Spacing)
|
|
37
40
|
├── types/ # Global TypeScript types and interfaces
|
|
38
41
|
└── utils/ # Helper functions and utilities
|
|
39
42
|
```
|
|
40
43
|
|
|
44
|
+
### Key Files & Directories
|
|
45
|
+
|
|
46
|
+
| Directory / File | Path | Description |
|
|
47
|
+
| :---------------- | :---------------- | :--------------------------------------------------------------- |
|
|
48
|
+
| **`assets/`** | `src/assets/` | Stores static assets such as images, fonts, and icons. |
|
|
49
|
+
| **`components/`** | `src/components/` | Contains reusable UI components used throughout the application. |
|
|
50
|
+
| **`context/`** | `src/context/` | Holds React Context definitions for global state management. |
|
|
51
|
+
| **`locales/`** | `src/locales/` | Contains translation files for internationalization. |
|
|
52
|
+
| **`mock/`** | `src/mock/` | Stores mock data used for development and testing. |
|
|
53
|
+
| **`navigation/`** | `src/navigation/` | Contains all navigation-related configuration. |
|
|
54
|
+
| **`screens/`** | `src/screens/` | Contains all the screen components (pages) of the application. |
|
|
55
|
+
| **`services/`** | `src/services/` | Data fetching layer using **React Query** and **Axios**. |
|
|
56
|
+
| **`theme/`** | `src/theme/` | Centralized theme configuration (e.g., Colors, Typography). |
|
|
57
|
+
| **`types/`** | `src/types/` | Stores TypeScript type definitions and interfaces. |
|
|
58
|
+
| **`utils/`** | `src/utils/` | Contains utility functions and helper classes. |
|
|
59
|
+
|
|
60
|
+
## 🔐 Authentication Flow
|
|
61
|
+
|
|
62
|
+
MMTemplate comes with a pre-configured authentication flow managed via React Context.
|
|
63
|
+
|
|
64
|
+
### 1. State Management
|
|
65
|
+
|
|
66
|
+
Authentication state is managed globally using `AuthContext` (`src/context/AuthContext.tsx`). You can access user data and authentication methods anywhere in the app:
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
const { user, updateUser, handleLogout, isUserLoggedIn } = useAuth();
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### 2. Navigation Logic
|
|
73
|
+
|
|
74
|
+
- **`AuthCheck`**: The entry point component that checks if a user is already logged in (via `react-native-mmkv` persistence).
|
|
75
|
+
- **`AuthStack`**: contains screens for non-authenticated users (Welcome, Login).
|
|
76
|
+
- **`AppStack`**: contains the main application screens (Home, Profile, Settings).
|
|
77
|
+
|
|
78
|
+
Navigation automatically switches between these stacks based on the `user` state in `AuthContext`.
|
|
79
|
+
|
|
80
|
+
### 3. Mock Credentials
|
|
81
|
+
|
|
82
|
+
For testing purposes, you can use the following credentials (defined in `src/mock/index.ts`):
|
|
83
|
+
|
|
84
|
+
- **Email**: `user@gmail.com`
|
|
85
|
+
- **Password**: `123456`
|
|
86
|
+
|
|
87
|
+
### 4. Storage Persistence
|
|
88
|
+
|
|
89
|
+
User sessions are persisted locally using `react-native-mmkv`, ensuring users stay logged in even after closing the app.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## 🚀 Data Fetching (React Query)
|
|
94
|
+
|
|
95
|
+
MMTemplate uses **TanStack Query (React Query) v5** for server state management and **Axios** for API requests.
|
|
96
|
+
|
|
97
|
+
### 1. Services Structure
|
|
98
|
+
|
|
99
|
+
- **`axiosInstance.ts`**: Configured Axios instance with base URL and interceptors.
|
|
100
|
+
- **`queryKeys.ts`**: Centralized keys for consistency and easy invalidation.
|
|
101
|
+
- **`*.query.ts`**: Feature-specific hooks for fetching and mutating data.
|
|
102
|
+
|
|
103
|
+
### 2. Usage Example
|
|
104
|
+
|
|
105
|
+
To fetch data, use a query hook defined in `src/services`:
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
import { useGetNotesQuery } from '../services/note.query';
|
|
109
|
+
|
|
110
|
+
const { data, isLoading, error } = useGetNotesQuery();
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
To update data, use a mutation hook:
|
|
114
|
+
|
|
115
|
+
```tsx
|
|
116
|
+
import { useAddNoteMutation } from '../services/note.query';
|
|
117
|
+
|
|
118
|
+
const { mutate, isPending } = useAddNoteMutation();
|
|
119
|
+
const handleSave = () => mutate({ title: 'New Note', content: '...' });
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### 3. Global Configuration
|
|
123
|
+
|
|
124
|
+
The `QueryClient` is pre-configured in `App.tsx` with optimized defaults (e.g., `refetchOnWindowFocus: false`).
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
41
128
|
## 🛠 Prerequisites
|
|
42
129
|
|
|
43
130
|
Before you begin, ensure you have the following installed on your machine:
|
|
44
131
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
132
|
+
- [Node.js](https://nodejs.org/) (>= 20)
|
|
133
|
+
- [Watchman](https://facebook.github.io/watchman/)
|
|
134
|
+
- [Ruby](https://www.ruby-lang.org/en/) (for iOS CocoaPods)
|
|
135
|
+
- **Android Studio** (for Android development)
|
|
136
|
+
- **Xcode** (for iOS development, macOS only)
|
|
50
137
|
|
|
51
138
|
> **Note**: For a detailed environment setup guide, refer to the [official React Native documentation](https://reactnative.dev/docs/set-up-your-environment).
|
|
52
139
|
|
|
53
140
|
## 📦 Installation
|
|
54
141
|
|
|
55
142
|
1. **Install Dependencies**:
|
|
143
|
+
|
|
56
144
|
```bash
|
|
57
145
|
yarn install
|
|
58
146
|
# OR
|
|
@@ -70,17 +158,21 @@ Before you begin, ensure you have the following installed on your machine:
|
|
|
70
158
|
## 🏃♂️ Running the App
|
|
71
159
|
|
|
72
160
|
### Start Metro Bundler
|
|
161
|
+
|
|
73
162
|
First, start the Metro bundler in a dedicated terminal:
|
|
163
|
+
|
|
74
164
|
```bash
|
|
75
165
|
yarn start
|
|
76
166
|
```
|
|
77
167
|
|
|
78
168
|
### Run on Android
|
|
169
|
+
|
|
79
170
|
```bash
|
|
80
171
|
yarn android
|
|
81
172
|
```
|
|
82
173
|
|
|
83
174
|
### Run on iOS
|
|
175
|
+
|
|
84
176
|
```bash
|
|
85
177
|
yarn ios
|
|
86
178
|
```
|
|
@@ -88,9 +180,11 @@ yarn ios
|
|
|
88
180
|
## 🔧 Customization
|
|
89
181
|
|
|
90
182
|
### Renaming the App
|
|
183
|
+
|
|
91
184
|
To rename the application from "MMTemplate" to your own project name, you can use `react-native-rename` or manually rename the files.
|
|
92
185
|
|
|
93
186
|
**Using `react-native-rename`:**
|
|
187
|
+
|
|
94
188
|
1. `npx react-native-rename "YourAppName" -b com.yourcompany.yourappname`
|
|
95
189
|
2. Edit `package.json` to update the name.
|
|
96
190
|
3. Delete `ios/Pods` and `node_modules`.
|
|
@@ -98,11 +192,11 @@ To rename the application from "MMTemplate" to your own project name, you can us
|
|
|
98
192
|
|
|
99
193
|
## 📝 Scripts
|
|
100
194
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
195
|
+
- `yarn start`: Starts the Metro Bundler.
|
|
196
|
+
- `yarn android`: Builds and runs the Android app.
|
|
197
|
+
- `yarn ios`: Builds and runs the iOS app.
|
|
198
|
+
- `yarn lint`: Lints the project files.
|
|
199
|
+
- `yarn test`: Runs Jest tests.
|
|
106
200
|
|
|
107
201
|
---
|
|
108
202
|
|
|
@@ -3,11 +3,13 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import React from 'react';
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
import { act, create } from 'react-test-renderer';
|
|
8
|
+
|
|
7
9
|
import App from '../App';
|
|
8
10
|
|
|
9
11
|
test('renders correctly', async () => {
|
|
10
|
-
await
|
|
11
|
-
|
|
12
|
+
await act(() => {
|
|
13
|
+
create(<App />);
|
|
12
14
|
});
|
|
13
15
|
});
|
|
@@ -4,5 +4,28 @@ const workletsPluginOptions = {
|
|
|
4
4
|
|
|
5
5
|
module.exports = {
|
|
6
6
|
presets: ['module:@react-native/babel-preset'],
|
|
7
|
-
plugins: [
|
|
7
|
+
plugins: [
|
|
8
|
+
['react-native-worklets/plugin', workletsPluginOptions],
|
|
9
|
+
[
|
|
10
|
+
'module-resolver',
|
|
11
|
+
{
|
|
12
|
+
root: ['./src'],
|
|
13
|
+
extensions: ['.ios.js', '.android.js', '.js', '.ts', '.tsx', '.json'],
|
|
14
|
+
alias: {
|
|
15
|
+
'@src': './src',
|
|
16
|
+
'@assets': './src/assets',
|
|
17
|
+
'@components': './src/components',
|
|
18
|
+
'@context': './src/context',
|
|
19
|
+
'@locales': './src/locales',
|
|
20
|
+
'@mock': './src/mock',
|
|
21
|
+
'@navigation': './src/navigation',
|
|
22
|
+
'@screens': './src/screens',
|
|
23
|
+
'@services': './src/services',
|
|
24
|
+
'@theme': './src/theme',
|
|
25
|
+
'@app-types': './src/types',
|
|
26
|
+
'@utils': './src/utils',
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
],
|
|
8
31
|
};
|
package/MMTemplate/index.js
CHANGED
package/MMTemplate/package.json
CHANGED
|
@@ -6,8 +6,11 @@
|
|
|
6
6
|
"android": "react-native run-android",
|
|
7
7
|
"ios": "react-native run-ios",
|
|
8
8
|
"lint": "eslint .",
|
|
9
|
-
"
|
|
10
|
-
"
|
|
9
|
+
"lint:fix": "eslint . --fix",
|
|
10
|
+
"format": "prettier --write .",
|
|
11
|
+
"start": "react-native start --reset-cache",
|
|
12
|
+
"test": "jest",
|
|
13
|
+
"prepare": "husky"
|
|
11
14
|
},
|
|
12
15
|
"dependencies": {
|
|
13
16
|
"@react-native/new-app-screen": "0.83.1",
|
|
@@ -21,9 +24,10 @@
|
|
|
21
24
|
"react": "19.2.0",
|
|
22
25
|
"react-i18next": "^16.5.1",
|
|
23
26
|
"react-native": "0.83.1",
|
|
27
|
+
"react-native-error-boundary": "^3.1.0",
|
|
24
28
|
"react-native-keyboard-controller": "^1.20.3",
|
|
25
|
-
"react-native-mmkv": "^4.1.
|
|
26
|
-
"react-native-nitro-modules": "^0.
|
|
29
|
+
"react-native-mmkv": "^4.1.2",
|
|
30
|
+
"react-native-nitro-modules": "^0.33.9",
|
|
27
31
|
"react-native-reanimated": "^4.2.1",
|
|
28
32
|
"react-native-safe-area-context": "^5.6.2",
|
|
29
33
|
"react-native-screens": "^4.19.0",
|
|
@@ -46,13 +50,29 @@
|
|
|
46
50
|
"@types/jest": "^29.5.13",
|
|
47
51
|
"@types/react": "^19.2.0",
|
|
48
52
|
"@types/react-test-renderer": "^19.1.0",
|
|
53
|
+
"babel-plugin-module-resolver": "^5.0.2",
|
|
49
54
|
"eslint": "^8.19.0",
|
|
55
|
+
"eslint-config-prettier": "^10.1.8",
|
|
56
|
+
"eslint-import-resolver-typescript": "^4.4.4",
|
|
57
|
+
"eslint-plugin-import": "^2.32.0",
|
|
58
|
+
"eslint-plugin-prettier": "^5.5.5",
|
|
59
|
+
"husky": "^9.1.7",
|
|
50
60
|
"jest": "^29.6.3",
|
|
61
|
+
"lint-staged": "^16.2.7",
|
|
51
62
|
"prettier": "2.8.8",
|
|
52
63
|
"react-test-renderer": "19.2.0",
|
|
53
64
|
"typescript": "^5.8.3"
|
|
54
65
|
},
|
|
55
66
|
"engines": {
|
|
56
67
|
"node": ">=20"
|
|
68
|
+
},
|
|
69
|
+
"lint-staged": {
|
|
70
|
+
"*.{ts,tsx}": [
|
|
71
|
+
"eslint --fix",
|
|
72
|
+
"prettier --write"
|
|
73
|
+
],
|
|
74
|
+
"*.{js,jsx,json,md}": [
|
|
75
|
+
"prettier --write"
|
|
76
|
+
]
|
|
57
77
|
}
|
|
58
78
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import React, { memo, useEffect } from 'react';
|
|
1
|
+
import React, { FC, memo, useEffect } from 'react';
|
|
2
|
+
|
|
2
3
|
import Animated, {
|
|
3
4
|
Easing,
|
|
4
5
|
useAnimatedStyle,
|
|
@@ -7,62 +8,49 @@ import Animated, {
|
|
|
7
8
|
withTiming,
|
|
8
9
|
} from 'react-native-reanimated';
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
import { AnimationViewProps } from '@src/types/components.types';
|
|
12
|
+
|
|
13
|
+
const AnimationView: FC<AnimationViewProps> = ({
|
|
11
14
|
children,
|
|
12
15
|
animType,
|
|
13
16
|
duration = 500,
|
|
14
17
|
delay = 0,
|
|
15
18
|
rotateValue = 360,
|
|
16
19
|
style,
|
|
17
|
-
}: {
|
|
18
|
-
children: React.ReactNode;
|
|
19
|
-
animType:
|
|
20
|
-
| 'FadeIn'
|
|
21
|
-
| 'FadeOut'
|
|
22
|
-
| 'ZoomIn'
|
|
23
|
-
| 'ZoomOut'
|
|
24
|
-
| 'RotateIn'
|
|
25
|
-
| 'RotateOut'
|
|
26
|
-
| 'SlideInDown';
|
|
27
|
-
duration?: number;
|
|
28
|
-
delay?: number;
|
|
29
|
-
rotateValue?: number;
|
|
30
|
-
style?: any;
|
|
31
20
|
}) => {
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
21
|
+
const getInitialValue = () => {
|
|
22
|
+
switch (animType) {
|
|
23
|
+
case 'SlideInDown':
|
|
24
|
+
return -100;
|
|
25
|
+
case 'FadeOut':
|
|
26
|
+
case 'ZoomOut':
|
|
27
|
+
return 1;
|
|
28
|
+
default:
|
|
29
|
+
return 0;
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
const animValue = useSharedValue(getInitialValue());
|
|
36
33
|
|
|
37
34
|
const animStyle = useAnimatedStyle(() => {
|
|
38
35
|
switch (animType) {
|
|
39
36
|
case 'FadeIn':
|
|
40
|
-
return {
|
|
41
|
-
opacity: fadeAnim.value,
|
|
42
|
-
};
|
|
43
37
|
case 'FadeOut':
|
|
44
38
|
return {
|
|
45
|
-
opacity:
|
|
39
|
+
opacity: animValue.value,
|
|
46
40
|
};
|
|
47
41
|
case 'ZoomIn':
|
|
48
|
-
return {
|
|
49
|
-
transform: [{ scale: zoomAnim.value }],
|
|
50
|
-
};
|
|
51
42
|
case 'ZoomOut':
|
|
52
43
|
return {
|
|
53
|
-
transform: [{ scale:
|
|
44
|
+
transform: [{ scale: animValue.value }],
|
|
54
45
|
};
|
|
55
46
|
case 'RotateIn':
|
|
56
|
-
return {
|
|
57
|
-
transform: [{ rotate: rotateAnim.value + 'deg' }],
|
|
58
|
-
};
|
|
59
47
|
case 'RotateOut':
|
|
60
48
|
return {
|
|
61
|
-
transform: [{ rotate:
|
|
49
|
+
transform: [{ rotate: animValue.value + 'deg' }],
|
|
62
50
|
};
|
|
63
51
|
case 'SlideInDown':
|
|
64
52
|
return {
|
|
65
|
-
transform: [{ translateY:
|
|
53
|
+
transform: [{ translateY: animValue.value }],
|
|
66
54
|
};
|
|
67
55
|
default:
|
|
68
56
|
return {};
|
|
@@ -70,43 +58,40 @@ const AnimationView = ({
|
|
|
70
58
|
});
|
|
71
59
|
|
|
72
60
|
useEffect(() => {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
easing: Easing.elastic(1),
|
|
101
|
-
}),
|
|
102
|
-
);
|
|
103
|
-
} else if (animType === 'SlideInDown') {
|
|
104
|
-
translateAnim.value = withDelay(
|
|
105
|
-
delay,
|
|
106
|
-
withTiming(0, { duration: duration, easing: Easing.elastic(1) }),
|
|
107
|
-
);
|
|
61
|
+
let targetValue = 0;
|
|
62
|
+
let easing = Easing.inOut(Easing.ease);
|
|
63
|
+
|
|
64
|
+
switch (animType) {
|
|
65
|
+
case 'FadeIn':
|
|
66
|
+
targetValue = 1;
|
|
67
|
+
break;
|
|
68
|
+
case 'FadeOut':
|
|
69
|
+
targetValue = 0;
|
|
70
|
+
break;
|
|
71
|
+
case 'ZoomIn':
|
|
72
|
+
targetValue = 1;
|
|
73
|
+
easing = Easing.elastic(1);
|
|
74
|
+
break;
|
|
75
|
+
case 'ZoomOut':
|
|
76
|
+
targetValue = 0;
|
|
77
|
+
easing = Easing.elastic(1);
|
|
78
|
+
break;
|
|
79
|
+
case 'RotateIn':
|
|
80
|
+
case 'RotateOut':
|
|
81
|
+
targetValue = rotateValue;
|
|
82
|
+
easing = Easing.elastic(1);
|
|
83
|
+
break;
|
|
84
|
+
case 'SlideInDown':
|
|
85
|
+
targetValue = 0;
|
|
86
|
+
easing = Easing.elastic(1);
|
|
87
|
+
break;
|
|
108
88
|
}
|
|
109
|
-
|
|
89
|
+
|
|
90
|
+
animValue.value = withDelay(
|
|
91
|
+
delay,
|
|
92
|
+
withTiming(targetValue, { duration, easing }),
|
|
93
|
+
);
|
|
94
|
+
}, [animType, duration, delay, rotateValue, animValue]);
|
|
110
95
|
return <Animated.View style={[animStyle, style]}>{children}</Animated.View>;
|
|
111
96
|
};
|
|
112
97
|
|