@umituz/react-native-localization 1.0.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 (76) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +292 -0
  3. package/lib/domain/repositories/ILocalizationRepository.d.ts +17 -0
  4. package/lib/domain/repositories/ILocalizationRepository.d.ts.map +1 -0
  5. package/lib/domain/repositories/ILocalizationRepository.js +6 -0
  6. package/lib/domain/repositories/ILocalizationRepository.js.map +1 -0
  7. package/lib/index.d.ts +10 -0
  8. package/lib/index.d.ts.map +1 -0
  9. package/lib/index.js +12 -0
  10. package/lib/index.js.map +1 -0
  11. package/lib/infrastructure/components/LocalizationProvider.d.ts +11 -0
  12. package/lib/infrastructure/components/LocalizationProvider.d.ts.map +1 -0
  13. package/lib/infrastructure/components/LocalizationProvider.js +14 -0
  14. package/lib/infrastructure/components/LocalizationProvider.js.map +1 -0
  15. package/lib/infrastructure/config/i18n.d.ts +7 -0
  16. package/lib/infrastructure/config/i18n.d.ts.map +1 -0
  17. package/lib/infrastructure/config/i18n.js +49 -0
  18. package/lib/infrastructure/config/i18n.js.map +1 -0
  19. package/lib/infrastructure/config/languages.d.ts +34 -0
  20. package/lib/infrastructure/config/languages.d.ts.map +1 -0
  21. package/lib/infrastructure/config/languages.js +200 -0
  22. package/lib/infrastructure/config/languages.js.map +1 -0
  23. package/lib/infrastructure/config/languagesData.d.ts +7 -0
  24. package/lib/infrastructure/config/languagesData.d.ts.map +1 -0
  25. package/lib/infrastructure/config/languagesData.js +36 -0
  26. package/lib/infrastructure/config/languagesData.js.map +1 -0
  27. package/lib/infrastructure/locales/en-US/animation.json +30 -0
  28. package/lib/infrastructure/locales/en-US/audio.json +56 -0
  29. package/lib/infrastructure/locales/en-US/datetime.json +140 -0
  30. package/lib/infrastructure/locales/en-US/emoji.json +29 -0
  31. package/lib/infrastructure/locales/en-US/errors.json +43 -0
  32. package/lib/infrastructure/locales/en-US/forms.json +38 -0
  33. package/lib/infrastructure/locales/en-US/general.json +56 -0
  34. package/lib/infrastructure/locales/en-US/icons.json +34 -0
  35. package/lib/infrastructure/locales/en-US/index.d.ts +757 -0
  36. package/lib/infrastructure/locales/en-US/index.d.ts.map +1 -0
  37. package/lib/infrastructure/locales/en-US/index.js +35 -0
  38. package/lib/infrastructure/locales/en-US/index.js.map +1 -0
  39. package/lib/infrastructure/locales/en-US/location.json +49 -0
  40. package/lib/infrastructure/locales/en-US/media.json +49 -0
  41. package/lib/infrastructure/locales/en-US/navigation.json +52 -0
  42. package/lib/infrastructure/locales/en-US/onboarding.json +76 -0
  43. package/lib/infrastructure/locales/en-US/settings.json +65 -0
  44. package/lib/infrastructure/locales/en-US/toast.json +38 -0
  45. package/lib/infrastructure/storage/AsyncStorageWrapper.d.ts +12 -0
  46. package/lib/infrastructure/storage/AsyncStorageWrapper.d.ts.map +1 -0
  47. package/lib/infrastructure/storage/AsyncStorageWrapper.js +29 -0
  48. package/lib/infrastructure/storage/AsyncStorageWrapper.js.map +1 -0
  49. package/lib/infrastructure/storage/LocalizationStore.d.ts +30 -0
  50. package/lib/infrastructure/storage/LocalizationStore.d.ts.map +1 -0
  51. package/lib/infrastructure/storage/LocalizationStore.js +90 -0
  52. package/lib/infrastructure/storage/LocalizationStore.js.map +1 -0
  53. package/package.json +64 -0
  54. package/src/domain/repositories/ILocalizationRepository.ts +18 -0
  55. package/src/index.ts +24 -0
  56. package/src/infrastructure/components/LocalizationProvider.tsx +21 -0
  57. package/src/infrastructure/config/i18n.ts +57 -0
  58. package/src/infrastructure/config/languages.ts +245 -0
  59. package/src/infrastructure/config/languagesData.ts +38 -0
  60. package/src/infrastructure/locales/en-US/animation.json +30 -0
  61. package/src/infrastructure/locales/en-US/audio.json +56 -0
  62. package/src/infrastructure/locales/en-US/datetime.json +140 -0
  63. package/src/infrastructure/locales/en-US/emoji.json +29 -0
  64. package/src/infrastructure/locales/en-US/errors.json +43 -0
  65. package/src/infrastructure/locales/en-US/forms.json +38 -0
  66. package/src/infrastructure/locales/en-US/general.json +56 -0
  67. package/src/infrastructure/locales/en-US/icons.json +34 -0
  68. package/src/infrastructure/locales/en-US/index.ts +36 -0
  69. package/src/infrastructure/locales/en-US/location.json +49 -0
  70. package/src/infrastructure/locales/en-US/media.json +49 -0
  71. package/src/infrastructure/locales/en-US/navigation.json +52 -0
  72. package/src/infrastructure/locales/en-US/onboarding.json +76 -0
  73. package/src/infrastructure/locales/en-US/settings.json +65 -0
  74. package/src/infrastructure/locales/en-US/toast.json +38 -0
  75. package/src/infrastructure/storage/AsyncStorageWrapper.ts +30 -0
  76. package/src/infrastructure/storage/LocalizationStore.ts +118 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/infrastructure/locales/en-US/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiBH,wBAeE"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * en-US translation modules
