@croacroa/react-native-template 2.0.1 → 3.2.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.
- package/.env.example +5 -0
- package/.eslintrc.js +8 -0
- package/.github/workflows/ci.yml +187 -187
- package/.github/workflows/eas-build.yml +55 -55
- package/.github/workflows/eas-update.yml +50 -50
- package/.github/workflows/npm-publish.yml +57 -0
- package/CHANGELOG.md +195 -106
- package/CONTRIBUTING.md +377 -377
- package/LICENSE +21 -0
- package/README.md +446 -399
- package/__tests__/accessibility/components.test.tsx +285 -0
- package/__tests__/components/Button.test.tsx +2 -4
- package/__tests__/components/__snapshots__/snapshots.test.tsx.snap +512 -0
- package/__tests__/components/snapshots.test.tsx +131 -131
- package/__tests__/helpers/a11y.ts +54 -0
- package/__tests__/hooks/useAnalytics.test.ts +100 -0
- package/__tests__/hooks/useAnimations.test.ts +70 -0
- package/__tests__/hooks/useAuth.test.tsx +71 -28
- package/__tests__/hooks/useMedia.test.ts +318 -0
- package/__tests__/hooks/usePayments.test.tsx +307 -0
- package/__tests__/hooks/usePermission.test.ts +230 -0
- package/__tests__/hooks/useWebSocket.test.ts +329 -0
- package/__tests__/integration/auth-api.test.tsx +224 -227
- package/__tests__/performance/VirtualizedList.perf.test.tsx +385 -362
- package/__tests__/services/api.test.ts +24 -6
- package/app/(auth)/home.tsx +11 -9
- package/app/(auth)/profile.tsx +8 -6
- package/app/(auth)/settings.tsx +11 -9
- package/app/(public)/forgot-password.tsx +25 -15
- package/app/(public)/login.tsx +48 -12
- package/app/(public)/onboarding.tsx +5 -5
- package/app/(public)/register.tsx +24 -15
- package/app/_layout.tsx +6 -3
- package/app.config.ts +27 -2
- package/assets/images/.gitkeep +7 -7
- package/assets/images/adaptive-icon.png +0 -0
- package/assets/images/favicon.png +0 -0
- package/assets/images/icon.png +0 -0
- package/assets/images/notification-icon.png +0 -0
- package/assets/images/splash.png +0 -0
- package/components/ErrorBoundary.tsx +73 -28
- package/components/auth/SocialLoginButtons.tsx +168 -0
- package/components/forms/FormInput.tsx +5 -3
- package/components/onboarding/OnboardingScreen.tsx +370 -370
- package/components/onboarding/index.ts +2 -2
- package/components/providers/AnalyticsProvider.tsx +67 -0
- package/components/providers/SuspenseBoundary.tsx +359 -357
- package/components/providers/index.ts +24 -21
- package/components/ui/AnimatedButton.tsx +1 -9
- package/components/ui/AnimatedList.tsx +98 -0
- package/components/ui/AnimatedScreen.tsx +89 -0
- package/components/ui/Avatar.tsx +319 -316
- package/components/ui/Badge.tsx +416 -416
- package/components/ui/BottomSheet.tsx +307 -307
- package/components/ui/Button.tsx +11 -3
- package/components/ui/Checkbox.tsx +261 -261
- package/components/ui/FeatureGate.tsx +57 -0
- package/components/ui/ForceUpdateScreen.tsx +108 -0
- package/components/ui/ImagePickerButton.tsx +180 -0
- package/components/ui/Input.stories.tsx +2 -10
- package/components/ui/Input.tsx +2 -10
- package/components/ui/OptimizedImage.tsx +369 -369
- package/components/ui/Paywall.tsx +253 -0
- package/components/ui/PermissionGate.tsx +155 -0
- package/components/ui/PurchaseButton.tsx +84 -0
- package/components/ui/Select.tsx +240 -240
- package/components/ui/Skeleton.tsx +3 -1
- package/components/ui/Toast.tsx +427 -0
- package/components/ui/UploadProgress.tsx +189 -0
- package/components/ui/VirtualizedList.tsx +288 -285
- package/components/ui/index.ts +28 -23
- package/constants/config.ts +135 -97
- package/docs/adr/001-state-management.md +79 -79
- package/docs/adr/002-styling-approach.md +130 -130
- package/docs/adr/003-data-fetching.md +155 -155
- package/docs/adr/004-auth-adapter-pattern.md +144 -144
- package/docs/adr/README.md +78 -78
- package/docs/guides/analytics-posthog.md +121 -0
- package/docs/guides/auth-supabase.md +162 -0
- package/docs/guides/feature-flags-launchdarkly.md +150 -0
- package/docs/guides/payments-revenuecat.md +169 -0
- package/docs/plans/2026-02-22-phase6-implementation.md +3222 -0
- package/docs/plans/2026-02-22-phase6-template-completion-design.md +196 -0
- package/docs/plans/2026-02-23-npm-publish-design.md +31 -0
- package/docs/plans/2026-02-23-phase7-polish-documentation-design.md +79 -0
- package/docs/plans/2026-02-23-phase8-additional-features-design.md +136 -0
- package/eas.json +2 -1
- package/hooks/index.ts +70 -27
- package/hooks/useAnimatedEntry.ts +204 -0
- package/hooks/useApi.ts +64 -4
- package/hooks/useAuth.tsx +7 -3
- package/hooks/useBiometrics.ts +295 -295
- package/hooks/useChannel.ts +111 -0
- package/hooks/useDeepLinking.ts +256 -256
- package/hooks/useExperiment.ts +36 -0
- package/hooks/useFeatureFlag.ts +59 -0
- package/hooks/useForceUpdate.ts +91 -0
- package/hooks/useImagePicker.ts +281 -0
- package/hooks/useInAppReview.ts +64 -0
- package/hooks/useMFA.ts +509 -499
- package/hooks/useParallax.ts +142 -0
- package/hooks/usePerformance.ts +434 -434
- package/hooks/usePermission.ts +190 -0
- package/hooks/usePresence.ts +129 -0
- package/hooks/useProducts.ts +36 -0
- package/hooks/usePurchase.ts +103 -0
- package/hooks/useRateLimit.ts +70 -0
- package/hooks/useSubscription.ts +49 -0
- package/hooks/useTrackEvent.ts +52 -0
- package/hooks/useTrackScreen.ts +40 -0
- package/hooks/useUpdates.ts +358 -358
- package/hooks/useUpload.ts +165 -0
- package/hooks/useWebSocket.ts +111 -0
- package/i18n/index.ts +197 -194
- package/i18n/locales/ar.json +170 -101
- package/i18n/locales/de.json +170 -101
- package/i18n/locales/en.json +170 -101
- package/i18n/locales/es.json +170 -101
- package/i18n/locales/fr.json +170 -101
- package/jest.config.js +1 -1
- package/maestro/README.md +113 -113
- package/maestro/config.yaml +35 -35
- package/maestro/flows/login.yaml +62 -62
- package/maestro/flows/mfa-login.yaml +92 -92
- package/maestro/flows/mfa-setup.yaml +86 -86
- package/maestro/flows/navigation.yaml +68 -68
- package/maestro/flows/offline-conflict.yaml +101 -101
- package/maestro/flows/offline-sync.yaml +128 -128
- package/maestro/flows/offline.yaml +60 -60
- package/maestro/flows/register.yaml +94 -94
- package/package.json +188 -175
- package/scripts/generate-placeholders.js +38 -0
- package/services/analytics/adapters/console.ts +50 -0
- package/services/analytics/analytics-adapter.ts +94 -0
- package/services/analytics/types.ts +73 -0
- package/services/analytics.ts +428 -428
- package/services/api.ts +419 -340
- package/services/auth/social/apple.ts +110 -0
- package/services/auth/social/google.ts +159 -0
- package/services/auth/social/social-auth.ts +100 -0
- package/services/auth/social/types.ts +80 -0
- package/services/authAdapter.ts +333 -333
- package/services/backgroundSync.ts +652 -626
- package/services/feature-flags/adapters/mock.ts +108 -0
- package/services/feature-flags/feature-flag-adapter.ts +174 -0
- package/services/feature-flags/types.ts +79 -0
- package/services/force-update.ts +140 -0
- package/services/index.ts +116 -54
- package/services/media/compression.ts +91 -0
- package/services/media/media-picker.ts +151 -0
- package/services/media/media-upload.ts +160 -0
- package/services/payments/adapters/mock.ts +159 -0
- package/services/payments/payment-adapter.ts +118 -0
- package/services/payments/types.ts +131 -0
- package/services/permissions/permission-manager.ts +284 -0
- package/services/permissions/types.ts +104 -0
- package/services/realtime/types.ts +100 -0
- package/services/realtime/websocket-manager.ts +441 -0
- package/services/security.ts +289 -286
- package/services/sentry.ts +4 -4
- package/stores/appStore.ts +9 -0
- package/stores/notificationStore.ts +3 -1
- package/tailwind.config.js +47 -47
- package/tsconfig.json +37 -13
- package/types/user.ts +1 -1
- package/utils/accessibility.ts +446 -446
- package/utils/animations/presets.ts +182 -0
- package/utils/animations/transitions.ts +62 -0
- package/utils/index.ts +63 -52
- package/utils/toast.ts +9 -2
- package/utils/validation.ts +4 -1
- package/utils/withAccessibility.tsx +272 -272
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useSharedValue,
|
|
3
|
+
useAnimatedStyle,
|
|
4
|
+
useAnimatedScrollHandler,
|
|
5
|
+
interpolate,
|
|
6
|
+
Extrapolation,
|
|
7
|
+
} from "react-native-reanimated";
|
|
8
|
+
import type { SharedValue } from "react-native-reanimated";
|
|
9
|
+
|
|
10
|
+
// ============================================================================
|
|
11
|
+
// Types
|
|
12
|
+
// ============================================================================
|
|
13
|
+
|
|
14
|
+
export interface UseParallaxOptions {
|
|
15
|
+
/**
|
|
16
|
+
* Parallax speed factor. 0 = no movement, 1 = moves with scroll.
|
|
17
|
+
* Values between 0 and 1 create a lagging effect; values > 1 amplify.
|
|
18
|
+
* @default 0.5
|
|
19
|
+
*/
|
|
20
|
+
speed?: number;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Height of the parallax header area in pixels.
|
|
24
|
+
* Used for interpolation ranges.
|
|
25
|
+
* @default 250
|
|
26
|
+
*/
|
|
27
|
+
headerHeight?: number;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface UseParallaxReturn {
|
|
31
|
+
/** Shared value tracking the current vertical scroll offset */
|
|
32
|
+
scrollY: SharedValue<number>;
|
|
33
|
+
|
|
34
|
+
/** Animated scroll handler — attach to an Animated.ScrollView's onScroll */
|
|
35
|
+
scrollHandler: ReturnType<typeof useAnimatedScrollHandler>;
|
|
36
|
+
|
|
37
|
+
/** Style with translateY for a parallax background layer */
|
|
38
|
+
parallaxStyle: ReturnType<typeof useAnimatedStyle>;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Style for a header element:
|
|
42
|
+
* - Fades out as the user scrolls up
|
|
43
|
+
* - Scales up on pull-down (overscroll)
|
|
44
|
+
*/
|
|
45
|
+
headerStyle: ReturnType<typeof useAnimatedStyle>;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// ============================================================================
|
|
49
|
+
// Hook Implementation
|
|
50
|
+
// ============================================================================
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Hook for parallax scroll effects.
|
|
54
|
+
*
|
|
55
|
+
* Returns scroll tracking state plus two animated styles:
|
|
56
|
+
* - `parallaxStyle` for a background layer that moves slower than content
|
|
57
|
+
* - `headerStyle` for a header that fades out on scroll and scales on pull-down
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```tsx
|
|
61
|
+
* function ParallaxScreen() {
|
|
62
|
+
* const { scrollHandler, parallaxStyle, headerStyle } = useParallax({
|
|
63
|
+
* speed: 0.5,
|
|
64
|
+
* headerHeight: 300,
|
|
65
|
+
* });
|
|
66
|
+
*
|
|
67
|
+
* return (
|
|
68
|
+
* <View style={{ flex: 1 }}>
|
|
69
|
+
* <Animated.View style={[styles.background, parallaxStyle]}>
|
|
70
|
+
* <Image source={backgroundImage} style={StyleSheet.absoluteFill} />
|
|
71
|
+
* </Animated.View>
|
|
72
|
+
*
|
|
73
|
+
* <Animated.View style={[styles.header, headerStyle]}>
|
|
74
|
+
* <Text>Header Content</Text>
|
|
75
|
+
* </Animated.View>
|
|
76
|
+
*
|
|
77
|
+
* <Animated.ScrollView onScroll={scrollHandler} scrollEventThrottle={16}>
|
|
78
|
+
* {content}
|
|
79
|
+
* </Animated.ScrollView>
|
|
80
|
+
* </View>
|
|
81
|
+
* );
|
|
82
|
+
* }
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export function useParallax(
|
|
86
|
+
options: UseParallaxOptions = {}
|
|
87
|
+
): UseParallaxReturn {
|
|
88
|
+
const { speed = 0.5, headerHeight = 250 } = options;
|
|
89
|
+
|
|
90
|
+
const scrollY = useSharedValue(0);
|
|
91
|
+
|
|
92
|
+
const scrollHandler = useAnimatedScrollHandler({
|
|
93
|
+
onScroll: (event) => {
|
|
94
|
+
scrollY.value = event.contentOffset.y;
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// Background layer: translates at a fraction of scroll speed
|
|
99
|
+
const parallaxStyle = useAnimatedStyle(() => {
|
|
100
|
+
const translateY = interpolate(
|
|
101
|
+
scrollY.value,
|
|
102
|
+
[0, headerHeight],
|
|
103
|
+
[0, headerHeight * speed],
|
|
104
|
+
Extrapolation.CLAMP
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
return {
|
|
108
|
+
transform: [{ translateY }],
|
|
109
|
+
};
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// Header: fades out on scroll up, scales up on pull-down
|
|
113
|
+
const headerStyle = useAnimatedStyle(() => {
|
|
114
|
+
// Fade out as user scrolls past the header
|
|
115
|
+
const opacity = interpolate(
|
|
116
|
+
scrollY.value,
|
|
117
|
+
[0, headerHeight * 0.6],
|
|
118
|
+
[1, 0],
|
|
119
|
+
Extrapolation.CLAMP
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
// Scale up on overscroll (pull-down)
|
|
123
|
+
const scale = interpolate(
|
|
124
|
+
scrollY.value,
|
|
125
|
+
[-headerHeight, 0],
|
|
126
|
+
[1.5, 1],
|
|
127
|
+
Extrapolation.CLAMP
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
opacity,
|
|
132
|
+
transform: [{ scale }],
|
|
133
|
+
};
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
return {
|
|
137
|
+
scrollY,
|
|
138
|
+
scrollHandler,
|
|
139
|
+
parallaxStyle,
|
|
140
|
+
headerStyle,
|
|
141
|
+
};
|
|
142
|
+
}
|