@croacroa/react-native-template 2.1.0 → 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 -21
- package/README.md +446 -402
- 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 -418
- package/components/ui/UploadProgress.tsx +189 -0
- package/components/ui/VirtualizedList.tsx +288 -285
- package/components/ui/index.ts +28 -30
- 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 -40
- package/hooks/useAnimatedEntry.ts +204 -0
- package/hooks/useApi.ts +5 -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 -375
- 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 -176
- 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,182 @@
|
|
|
1
|
+
import { Easing } from "react-native-reanimated";
|
|
2
|
+
import type {
|
|
3
|
+
WithTimingConfig,
|
|
4
|
+
WithSpringConfig,
|
|
5
|
+
} from "react-native-reanimated";
|
|
6
|
+
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// Types
|
|
9
|
+
// ============================================================================
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Available entry animation types
|
|
13
|
+
*/
|
|
14
|
+
export type EntryAnimation =
|
|
15
|
+
| "fadeIn"
|
|
16
|
+
| "slideUp"
|
|
17
|
+
| "slideDown"
|
|
18
|
+
| "slideLeft"
|
|
19
|
+
| "slideRight"
|
|
20
|
+
| "scale"
|
|
21
|
+
| "none";
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Initial values for an entry animation
|
|
25
|
+
*/
|
|
26
|
+
export interface EntryConfig {
|
|
27
|
+
opacity: number;
|
|
28
|
+
translateX: number;
|
|
29
|
+
translateY: number;
|
|
30
|
+
scale: number;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// ============================================================================
|
|
34
|
+
// Timing Presets
|
|
35
|
+
// ============================================================================
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Timing-based animation presets
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* withTiming(targetValue, TIMING.fast);
|
|
43
|
+
* withTiming(targetValue, TIMING.bounce);
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export const TIMING = {
|
|
47
|
+
/** Quick interactions - 200ms */
|
|
48
|
+
fast: {
|
|
49
|
+
duration: 200,
|
|
50
|
+
easing: Easing.out(Easing.quad),
|
|
51
|
+
},
|
|
52
|
+
/** Standard transitions - 300ms */
|
|
53
|
+
normal: {
|
|
54
|
+
duration: 300,
|
|
55
|
+
easing: Easing.out(Easing.quad),
|
|
56
|
+
},
|
|
57
|
+
/** Deliberate, emphasis animations - 500ms */
|
|
58
|
+
slow: {
|
|
59
|
+
duration: 500,
|
|
60
|
+
easing: Easing.out(Easing.quad),
|
|
61
|
+
},
|
|
62
|
+
/** Playful overshoot effect - 400ms */
|
|
63
|
+
bounce: {
|
|
64
|
+
duration: 400,
|
|
65
|
+
easing: Easing.out(Easing.back(1.5)),
|
|
66
|
+
},
|
|
67
|
+
} satisfies Record<string, WithTimingConfig>;
|
|
68
|
+
|
|
69
|
+
// ============================================================================
|
|
70
|
+
// Spring Presets
|
|
71
|
+
// ============================================================================
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Spring-based animation presets
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```ts
|
|
78
|
+
* withSpring(targetValue, SPRING.gentle);
|
|
79
|
+
* withSpring(targetValue, SPRING.bouncy);
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export const SPRING = {
|
|
83
|
+
/** Soft, slow spring - great for large movements */
|
|
84
|
+
gentle: {
|
|
85
|
+
damping: 20,
|
|
86
|
+
stiffness: 100,
|
|
87
|
+
mass: 1,
|
|
88
|
+
},
|
|
89
|
+
/** Playful spring with visible overshoot */
|
|
90
|
+
bouncy: {
|
|
91
|
+
damping: 8,
|
|
92
|
+
stiffness: 150,
|
|
93
|
+
mass: 0.8,
|
|
94
|
+
},
|
|
95
|
+
/** Rigid, fast spring - minimal overshoot */
|
|
96
|
+
stiff: {
|
|
97
|
+
damping: 20,
|
|
98
|
+
stiffness: 400,
|
|
99
|
+
mass: 0.5,
|
|
100
|
+
},
|
|
101
|
+
/** Quick response with slight bounce */
|
|
102
|
+
snappy: {
|
|
103
|
+
damping: 15,
|
|
104
|
+
stiffness: 300,
|
|
105
|
+
mass: 0.6,
|
|
106
|
+
},
|
|
107
|
+
} satisfies Record<string, WithSpringConfig>;
|
|
108
|
+
|
|
109
|
+
// ============================================================================
|
|
110
|
+
// Entry Configs
|
|
111
|
+
// ============================================================================
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Initial transform values for each entry animation type.
|
|
115
|
+
* The animation interpolates from these values (progress=0) to the
|
|
116
|
+
* identity transform (progress=1): opacity 1, translate 0, scale 1.
|
|
117
|
+
*/
|
|
118
|
+
export const ENTRY_CONFIGS: Record<EntryAnimation, EntryConfig> = {
|
|
119
|
+
fadeIn: {
|
|
120
|
+
opacity: 0,
|
|
121
|
+
translateX: 0,
|
|
122
|
+
translateY: 0,
|
|
123
|
+
scale: 1,
|
|
124
|
+
},
|
|
125
|
+
slideUp: {
|
|
126
|
+
opacity: 0,
|
|
127
|
+
translateX: 0,
|
|
128
|
+
translateY: 30,
|
|
129
|
+
scale: 1,
|
|
130
|
+
},
|
|
131
|
+
slideDown: {
|
|
132
|
+
opacity: 0,
|
|
133
|
+
translateX: 0,
|
|
134
|
+
translateY: -30,
|
|
135
|
+
scale: 1,
|
|
136
|
+
},
|
|
137
|
+
slideLeft: {
|
|
138
|
+
opacity: 0,
|
|
139
|
+
translateX: 30,
|
|
140
|
+
translateY: 0,
|
|
141
|
+
scale: 1,
|
|
142
|
+
},
|
|
143
|
+
slideRight: {
|
|
144
|
+
opacity: 0,
|
|
145
|
+
translateX: -30,
|
|
146
|
+
translateY: 0,
|
|
147
|
+
scale: 1,
|
|
148
|
+
},
|
|
149
|
+
scale: {
|
|
150
|
+
opacity: 0,
|
|
151
|
+
translateX: 0,
|
|
152
|
+
translateY: 0,
|
|
153
|
+
scale: 0.85,
|
|
154
|
+
},
|
|
155
|
+
none: {
|
|
156
|
+
opacity: 1,
|
|
157
|
+
translateX: 0,
|
|
158
|
+
translateY: 0,
|
|
159
|
+
scale: 1,
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
// ============================================================================
|
|
164
|
+
// Helpers
|
|
165
|
+
// ============================================================================
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Calculate stagger delay for a list item at the given index.
|
|
169
|
+
*
|
|
170
|
+
* @param index - The item index in the list
|
|
171
|
+
* @param baseDelay - Delay between each item in ms (default 50)
|
|
172
|
+
* @returns Total delay in ms for this item
|
|
173
|
+
*
|
|
174
|
+
* @example
|
|
175
|
+
* ```ts
|
|
176
|
+
* // Stagger 5 items, each 80ms apart
|
|
177
|
+
* items.map((item, i) => staggerDelay(i, 80)); // [0, 80, 160, 240, 320]
|
|
178
|
+
* ```
|
|
179
|
+
*/
|
|
180
|
+
export function staggerDelay(index: number, baseDelay: number = 50): number {
|
|
181
|
+
return index * baseDelay;
|
|
182
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { NativeStackNavigationOptions } from "@react-navigation/native-stack";
|
|
2
|
+
|
|
3
|
+
// ============================================================================
|
|
4
|
+
// Screen Transition Presets
|
|
5
|
+
// ============================================================================
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Pre-configured screen transition options for Expo Router / React Navigation.
|
|
9
|
+
*
|
|
10
|
+
* Apply to individual `Stack.Screen` components or to `screenOptions` on a
|
|
11
|
+
* `Stack` navigator.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* // Single screen
|
|
16
|
+
* <Stack.Screen name="details" options={screenTransitions.slide} />
|
|
17
|
+
*
|
|
18
|
+
* // All screens in a navigator
|
|
19
|
+
* <Stack screenOptions={screenTransitions.fade}>
|
|
20
|
+
* ...
|
|
21
|
+
* </Stack>
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export const screenTransitions = {
|
|
25
|
+
/** Standard platform slide (iOS: slide from right, Android: slide from bottom) */
|
|
26
|
+
slide: {
|
|
27
|
+
animation: "slide_from_right",
|
|
28
|
+
} satisfies NativeStackNavigationOptions,
|
|
29
|
+
|
|
30
|
+
/** Cross-fade between screens */
|
|
31
|
+
fade: {
|
|
32
|
+
animation: "fade",
|
|
33
|
+
} satisfies NativeStackNavigationOptions,
|
|
34
|
+
|
|
35
|
+
/** Modal presentation (slides up from bottom with card styling) */
|
|
36
|
+
modal: {
|
|
37
|
+
animation: "slide_from_bottom",
|
|
38
|
+
presentation: "modal",
|
|
39
|
+
} satisfies NativeStackNavigationOptions,
|
|
40
|
+
|
|
41
|
+
/** Full-screen modal (no card inset) */
|
|
42
|
+
fullScreenModal: {
|
|
43
|
+
animation: "slide_from_bottom",
|
|
44
|
+
presentation: "fullScreenModal",
|
|
45
|
+
} satisfies NativeStackNavigationOptions,
|
|
46
|
+
|
|
47
|
+
/** Transparent modal (overlay on top of current screen) */
|
|
48
|
+
transparentModal: {
|
|
49
|
+
animation: "fade",
|
|
50
|
+
presentation: "transparentModal",
|
|
51
|
+
} satisfies NativeStackNavigationOptions,
|
|
52
|
+
|
|
53
|
+
/** No animation at all */
|
|
54
|
+
none: {
|
|
55
|
+
animation: "none",
|
|
56
|
+
} satisfies NativeStackNavigationOptions,
|
|
57
|
+
} as const;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Type of available screen transition keys
|
|
61
|
+
*/
|
|
62
|
+
export type ScreenTransitionName = keyof typeof screenTransitions;
|
package/utils/index.ts
CHANGED
|
@@ -1,52 +1,63 @@
|
|
|
1
|
-
export { cn } from "./cn";
|
|
2
|
-
export { toast, handleApiError } from "./toast";
|
|
3
|
-
export {
|
|
4
|
-
emailSchema,
|
|
5
|
-
passwordSchema,
|
|
6
|
-
nameSchema,
|
|
7
|
-
loginSchema,
|
|
8
|
-
registerSchema,
|
|
9
|
-
forgotPasswordSchema,
|
|
10
|
-
changePasswordSchema,
|
|
11
|
-
profileSchema,
|
|
12
|
-
} from "./validation";
|
|
13
|
-
export type {
|
|
14
|
-
LoginFormData,
|
|
15
|
-
RegisterFormData,
|
|
16
|
-
ForgotPasswordFormData,
|
|
17
|
-
ChangePasswordFormData,
|
|
18
|
-
ProfileFormData,
|
|
19
|
-
} from "./validation";
|
|
20
|
-
|
|
21
|
-
// Accessibility utilities
|
|
22
|
-
export {
|
|
23
|
-
buttonA11y,
|
|
24
|
-
linkA11y,
|
|
25
|
-
inputA11y,
|
|
26
|
-
toggleA11y,
|
|
27
|
-
headerA11y,
|
|
28
|
-
imageA11y,
|
|
29
|
-
listItemA11y,
|
|
30
|
-
progressA11y,
|
|
31
|
-
tabA11y,
|
|
32
|
-
alertA11y,
|
|
33
|
-
useScreenReader,
|
|
34
|
-
useReduceMotion,
|
|
35
|
-
useBoldText,
|
|
36
|
-
useAccessibilityPreferences,
|
|
37
|
-
announce,
|
|
38
|
-
setAccessibilityFocus,
|
|
39
|
-
formatPriceA11y,
|
|
40
|
-
formatDateA11y,
|
|
41
|
-
formatDurationA11y,
|
|
42
|
-
} from "./accessibility";
|
|
43
|
-
export type { AccessibilityProps } from "./accessibility";
|
|
44
|
-
|
|
45
|
-
// Accessibility enforcement HOC and utilities
|
|
46
|
-
export {
|
|
47
|
-
withAccessibility,
|
|
48
|
-
useAccessibilityValidation,
|
|
49
|
-
createA11yProps,
|
|
50
|
-
A11yContext,
|
|
51
|
-
auditAccessibility,
|
|
52
|
-
} from "./withAccessibility";
|
|
1
|
+
export { cn } from "./cn";
|
|
2
|
+
export { toast, handleApiError } from "./toast";
|
|
3
|
+
export {
|
|
4
|
+
emailSchema,
|
|
5
|
+
passwordSchema,
|
|
6
|
+
nameSchema,
|
|
7
|
+
loginSchema,
|
|
8
|
+
registerSchema,
|
|
9
|
+
forgotPasswordSchema,
|
|
10
|
+
changePasswordSchema,
|
|
11
|
+
profileSchema,
|
|
12
|
+
} from "./validation";
|
|
13
|
+
export type {
|
|
14
|
+
LoginFormData,
|
|
15
|
+
RegisterFormData,
|
|
16
|
+
ForgotPasswordFormData,
|
|
17
|
+
ChangePasswordFormData,
|
|
18
|
+
ProfileFormData,
|
|
19
|
+
} from "./validation";
|
|
20
|
+
|
|
21
|
+
// Accessibility utilities
|
|
22
|
+
export {
|
|
23
|
+
buttonA11y,
|
|
24
|
+
linkA11y,
|
|
25
|
+
inputA11y,
|
|
26
|
+
toggleA11y,
|
|
27
|
+
headerA11y,
|
|
28
|
+
imageA11y,
|
|
29
|
+
listItemA11y,
|
|
30
|
+
progressA11y,
|
|
31
|
+
tabA11y,
|
|
32
|
+
alertA11y,
|
|
33
|
+
useScreenReader,
|
|
34
|
+
useReduceMotion,
|
|
35
|
+
useBoldText,
|
|
36
|
+
useAccessibilityPreferences,
|
|
37
|
+
announce,
|
|
38
|
+
setAccessibilityFocus,
|
|
39
|
+
formatPriceA11y,
|
|
40
|
+
formatDateA11y,
|
|
41
|
+
formatDurationA11y,
|
|
42
|
+
} from "./accessibility";
|
|
43
|
+
export type { AccessibilityProps } from "./accessibility";
|
|
44
|
+
|
|
45
|
+
// Accessibility enforcement HOC and utilities
|
|
46
|
+
export {
|
|
47
|
+
withAccessibility,
|
|
48
|
+
useAccessibilityValidation,
|
|
49
|
+
createA11yProps,
|
|
50
|
+
A11yContext,
|
|
51
|
+
auditAccessibility,
|
|
52
|
+
} from "./withAccessibility";
|
|
53
|
+
|
|
54
|
+
// Animation presets and transitions
|
|
55
|
+
export {
|
|
56
|
+
TIMING,
|
|
57
|
+
SPRING,
|
|
58
|
+
ENTRY_CONFIGS,
|
|
59
|
+
staggerDelay,
|
|
60
|
+
} from "./animations/presets";
|
|
61
|
+
export type { EntryAnimation, EntryConfig } from "./animations/presets";
|
|
62
|
+
export { screenTransitions } from "./animations/transitions";
|
|
63
|
+
export type { ScreenTransitionName } from "./animations/transitions";
|
package/utils/toast.ts
CHANGED
|
@@ -70,7 +70,11 @@ export const toast = {
|
|
|
70
70
|
/**
|
|
71
71
|
* Show a native alert dialog
|
|
72
72
|
*/
|
|
73
|
-
alert: (
|
|
73
|
+
alert: (
|
|
74
|
+
title: string,
|
|
75
|
+
message?: string,
|
|
76
|
+
preset?: "done" | "error" | "heart"
|
|
77
|
+
) => {
|
|
74
78
|
Burnt.alert({
|
|
75
79
|
title,
|
|
76
80
|
message,
|
|
@@ -89,7 +93,10 @@ export const toast = {
|
|
|
89
93
|
/**
|
|
90
94
|
* Handle API errors and show appropriate toast
|
|
91
95
|
*/
|
|
92
|
-
export const handleApiError = (
|
|
96
|
+
export const handleApiError = (
|
|
97
|
+
error: unknown,
|
|
98
|
+
fallbackMessage = "Something went wrong"
|
|
99
|
+
) => {
|
|
93
100
|
if (error instanceof Error) {
|
|
94
101
|
// Check for network errors
|
|
95
102
|
if (error.message.includes("Network") || error.message.includes("fetch")) {
|
package/utils/validation.ts
CHANGED
|
@@ -13,7 +13,10 @@ export const passwordSchema = z
|
|
|
13
13
|
.regex(/[A-Z]/, "Password must contain at least one uppercase letter")
|
|
14
14
|
.regex(/[a-z]/, "Password must contain at least one lowercase letter")
|
|
15
15
|
.regex(/[0-9]/, "Password must contain at least one number")
|
|
16
|
-
.regex(
|
|
16
|
+
.regex(
|
|
17
|
+
/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/,
|
|
18
|
+
"Password must contain at least one special character"
|
|
19
|
+
);
|
|
17
20
|
|
|
18
21
|
export const nameSchema = z
|
|
19
22
|
.string()
|