3
+ * All common translations for English (US)
4
+ */
5
+ import animation from './animation.json';
6
+ import audio from './audio.json';
7
+ import datetime from './datetime.json';
8
+ import emoji from './emoji.json';
9
+ import errors from './errors.json';
10
+ import forms from './forms.json';
11
+ import general from './general.json';
12
+ import icons from './icons.json';
13
+ import location from './location.json';
14
+ import media from './media.json';
15
+ import navigation from './navigation.json';
16
+ import onboarding from './onboarding.json';
17
+ import settings from './settings.json';
18
+ import toast from './toast.json';
19
+ export default {
20
+ animation,
21
+ audio,
22
+ datetime,
23
+ emoji,
24
+ errors,
25
+ forms,
26
+ general,
27
+ icons,
28
+ location,
29
+ media,
30
+ navigation,
31
+ onboarding,
32
+ settings,
33
+ toast,
34
+ };
35
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/infrastructure/locales/en-US/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,SAAS,MAAM,kBAAkB,CAAC;AACzC,OAAO,KAAK,MAAM,cAAc,CAAC;AACjC,OAAO,QAAQ,MAAM,iBAAiB,CAAC;AACvC,OAAO,KAAK,MAAM,cAAc,CAAC;AACjC,OAAO,MAAM,MAAM,eAAe,CAAC;AACnC,OAAO,KAAK,MAAM,cAAc,CAAC;AACjC,OAAO,OAAO,MAAM,gBAAgB,CAAC;AACrC,OAAO,KAAK,MAAM,cAAc,CAAC;AACjC,OAAO,QAAQ,MAAM,iBAAiB,CAAC;AACvC,OAAO,KAAK,MAAM,cAAc,CAAC;AACjC,OAAO,UAAU,MAAM,mBAAmB,CAAC;AAC3C,OAAO,UAAU,MAAM,mBAAmB,CAAC;AAC3C,OAAO,QAAQ,MAAM,iBAAiB,CAAC;AACvC,OAAO,KAAK,MAAM,cAAc,CAAC;AAEjC,eAAe;IACb,SAAS;IACT,KAAK;IACL,QAAQ;IACR,KAAK;IACL,MAAM;IACN,KAAK;IACL,OAAO;IACP,KAAK;IACL,QAAQ;IACR,KAAK;IACL,UAAU;IACV,UAAU;IACV,QAAQ;IACR,KAAK;CACN,CAAC"}
@@ -0,0 +1,49 @@
1
+ {
2
+ "permission": {
3
+ "title": "Location Permission",
4
+ "message": "This app needs access to your location to provide location-based features.",
5
+ "request": "Grant Location Permission",
6
+ "denied": "Location permission denied",
7
+ "granted": "Location permission granted",
8
+ "unknown": "Location permission status unknown"
9
+ },
10
+ "status": {
11
+ "loading": "Getting your location...",
12
+ "success": "Location retrieved successfully",
13
+ "failed": "Unable to get location",
14
+ "unavailable": "Location services not available",
15
+ "cached": "Using cached location",
16
+ "timeout": "Location request timed out"
17
+ },
18
+ "accuracy": {
19
+ "high": "High accuracy",
20
+ "balanced": "Balanced accuracy",
21
+ "low": "Low accuracy",
22
+ "lowest": "Lowest accuracy"
23
+ },
24
+ "errors": {
25
+ "notAvailable": "Location services not available on this platform",
26
+ "permissionDenied": "Location permission denied. Please enable location access in settings.",
27
+ "timeout": "Location request timed out. Please try again.",
28
+ "unknown": "An unknown error occurred while getting location",
29
+ "noLocation": "Unable to determine your location"
30
+ },
31
+ "actions": {
32
+ "getCurrentLocation": "Get Current Location",
33
+ "refreshLocation": "Refresh Location",
34
+ "clearLocation": "Clear Location",
35
+ "openSettings": "Open Settings"
36
+ },
37
+ "labels": {
38
+ "latitude": "Latitude",
39
+ "longitude": "Longitude",
40
+ "accuracy": "Accuracy",
41
+ "address": "Address",
42
+ "timestamp": "Time",
43
+ "coordinates": "Coordinates"
44
+ },
45
+ "units": {
46
+ "meters": "meters",
47
+ "kilometers": "kilometers"
48
+ }
49
+ }
@@ -0,0 +1,49 @@
1
+ {
2
+ "picker": {
3
+ "selectImage": "Select Image",
4
+ "selectImages": "Select Images",
5
+ "selectVideo": "Select Video",
6
+ "takePhoto": "Take Photo",
7
+ "chooseFromLibrary": "Choose from Library",
8
+ "cancel": "Cancel"
9
+ },
10
+ "permissions": {
11
+ "cameraTitle": "Camera Permission",
12
+ "cameraMessage": "This app needs camera access to take photos",
13
+ "libraryTitle": "Photo Library Permission",
14
+ "libraryMessage": "This app needs access to your photo library",
15
+ "deniedTitle": "Permission Denied",
16
+ "deniedMessage": "Please enable permissions in Settings",
17
+ "openSettings": "Open Settings"
18
+ },
19
+ "actions": {
20
+ "resize": "Resize",
21
+ "crop": "Crop",
22
+ "rotate": "Rotate",
23
+ "flip": "Flip",
24
+ "compress": "Compress",
25
+ "save": "Save",
26
+ "delete": "Delete",
27
+ "edit": "Edit"
28
+ },
29
+ "errors": {
30
+ "pickFailed": "Failed to pick image",
31
+ "cameraFailed": "Failed to launch camera",
32
+ "saveFailed": "Failed to save image",
33
+ "manipulateFailed": "Failed to edit image",
34
+ "permissionDenied": "Permission denied",
35
+ "noImage": "No image selected",
36
+ "invalidImage": "Invalid image file",
37
+ "tooLarge": "File size too large"
38
+ },
39
+ "quality": {
40
+ "low": "Low",
41
+ "medium": "Medium",
42
+ "high": "High"
43
+ },
44
+ "format": {
45
+ "jpeg": "JPEG",
46
+ "png": "PNG",
47
+ "webp": "WebP"
48
+ }
49
+ }
@@ -0,0 +1,52 @@
1
+ {
2
+ "home": "Home",
3
+ "settings": "Settings",
4
+ "about": "About",
5
+ "back": "Back",
6
+ "explore": "Explore",
7
+ "search": "Search",
8
+ "favorites": "Favorites",
9
+ "activity": "Activity",
10
+ "discover": "Discover",
11
+ "library": "Library",
12
+ "stats": "Stats",
13
+ "wellness": "Wellness",
14
+ "exercises": "Exercises",
15
+ "nutrition": "Nutrition",
16
+ "progress": "Progress",
17
+ "workouts": "Workouts",
18
+ "dashboard": "Dashboard",
19
+ "calendar": "Calendar",
20
+ "tasks": "Tasks",
21
+ "notes": "Notes",
22
+ "projects": "Projects",
23
+ "goals": "Goals",
24
+ "habits": "Habits",
25
+ "budget": "Budget",
26
+ "expenses": "Expenses",
27
+ "income": "Income",
28
+ "accounts": "Accounts",
29
+ "reports": "Reports",
30
+ "courses": "Courses",
31
+ "lessons": "Lessons",
32
+ "practice": "Practice",
33
+ "learning": "Learning",
34
+ "meditation": "Meditation",
35
+ "journal": "Journal",
36
+ "timer": "Timer",
37
+ "tracking": "Tracking",
38
+ "analytics": "Analytics",
39
+ "community": "Community",
40
+ "feed": "Feed",
41
+ "browse": "Browse",
42
+ "categories": "Categories",
43
+ "saved": "Saved",
44
+ "history": "History",
45
+ "achievements": "Achievements",
46
+ "leaderboard": "Leaderboard",
47
+ "challenges": "Challenges",
48
+ "rewards": "Rewards",
49
+ "today": "Today",
50
+ "medicines": "Medicines",
51
+ "adherence": "Adherence"
52
+ }
@@ -0,0 +1,76 @@
1
+ {
2
+ "skip": "Skip",
3
+ "getStarted": "Get Started",
4
+ "welcome": {
5
+ "title": "Welcome!",
6
+ "subtitle": "Your journey starts here",
7
+ "getStarted": "Get Started",
8
+ "skip": "Skip"
9
+ },
10
+ "slides": {
11
+ "slide1": {
12
+ "title": "Discover Amazing Features",
13
+ "description": "Explore everything our app has to offer"
14
+ },
15
+ "slide2": {
16
+ "title": "Stay Organized",
17
+ "description": "Keep track of what matters most"
18
+ },
19
+ "slide3": {
20
+ "title": "Achieve Your Goals",
21
+ "description": "We're here to help you succeed"
22
+ }
23
+ },
24
+ "permissions": {
25
+ "title": "Permissions",
26
+ "subtitle": "We need some permissions to provide the best experience",
27
+ "location": {
28
+ "title": "Location",
29
+ "description": "Provide location-based features",
30
+ "enable": "Enable Location"
31
+ },
32
+ "camera": {
33
+ "title": "Camera",
34
+ "description": "Take photos and scan documents",
35
+ "enable": "Enable Camera"
36
+ },
37
+ "photos": {
38
+ "title": "Photos",
39
+ "description": "Access your photo library",
40
+ "enable": "Enable Photos"
41
+ },
42
+ "later": "I'll do this later",
43
+ "continue": "Continue"
44
+ },
45
+ "personalization": {
46
+ "title": "Personalize Your Experience",
47
+ "subtitle": "Tell us about yourself",
48
+ "goals": {
49
+ "title": "What are your goals?",
50
+ "options": [
51
+ "Stay healthy",
52
+ "Be productive",
53
+ "Learn new skills",
54
+ "Connect with others",
55
+ "Have fun"
56
+ ]
57
+ },
58
+ "preferences": {
59
+ "title": "Set your preferences",
60
+ "theme": "Choose Theme",
61
+ "language": "Choose Language"
62
+ },
63
+ "continue": "Continue"
64
+ },
65
+ "complete": {
66
+ "title": "You're All Set!",
67
+ "subtitle": "Let's get started!",
68
+ "startButton": "Start Using App"
69
+ },
70
+ "navigation": {
71
+ "next": "Next",
72
+ "back": "Back",
73
+ "skip": "Skip",
74
+ "done": "Done"
75
+ }
76
+ }
@@ -0,0 +1,65 @@
1
+ {
2
+ "lightMode": "Light Mode",
3
+ "darkMode": "Dark Mode",
4
+ "language": "Language",
5
+ "aboutDescription": "App information and version",
6
+ "sections": {
7
+ "appearance": "Appearance",
8
+ "general": "General",
9
+ "support": "Support Development",
10
+ "about": "About & Legal"
11
+ },
12
+ "about": {
13
+ "title": "About",
14
+ "description": "App information and version",
15
+ "appInfo": "App Information",
16
+ "appVersion": "App Version",
17
+ "moreApps": "More Apps",
18
+ "moreAppsDescription": "Check out our other apps",
19
+ "contact": "Contact",
20
+ "contactEmail": "Contact Email",
21
+ "website": "Website"
22
+ },
23
+ "disclaimer": {
24
+ "title": "Health Disclaimer",
25
+ "shortMessage": "Tap to read important health information",
26
+ "message": "This app is for informational and wellness support purposes only. It is NOT a substitute for professional medical or mental health care.\n\nIf you're experiencing a health crisis or emergency, contact your local emergency services or healthcare provider immediately.\n\nAlways consult qualified healthcare professionals for medical advice, diagnosis, or treatment. The content in this app should not be used as a substitute for professional medical judgment.\n\nYour privacy is important. All data stays private on your device unless you explicitly choose to share it."
27
+ },
28
+ "legal": {
29
+ "title": "Legal",
30
+ "description": "Privacy policy, terms of use, and EULA",
31
+ "privacy": "Privacy Policy",
32
+ "privacyDescription": "How we handle your data",
33
+ "terms": "Terms of Use",
34
+ "termsDescription": "Terms and conditions",
35
+ "eula": "End User License Agreement",
36
+ "eulaDescription": "License agreement"
37
+ },
38
+ "version": {
39
+ "title": "App Version"
40
+ },
41
+ "languageSelection": {
42
+ "title": "Select Language",
43
+ "description": "Choose your preferred language",
44
+ "currentLanguage": "Current Language",
45
+ "searchPlaceholder": "Search languages"
46
+ },
47
+ "appearance": {
48
+ "title": "Appearance",
49
+ "darkMode": "Dark Mode",
50
+ "darkTheme": "Dark Theme",
51
+ "lightTheme": "Light Theme",
52
+ "themeDescription": "Language and theme settings"
53
+ },
54
+ "notifications": {
55
+ "title": "Notifications",
56
+ "description": "Manage notification preferences",
57
+ "enableNotifications": "Enable Notifications",
58
+ "notificationPermission": "Notification Permission",
59
+ "notificationPermissionDescription": "Allow app to send notifications"
60
+ },
61
+ "donate": {
62
+ "title": "Support the Developer",
63
+ "description": "Buy me a coffee to support development"
64
+ }
65
+ }
@@ -0,0 +1,38 @@
1
+ {
2
+ "types": {
3
+ "success": "Success",
4
+ "error": "Error",
5
+ "info": "Info",
6
+ "warning": "Warning"
7
+ },
8
+ "position": {
9
+ "top": "Top",
10
+ "bottom": "Bottom"
11
+ },
12
+ "presets": {
13
+ "saved": "Saved",
14
+ "savedDescription": "Your changes have been saved",
15
+ "deleted": "Deleted",
16
+ "deletedDescription": "Item has been removed",
17
+ "copied": "Copied",
18
+ "copiedDescription": "Copied to clipboard",
19
+ "errorGeneric": "Error",
20
+ "errorGenericDescription": "Something went wrong. Please try again.",
21
+ "errorNetwork": "Network Error",
22
+ "errorNetworkDescription": "Please check your connection",
23
+ "errorValidation": "Validation Error",
24
+ "errorValidationDescription": "Please check your input",
25
+ "infoLoading": "Loading",
26
+ "infoLoadingDescription": "Please wait...",
27
+ "infoSyncing": "Syncing",
28
+ "infoSyncingDescription": "Syncing your data...",
29
+ "warningUnsaved": "Unsaved Changes",
30
+ "warningUnsavedDescription": "You have unsaved changes",
31
+ "warningLimit": "Limit Reached",
32
+ "warningLimitDescription": "You have reached the limit"
33
+ },
34
+ "labels": {
35
+ "visibilityTime": "Display Duration",
36
+ "autoHide": "Auto Hide"
37
+ }
38
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * AsyncStorage Wrapper
3
+ * Simple wrapper for AsyncStorage operations
4
+ */
5
+ export declare const STORAGE_KEYS: {
6
+ readonly LANGUAGE: "@localization:language";
7
+ };
8
+ export declare const StorageWrapper: {
9
+ getString(key: string, defaultValue: string): Promise<string>;
10
+ setString(key: string, value: string): Promise<void>;
11
+ };
12
+ //# sourceMappingURL=AsyncStorageWrapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AsyncStorageWrapper.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/storage/AsyncStorageWrapper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,eAAO,MAAM,YAAY;;CAEf,CAAC;AAEX,eAAO,MAAM,cAAc;mBACJ,MAAM,gBAAgB,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;mBAU9C,MAAM,SAAS,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAO3D,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * AsyncStorage Wrapper
3
+ * Simple wrapper for AsyncStorage operations
4
+ */
5
+ import AsyncStorage from '@react-native-async-storage/async-storage';
6
+ export const STORAGE_KEYS = {
7
+ LANGUAGE: '@localization:language',
8
+ };
9
+ export const StorageWrapper = {
10
+ async getString(key, defaultValue) {
11
+ try {
12
+ const value = await AsyncStorage.getItem(key);
13
+ return value ?? defaultValue;
14
+ }
15
+ catch (error) {
16
+ console.warn('[Localization] Failed to get storage value:', error);
17
+ return defaultValue;
18
+ }
19
+ },
20
+ async setString(key, value) {
21
+ try {
22
+ await AsyncStorage.setItem(key, value);
23
+ }
24
+ catch (error) {
25
+ console.warn('[Localization] Failed to set storage value:', error);
26
+ }
27
+ },
28
+ };
29
+ //# sourceMappingURL=AsyncStorageWrapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AsyncStorageWrapper.js","sourceRoot":"","sources":["../../../src/infrastructure/storage/AsyncStorageWrapper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,YAAY,MAAM,2CAA2C,CAAC;AAErE,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,QAAQ,EAAE,wBAAwB;CAC1B,CAAC;AAEX,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,KAAK,CAAC,SAAS,CAAC,GAAW,EAAE,YAAoB;QAC/C,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAC9C,OAAO,KAAK,IAAI,YAAY,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,6CAA6C,EAAE,KAAK,CAAC,CAAC;YACnE,OAAO,YAAY,CAAC;QACtB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,GAAW,EAAE,KAAa;QACxC,IAAI,CAAC;YACH,MAAM,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACzC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,6CAA6C,EAAE,KAAK,CAAC,CAAC;QACrE,CAAC;IACH,CAAC;CACF,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Localization Store
3
+ * Zustand state management for language preferences with AsyncStorage persistence
4
+ */
5
+ import type { Language } from '../../domain/repositories/ILocalizationRepository';
6
+ interface LocalizationState {
7
+ currentLanguage: string;
8
+ isRTL: boolean;
9
+ isInitialized: boolean;
10
+ supportedLanguages: Language[];
11
+ setLanguage: (languageCode: string) => Promise<void>;
12
+ initialize: () => Promise<void>;
13
+ }
14
+ export declare const useLocalizationStore: import("zustand").UseBoundStore<import("zustand").StoreApi<LocalizationState>>;
15
+ /**
16
+ * Hook to use localization
17
+ * Provides current language, RTL state, language switching, and translation function
18
+ */
19
+ export declare const useLocalization: () => {
20
+ t: any;
21
+ currentLanguage: string;
22
+ currentLanguageObject: Language;
23
+ isRTL: boolean;
24
+ isInitialized: boolean;
25
+ supportedLanguages: Language[];
26
+ setLanguage: (languageCode: string) => Promise<void>;
27
+ initialize: () => Promise<void>;
28
+ };
29
+ export {};
30
+ //# sourceMappingURL=LocalizationStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalizationStore.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/storage/LocalizationStore.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mDAAmD,CAAC;AAElF,UAAU,iBAAiB;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,OAAO,CAAC;IACf,aAAa,EAAE,OAAO,CAAC;IACvB,kBAAkB,EAAE,QAAQ,EAAE,CAAC;IAC/B,WAAW,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC;AAED,eAAO,MAAM,oBAAoB,gFAqE9B,CAAC;AAEJ;;;GAGG;AACH,eAAO,MAAM,eAAe;;;;;;;gCA/EE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC;sBAClC,OAAO,CAAC,IAAI,CAAC;CAoGhC,CAAC"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Localization Store
3
+ * Zustand state management for language preferences with AsyncStorage persistence
4
+ */
5
+ import { create } from 'zustand';
6
+ import { StorageWrapper, STORAGE_KEYS } from './AsyncStorageWrapper';
7
+ import i18n from '../config/i18n';
8
+ import { SUPPORTED_LANGUAGES, DEFAULT_LANGUAGE, getLanguageByCode, getDeviceLocale } from '../config/languages';
9
+ export const useLocalizationStore = create((set, get) => ({
10
+ currentLanguage: DEFAULT_LANGUAGE,
11
+ isRTL: false,
12
+ isInitialized: false,
13
+ supportedLanguages: SUPPORTED_LANGUAGES,
14
+ /**
15
+ * Initialize localization
16
+ * DEVICE LOCALE DETECTION:
17
+ * - First launch (no saved language): Automatically detect device locale
18
+ * - After manual selection: Use saved language preference
19
+ * - Fallback: English (en-US) if device locale not supported
20
+ */
21
+ initialize: async () => {
22
+ // ✅ CRITICAL FIX: Don't reset isInitialized if already initialized
23
+ // This prevents UI flash on re-initialization
24
+ const { isInitialized: alreadyInitialized } = get();
25
+ if (alreadyInitialized)
26
+ return;
27
+ // Get saved language preference
28
+ const savedLanguage = await StorageWrapper.getString(STORAGE_KEYS.LANGUAGE, DEFAULT_LANGUAGE);
29
+ // ✅ DEVICE LOCALE DETECTION: Use device locale on first launch
30
+ let languageCode;
31
+ if (savedLanguage && savedLanguage !== DEFAULT_LANGUAGE) {
32
+ // User has previously selected a language → Use their choice
33
+ languageCode = savedLanguage;
34
+ }
35
+ else {
36
+ // First launch → Detect device locale automatically
37
+ languageCode = getDeviceLocale();
38
+ // Save detected locale for future launches
39
+ await StorageWrapper.setString(STORAGE_KEYS.LANGUAGE, languageCode);
40
+ }
41
+ // ✅ DEFENSIVE: Validate language exists, fallback to default
42
+ const language = getLanguageByCode(languageCode);
43
+ const finalLanguage = language ? languageCode : DEFAULT_LANGUAGE;
44
+ const finalLanguageObj = getLanguageByCode(finalLanguage);
45
+ await i18n.changeLanguage(finalLanguage);
46
+ set({
47
+ currentLanguage: finalLanguage,
48
+ isRTL: finalLanguageObj?.rtl || false,
49
+ isInitialized: true, // ✅ Always set true to unblock UI
50
+ });
51
+ },
52
+ /**
53
+ * Change language
54
+ * Updates i18n, state, and persists to AsyncStorage
55
+ */
56
+ setLanguage: async (languageCode) => {
57
+ const language = getLanguageByCode(languageCode);
58
+ // ✅ DEFENSIVE: Early return if unsupported language
59
+ if (!language)
60
+ return;
61
+ // Update i18n
62
+ await i18n.changeLanguage(languageCode);
63
+ // Update state
64
+ set({
65
+ currentLanguage: languageCode,
66
+ isRTL: language.rtl || false,
67
+ });
68
+ // Persist language preference
69
+ await StorageWrapper.setString(STORAGE_KEYS.LANGUAGE, languageCode);
70
+ },
71
+ }));
72
+ /**
73
+ * Hook to use localization
74
+ * Provides current language, RTL state, language switching, and translation function
75
+ */
76
+ export const useLocalization = () => {
77
+ const { currentLanguage, isRTL, isInitialized, supportedLanguages, setLanguage, initialize, } = useLocalizationStore();
78
+ const currentLanguageObject = getLanguageByCode(currentLanguage);
79
+ return {
80
+ t: i18n.t.bind(i18n), // Translation function
81
+ currentLanguage,
82
+ currentLanguageObject,
83
+ isRTL,
84
+ isInitialized,
85
+ supportedLanguages,
86
+ setLanguage,
87
+ initialize,
88
+ };
89
+ };
90
+ //# sourceMappingURL=LocalizationStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalizationStore.js","sourceRoot":"","sources":["../../../src/infrastructure/storage/LocalizationStore.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "@umituz/react-native-localization",
3
+ "version": "1.0.0",
4
+ "description": "Universal localization system for React Native apps with i18n support",
5
+ "main": "./lib/index.js",
6
+ "types": "./lib/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "typecheck": "tsc --noEmit",
10
+ "lint": "tsc --noEmit",
11
+ "clean": "rm -rf lib",
12
+ "prebuild": "npm run clean",
13
+ "prepublishOnly": "npm run build",
14
+ "version:patch": "npm version patch -m 'chore: release v%s'",
15
+ "version:minor": "npm version minor -m 'chore: release v%s'",
16
+ "version:major": "npm version major -m 'chore: release v%s'"
17
+ },
18
+ "keywords": [
19
+ "react-native",
20
+ "localization",
21
+ "i18n",
22
+ "internationalization",
23
+ "translation",
24
+ "language",
25
+ "locale",
26
+ "multilingual"
27
+ ],
28
+ "author": "Ümit UZ <umit@umituz.com>",
29
+ "license": "MIT",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "https://github.com/umituz/react-native-localization"
33
+ },
34
+ "peerDependencies": {
35
+ "react": ">=18.2.0",
36
+ "react-native": ">=0.74.0",
37
+ "zustand": "^5.0.2",
38
+ "i18next": "^23.0.0",
39
+ "react-i18next": "^14.0.0",
40
+ "expo-localization": "~15.0.0",
41
+ "@react-native-async-storage/async-storage": "^1.21.0"
42
+ },
43
+ "devDependencies": {
44
+ "typescript": "^5.3.3",
45
+ "@types/react": "^18.2.45",
46
+ "@types/react-native": "^0.73.0",
47
+ "react": ">=18.2.0",
48
+ "react-native": ">=0.74.0",
49
+ "zustand": "^5.0.2",
50
+ "i18next": "^23.0.0",
51
+ "react-i18next": "^14.0.0",
52
+ "expo-localization": "~15.0.0",
53
+ "@react-native-async-storage/async-storage": "^1.21.0"
54
+ },
55
+ "publishConfig": {
56
+ "access": "public"
57
+ },
58
+ "files": [
59
+ "lib",
60
+ "src",
61
+ "README.md",
62
+ "LICENSE"
63
+ ]
64
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Localization Repository Interface
3
+ * Defines language configuration and types
4
+ */
5
+
6
+ export interface Language {
7
+ code: string;
8
+ name: string;
9
+ nativeName: string;
10
+ flag: string;
11
+ rtl?: boolean;
12
+ }
13
+
14
+ export interface ILocalizationRepository {
15
+ getSupportedLanguages(): Language[];
16
+ getLanguageByCode(code: string): Language | undefined;
17
+ isLanguageSupported(code: string): boolean;
18
+ }