locon 1.0.4 → 1.1.1

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/README.md CHANGED
@@ -4,6 +4,28 @@
4
4
  It provides a context provider, a hook, and a simple text component to keep
5
5
  your translations flat, explicit, and easy to use.
6
6
 
7
+ Basic usage: use `<LText>` instead of `<Text>`. Put plain text in your project language (or the default language) inside and it will be localized automatically.
8
+
9
+ ```tsx
10
+ import { LText } from 'locon'
11
+
12
+ function Example() {
13
+ return <LText>Hello</LText>
14
+ }
15
+ ```
16
+
17
+ For dynamic strings (variables), use `useLocon()` and `l()`:
18
+
19
+ ```tsx
20
+ import { Text } from 'react-native'
21
+ import { useLocon } from 'locon'
22
+
23
+ function Example({ userName }: { userName: string }) {
24
+ const { l } = useLocon()
25
+ return <Text>{l('hello')}, {userName}</Text>
26
+ }
27
+ ```
28
+
7
29
  ---
8
30
 
9
31
  ### Features
@@ -25,10 +47,19 @@ npm install locon
25
47
  yarn add locon
26
48
  ```
27
49
 
50
+ **Important:** After installation, run pod install for iOS:
51
+
52
+ ```bash
53
+ cd ios && pod install
54
+ ```
55
+
28
56
  **Peer dependencies**
29
57
 
30
58
  - `react >= 19.0.0`
31
59
  - `react-native >= 0.70.0`
60
+ - `react-native-localize >= 3.0.0` (installed automatically)
61
+
62
+ `react-native-localize` is used for accurate device language detection on iOS and Android.
32
63
 
33
64
  ---
34
65
 
@@ -79,9 +110,7 @@ function App() {
79
110
  return (
80
111
  <Locon
81
112
  assets={{ en, de }}
82
- defaultLocale='en'
83
113
  projectLocale='de'
84
- autodetect
85
114
  >
86
115
  <NavigationContainer theme={theme}>
87
116
  <RootNavigator />
@@ -96,9 +125,9 @@ export default App
96
125
  If `currentLocale` is not provided and `autodetect` is `true` (default),
97
126
  `locon` will:
98
127
 
99
- 1. Read device locale from `Intl.DateTimeFormat().resolvedOptions().locale`
100
- 2. Extract language code (e.g. `'en'` from `'en-US'`)
101
- 3. If that language exists in `assets`, use it as initial locale
128
+ 1. Use `react-native-localize` to detect device locale on iOS/Android
129
+ 2. Match the detected locale (including region) or just language code against your `assets`
130
+ 3. If a match is found, use it as initial locale
102
131
  4. Otherwise, fall back to `defaultLocale`
103
132
 
104
133
  #### 3. Use the `useLocon()` hook
@@ -145,7 +174,7 @@ function Welcome() {
145
174
  return (
146
175
  <View>
147
176
  {/* Uses children as value to find the key, with fallback children */}
148
- <LText>Hello</LText>
177
+ <LText>Hallo</LText>
149
178
 
150
179
  {/* Or explicit key with fallback children */}
151
180
  <LText assetKey='welcome_title'>Welcome</LText>
@@ -180,6 +209,7 @@ interface LoconProps extends PropsWithChildren {
180
209
  Used when key is missing in the current locale.
181
210
 
182
211
  - **`projectLocale`** (default `'en'`)
212
+ Define language you use for texts in your project.
183
213
  Used for reverse lookup by value (e.g. when you only know the string in
184
214
  project language).
185
215
 
package/dist/index.js CHANGED
@@ -3,37 +3,105 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var react = require('react');
6
- var RNLocalize = require('react-native-localize');
7
6
  var reactNative = require('react-native');
8
7
  var jsxRuntime = require('react/jsx-runtime');
9
8
 
10
- function _interopNamespace(e) {
11
- if (e && e.__esModule) return e;
12
- var n = Object.create(null);
13
- if (e) {
14
- Object.keys(e).forEach(function (k) {
15
- if (k !== 'default') {
16
- var d = Object.getOwnPropertyDescriptor(e, k);
17
- Object.defineProperty(n, k, d.get ? d : {
18
- enumerable: true,
19
- get: function () { return e[k]; }
20
- });
21
- }
22
- });
23
- }
24
- n.default = e;
25
- return Object.freeze(n);
26
- }
27
-
28
- var RNLocalize__namespace = /*#__PURE__*/_interopNamespace(RNLocalize);
9
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
10
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
11
+ }) : x)(function(x) {
12
+ if (typeof require !== "undefined") return require.apply(this, arguments);
13
+ throw Error('Dynamic require of "' + x + '" is not supported');
14
+ });
29
15
 
30
- // src/locon/index.tsx
16
+ // src/locon/utils/getSystemLanguage.ts
31
17
  function getSystemLanguage(availableLocales) {
32
18
  if (!availableLocales?.length) return null;
33
19
  try {
34
- const best = RNLocalize__namespace.findBestLanguageTag(availableLocales);
35
- return best?.languageTag ?? null;
36
- } catch {
20
+ try {
21
+ const RNLocalize = __require("react-native-localize");
22
+ const best = RNLocalize.findBestLanguageTag(availableLocales);
23
+ if (best?.languageTag) {
24
+ return best.languageTag;
25
+ }
26
+ } catch (localizeError) {
27
+ }
28
+ try {
29
+ const reactNative = __require("react-native");
30
+ const { NativeModules, Platform } = reactNative;
31
+ if (Platform?.OS === "ios") {
32
+ const SettingsManager = NativeModules?.SettingsManager;
33
+ if (SettingsManager?.settings?.AppleLanguages) {
34
+ const appleLanguages = SettingsManager.settings.AppleLanguages;
35
+ for (const lang of appleLanguages) {
36
+ const languageCode = lang.split("-")[0]?.toLowerCase();
37
+ if (languageCode) {
38
+ const supportedLanguage = availableLocales.find((locale) => locale === languageCode);
39
+ if (supportedLanguage) {
40
+ return supportedLanguage;
41
+ }
42
+ }
43
+ }
44
+ }
45
+ const I18nManager = NativeModules?.I18nManager;
46
+ if (I18nManager?.localeIdentifier) {
47
+ const languageCode = I18nManager.localeIdentifier.split("-")[0]?.toLowerCase();
48
+ if (languageCode) {
49
+ const supportedLanguage = availableLocales.find((locale) => locale === languageCode);
50
+ if (supportedLanguage) {
51
+ return supportedLanguage;
52
+ }
53
+ }
54
+ }
55
+ } else if (Platform?.OS === "android") {
56
+ const I18nManager = NativeModules?.I18nManager;
57
+ if (I18nManager?.localeIdentifier) {
58
+ const languageCode = I18nManager.localeIdentifier.split("-")[0]?.toLowerCase();
59
+ if (languageCode) {
60
+ const supportedLanguage = availableLocales.find((locale) => locale === languageCode);
61
+ if (supportedLanguage) {
62
+ return supportedLanguage;
63
+ }
64
+ }
65
+ }
66
+ }
67
+ } catch (rnError) {
68
+ }
69
+ const navigatorObj = typeof navigator !== "undefined" ? navigator : null;
70
+ const preferredLanguages = navigatorObj?.languages;
71
+ if (preferredLanguages) {
72
+ for (const lang of preferredLanguages) {
73
+ const languageCode = lang.split("-")[0]?.toLowerCase();
74
+ if (languageCode) {
75
+ const supportedLanguage = availableLocales.find((locale) => locale === languageCode);
76
+ if (supportedLanguage) {
77
+ return supportedLanguage;
78
+ }
79
+ }
80
+ }
81
+ }
82
+ const navigatorLanguage = navigatorObj?.language;
83
+ if (navigatorLanguage) {
84
+ const languageCode = navigatorLanguage.split("-")[0]?.toLowerCase();
85
+ if (languageCode) {
86
+ const supportedLanguage = availableLocales.find((locale) => locale === languageCode);
87
+ if (supportedLanguage) {
88
+ return supportedLanguage;
89
+ }
90
+ }
91
+ }
92
+ const systemLocale = Intl.DateTimeFormat().resolvedOptions().locale;
93
+ if (systemLocale) {
94
+ const languageCode = systemLocale.split("-")[0]?.toLowerCase();
95
+ if (languageCode) {
96
+ const supportedLanguage = availableLocales.find((locale) => locale === languageCode);
97
+ if (supportedLanguage) {
98
+ return supportedLanguage;
99
+ }
100
+ }
101
+ }
102
+ return null;
103
+ } catch (error) {
104
+ console.log("Could not detect system language:", error);
37
105
  return null;
38
106
  }
39
107
  }
package/dist/index.mjs CHANGED
@@ -1,15 +1,103 @@
1
1
  import { createContext, useContext, useState, useCallback, useMemo } from 'react';
2
- import * as RNLocalize from 'react-native-localize';
3
2
  import { Text } from 'react-native';
4
3
  import { jsx } from 'react/jsx-runtime';
5
4
 
6
- // src/locon/index.tsx
5
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
6
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
7
+ }) : x)(function(x) {
8
+ if (typeof require !== "undefined") return require.apply(this, arguments);
9
+ throw Error('Dynamic require of "' + x + '" is not supported');
10
+ });
11
+
12
+ // src/locon/utils/getSystemLanguage.ts
7
13
  function getSystemLanguage(availableLocales) {
8
14
  if (!availableLocales?.length) return null;
9
15
  try {
10
- const best = RNLocalize.findBestLanguageTag(availableLocales);
11
- return best?.languageTag ?? null;
12
- } catch {
16
+ try {
17
+ const RNLocalize = __require("react-native-localize");
18
+ const best = RNLocalize.findBestLanguageTag(availableLocales);
19
+ if (best?.languageTag) {
20
+ return best.languageTag;
21
+ }
22
+ } catch (localizeError) {
23
+ }
24
+ try {
25
+ const reactNative = __require("react-native");
26
+ const { NativeModules, Platform } = reactNative;
27
+ if (Platform?.OS === "ios") {
28
+ const SettingsManager = NativeModules?.SettingsManager;
29
+ if (SettingsManager?.settings?.AppleLanguages) {
30
+ const appleLanguages = SettingsManager.settings.AppleLanguages;
31
+ for (const lang of appleLanguages) {
32
+ const languageCode = lang.split("-")[0]?.toLowerCase();
33
+ if (languageCode) {
34
+ const supportedLanguage = availableLocales.find((locale) => locale === languageCode);
35
+ if (supportedLanguage) {
36
+ return supportedLanguage;
37
+ }
38
+ }
39
+ }
40
+ }
41
+ const I18nManager = NativeModules?.I18nManager;
42
+ if (I18nManager?.localeIdentifier) {
43
+ const languageCode = I18nManager.localeIdentifier.split("-")[0]?.toLowerCase();
44
+ if (languageCode) {
45
+ const supportedLanguage = availableLocales.find((locale) => locale === languageCode);
46
+ if (supportedLanguage) {
47
+ return supportedLanguage;
48
+ }
49
+ }
50
+ }
51
+ } else if (Platform?.OS === "android") {
52
+ const I18nManager = NativeModules?.I18nManager;
53
+ if (I18nManager?.localeIdentifier) {
54
+ const languageCode = I18nManager.localeIdentifier.split("-")[0]?.toLowerCase();
55
+ if (languageCode) {
56
+ const supportedLanguage = availableLocales.find((locale) => locale === languageCode);
57
+ if (supportedLanguage) {
58
+ return supportedLanguage;
59
+ }
60
+ }
61
+ }
62
+ }
63
+ } catch (rnError) {
64
+ }
65
+ const navigatorObj = typeof navigator !== "undefined" ? navigator : null;
66
+ const preferredLanguages = navigatorObj?.languages;
67
+ if (preferredLanguages) {
68
+ for (const lang of preferredLanguages) {
69
+ const languageCode = lang.split("-")[0]?.toLowerCase();
70
+ if (languageCode) {
71
+ const supportedLanguage = availableLocales.find((locale) => locale === languageCode);
72
+ if (supportedLanguage) {
73
+ return supportedLanguage;
74
+ }
75
+ }
76
+ }
77
+ }
78
+ const navigatorLanguage = navigatorObj?.language;
79
+ if (navigatorLanguage) {
80
+ const languageCode = navigatorLanguage.split("-")[0]?.toLowerCase();
81
+ if (languageCode) {
82
+ const supportedLanguage = availableLocales.find((locale) => locale === languageCode);
83
+ if (supportedLanguage) {
84
+ return supportedLanguage;
85
+ }
86
+ }
87
+ }
88
+ const systemLocale = Intl.DateTimeFormat().resolvedOptions().locale;
89
+ if (systemLocale) {
90
+ const languageCode = systemLocale.split("-")[0]?.toLowerCase();
91
+ if (languageCode) {
92
+ const supportedLanguage = availableLocales.find((locale) => locale === languageCode);
93
+ if (supportedLanguage) {
94
+ return supportedLanguage;
95
+ }
96
+ }
97
+ }
98
+ return null;
99
+ } catch (error) {
100
+ console.log("Could not detect system language:", error);
13
101
  return null;
14
102
  }
15
103
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "locon",
3
- "version": "1.0.4",
3
+ "version": "1.1.1",
4
4
  "description": "locon is a simple and lightweight library for React Native that provides a simple way to manage translations in your app.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -30,15 +30,9 @@
30
30
  "license": "ISC",
31
31
  "peerDependencies": {
32
32
  "react": ">=19.0.0",
33
- "react-native": ">=0.70.0",
34
- "react-native-localize": ">=3.0.0"
33
+ "react-native": ">=0.70.0"
35
34
  },
36
- "peerDependenciesMeta": {
37
- "react-native-localize": {
38
- "optional": true
39
- }
40
- },
41
- "dependencies": {
35
+ "optionalDependencies": {
42
36
  "react-native-localize": "^3.2.1"
43
37
  },
44
38
  "devDependencies": {