gt-react-native 0.0.0 → 0.0.1-alpha.2

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 (79) hide show
  1. package/GtReactNative.podspec +21 -0
  2. package/LICENSE +105 -0
  3. package/README.md +27 -1
  4. package/android/app/build/generated/source/codegen/java/com/facebook/fbreact/specs/NativeGtReactNativeSpec.java +51 -0
  5. package/android/app/build/generated/source/codegen/jni/CMakeLists.txt +28 -0
  6. package/android/app/build/generated/source/codegen/jni/GtReactNativeSpec-generated.cpp +50 -0
  7. package/android/app/build/generated/source/codegen/jni/GtReactNativeSpec.h +31 -0
  8. package/android/app/build/generated/source/codegen/jni/react/renderer/components/GtReactNativeSpec/GtReactNativeSpecJSI-generated.cpp +51 -0
  9. package/android/app/build/generated/source/codegen/jni/react/renderer/components/GtReactNativeSpec/GtReactNativeSpecJSI.h +98 -0
  10. package/android/build.gradle +77 -0
  11. package/android/gradle.properties +5 -0
  12. package/android/src/main/AndroidManifest.xml +2 -0
  13. package/android/src/main/java/com/gtreactnative/GtReactNativeModule.kt +68 -0
  14. package/android/src/main/java/com/gtreactnative/GtReactNativePackage.kt +33 -0
  15. package/ios/GtReactNative.h +5 -0
  16. package/ios/GtReactNative.mm +64 -0
  17. package/lib/module/NativeGtReactNative.js +5 -0
  18. package/lib/module/NativeGtReactNative.js.map +1 -0
  19. package/lib/module/errors-dir/constants.js +4 -0
  20. package/lib/module/errors-dir/constants.js.map +1 -0
  21. package/lib/module/index.js +11 -0
  22. package/lib/module/index.js.map +1 -0
  23. package/lib/module/package.json +1 -0
  24. package/lib/module/provider/GTProvider.js +19 -0
  25. package/lib/module/provider/GTProvider.js.map +1 -0
  26. package/lib/module/provider/hooks/locale/useDetermineLocale.js +140 -0
  27. package/lib/module/provider/hooks/locale/useDetermineLocale.js.map +1 -0
  28. package/lib/module/provider/hooks/useRegionState.js +55 -0
  29. package/lib/module/provider/hooks/useRegionState.js.map +1 -0
  30. package/lib/module/types/config.js +4 -0
  31. package/lib/module/types/config.js.map +1 -0
  32. package/lib/module/utils/constants.js +8 -0
  33. package/lib/module/utils/constants.js.map +1 -0
  34. package/lib/module/utils/getNativeLocales.js +54 -0
  35. package/lib/module/utils/getNativeLocales.js.map +1 -0
  36. package/lib/module/utils/nativeStore.js +34 -0
  37. package/lib/module/utils/nativeStore.js.map +1 -0
  38. package/lib/module/utils/polyfill.js +32 -0
  39. package/lib/module/utils/polyfill.js.map +1 -0
  40. package/lib/module/utils/utils.js +16 -0
  41. package/lib/module/utils/utils.js.map +1 -0
  42. package/lib/typescript/package.json +1 -0
  43. package/lib/typescript/src/NativeGtReactNative.d.ts +10 -0
  44. package/lib/typescript/src/NativeGtReactNative.d.ts.map +1 -0
  45. package/lib/typescript/src/errors-dir/constants.d.ts +2 -0
  46. package/lib/typescript/src/errors-dir/constants.d.ts.map +1 -0
  47. package/lib/typescript/src/index.d.ts +7 -0
  48. package/lib/typescript/src/index.d.ts.map +1 -0
  49. package/lib/typescript/src/provider/GTProvider.d.ts +4 -0
  50. package/lib/typescript/src/provider/GTProvider.d.ts.map +1 -0
  51. package/lib/typescript/src/provider/hooks/locale/useDetermineLocale.d.ts +4 -0
  52. package/lib/typescript/src/provider/hooks/locale/useDetermineLocale.d.ts.map +1 -0
  53. package/lib/typescript/src/provider/hooks/useRegionState.d.ts +3 -0
  54. package/lib/typescript/src/provider/hooks/useRegionState.d.ts.map +1 -0
  55. package/lib/typescript/src/types/config.d.ts +30 -0
  56. package/lib/typescript/src/types/config.d.ts.map +1 -0
  57. package/lib/typescript/src/utils/constants.d.ts +3 -0
  58. package/lib/typescript/src/utils/constants.d.ts.map +1 -0
  59. package/lib/typescript/src/utils/getNativeLocales.d.ts +10 -0
  60. package/lib/typescript/src/utils/getNativeLocales.d.ts.map +1 -0
  61. package/lib/typescript/src/utils/nativeStore.d.ts +16 -0
  62. package/lib/typescript/src/utils/nativeStore.d.ts.map +1 -0
  63. package/lib/typescript/src/utils/polyfill.d.ts +28 -0
  64. package/lib/typescript/src/utils/polyfill.d.ts.map +1 -0
  65. package/lib/typescript/src/utils/utils.d.ts +3 -0
  66. package/lib/typescript/src/utils/utils.d.ts.map +1 -0
  67. package/package.json +153 -7
  68. package/src/NativeGtReactNative.ts +10 -0
  69. package/src/errors-dir/constants.ts +1 -0
  70. package/src/index.tsx +68 -0
  71. package/src/provider/GTProvider.tsx +20 -0
  72. package/src/provider/hooks/locale/useDetermineLocale.ts +192 -0
  73. package/src/provider/hooks/useRegionState.ts +63 -0
  74. package/src/types/config.ts +35 -0
  75. package/src/utils/constants.ts +5 -0
  76. package/src/utils/getNativeLocales.ts +53 -0
  77. package/src/utils/nativeStore.ts +31 -0
  78. package/src/utils/polyfill.ts +36 -0
  79. package/src/utils/utils.ts +13 -0
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Get native device locales in preference order
3
+ * Returns an empty array if detection fails or is not supported
4
+ *
5
+ * iOS: Returns current locale first, followed by preferred languages
6
+ * Android: Returns user's preferred language list (LocaleList on API 24+, single locale on older versions)
7
+ * Web: Returns browser language preferences from navigator
8
+ */
9
+ export declare function getNativeLocales(): string[];
10
+ //# sourceMappingURL=getNativeLocales.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getNativeLocales.d.ts","sourceRoot":"","sources":["../../../../src/utils/getNativeLocales.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,EAAE,CAa3C"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Native store interface, used to replace cookie behavior from gt-react
3
+ */
4
+ /**
5
+ * Get a value from the native store
6
+ * @param key - The key to get the value for
7
+ * @returns The value for the key
8
+ */
9
+ export declare function nativeStoreGet(key: string): string | null;
10
+ /**
11
+ * Set a value in the native store
12
+ * @param key - The key to set the value for
13
+ * @param value - The value to set
14
+ */
15
+ export declare function nativeStoreSet(key: string, value: string): void;
16
+ //# sourceMappingURL=nativeStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nativeStore.d.ts","sourceRoot":"","sources":["../../../../src/utils/nativeStore.ts"],"names":[],"mappings":"AAGA;;GAEG;AAEH;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKzD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAM/D"}
@@ -0,0 +1,28 @@
1
+ import '@formatjs/intl-getcanonicallocales/polyfill';
2
+ import '@formatjs/intl-locale/polyfill';
3
+ import '@formatjs/intl-displaynames/polyfill';
4
+ import '@formatjs/intl-displaynames/locale-data/en';
5
+ import '@formatjs/intl-displaynames/locale-data/zh';
6
+ import '@formatjs/intl-displaynames/locale-data/es';
7
+ import '@formatjs/intl-listformat/polyfill';
8
+ import '@formatjs/intl-listformat/locale-data/en';
9
+ import '@formatjs/intl-listformat/locale-data/zh';
10
+ import '@formatjs/intl-listformat/locale-data/es';
11
+ import '@formatjs/intl-pluralrules/polyfill';
12
+ import '@formatjs/intl-pluralrules/locale-data/en';
13
+ import '@formatjs/intl-pluralrules/locale-data/zh';
14
+ import '@formatjs/intl-pluralrules/locale-data/es';
15
+ import '@formatjs/intl-numberformat/polyfill';
16
+ import '@formatjs/intl-numberformat/locale-data/en';
17
+ import '@formatjs/intl-numberformat/locale-data/zh';
18
+ import '@formatjs/intl-numberformat/locale-data/es';
19
+ import '@formatjs/intl-relativetimeformat/polyfill';
20
+ import '@formatjs/intl-relativetimeformat/locale-data/en';
21
+ import '@formatjs/intl-relativetimeformat/locale-data/zh';
22
+ import '@formatjs/intl-relativetimeformat/locale-data/es';
23
+ import '@formatjs/intl-datetimeformat/polyfill';
24
+ import '@formatjs/intl-datetimeformat/add-all-tz';
25
+ import '@formatjs/intl-datetimeformat/locale-data/en';
26
+ import '@formatjs/intl-datetimeformat/locale-data/zh';
27
+ import '@formatjs/intl-datetimeformat/locale-data/es';
28
+ //# sourceMappingURL=polyfill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"polyfill.d.ts","sourceRoot":"","sources":["../../../../src/utils/polyfill.ts"],"names":[],"mappings":"AAEA,OAAO,6CAA6C,CAAC;AAErD,OAAO,gCAAgC,CAAC;AAExC,OAAO,sCAAsC,CAAC;AAC9C,OAAO,4CAA4C,CAAC;AACpD,OAAO,4CAA4C,CAAC;AACpD,OAAO,4CAA4C,CAAC;AAEpD,OAAO,oCAAoC,CAAC;AAC5C,OAAO,0CAA0C,CAAC;AAClD,OAAO,0CAA0C,CAAC;AAClD,OAAO,0CAA0C,CAAC;AAElD,OAAO,qCAAqC,CAAC;AAC7C,OAAO,2CAA2C,CAAC;AACnD,OAAO,2CAA2C,CAAC;AACnD,OAAO,2CAA2C,CAAC;AAEnD,OAAO,sCAAsC,CAAC;AAC9C,OAAO,4CAA4C,CAAC;AACpD,OAAO,4CAA4C,CAAC;AACpD,OAAO,4CAA4C,CAAC;AAEpD,OAAO,4CAA4C,CAAC;AACpD,OAAO,kDAAkD,CAAC;AAC1D,OAAO,kDAAkD,CAAC;AAC1D,OAAO,kDAAkD,CAAC;AAE1D,OAAO,wCAAwC,CAAC;AAChD,OAAO,0CAA0C,CAAC;AAClD,OAAO,8CAA8C,CAAC;AACtD,OAAO,8CAA8C,CAAC;AACtD,OAAO,8CAA8C,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { AuthFromEnvParams, AuthFromEnvReturn } from '@generaltranslation/react-core/types';
2
+ export declare function readAuthFromEnv(params: AuthFromEnvParams): AuthFromEnvReturn;
3
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../src/utils/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,sCAAsC,CAAC;AAE9C,wBAAgB,eAAe,CAAC,MAAM,EAAE,iBAAiB,GAAG,iBAAiB,CAM5E"}
package/package.json CHANGED
@@ -1,12 +1,158 @@
1
1
  {
2
2
  "name": "gt-react-native",
3
- "version": "0.0.0",
4
- "description": "",
5
- "license": "UNLICENSED",
6
- "author": "",
7
- "type": "commonjs",
8
- "main": "index.js",
3
+ "version": "0.0.1-alpha.2",
4
+ "description": "An i18n package for React Native",
5
+ "main": "./lib/module/index.js",
6
+ "types": "./lib/typescript/src/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "source": "./src/index.tsx",
10
+ "types": "./lib/typescript/src/index.d.ts",
11
+ "default": "./lib/module/index.js"
12
+ },
13
+ "./package.json": "./package.json"
14
+ },
15
+ "files": [
16
+ "src",
17
+ "lib",
18
+ "android",
19
+ "ios",
20
+ "cpp",
21
+ "*.podspec",
22
+ "react-native.config.js",
23
+ "!ios/build",
24
+ "!android/build",
25
+ "!android/gradle",
26
+ "!android/gradlew",
27
+ "!android/gradlew.bat",
28
+ "!android/local.properties",
29
+ "!**/__tests__",
30
+ "!**/__fixtures__",
31
+ "!**/__mocks__",
32
+ "!**/.*"
33
+ ],
9
34
  "scripts": {
10
- "test": "echo \"Error: no test specified\" && exit 1"
35
+ "example": "yarn workspace gt-react-native-example",
36
+ "test": "jest",
37
+ "typecheck": "tsc",
38
+ "lint": "eslint \"**/*.{js,ts,tsx}\"",
39
+ "clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib",
40
+ "prepare": "bob build",
41
+ "release": "yarn clean && yarn npm publish --tag latest",
42
+ "release:alpha": "yarn clean && npm publish --tag alpha"
43
+ },
44
+ "keywords": [
45
+ "react-native",
46
+ "ios",
47
+ "android"
48
+ ],
49
+ "repository": {
50
+ "type": "git",
51
+ "url": "git+https://github.com/generaltranslation/gt-react-native.git"
52
+ },
53
+ "author": "General Translation, Inc. <support@generaltranslation.com> (https://generaltranslation.com)",
54
+ "license": "FSL-1.1-ALv2",
55
+ "bugs": {
56
+ "url": "https://github.com/generaltranslation/gt-react-native/issues"
57
+ },
58
+ "homepage": "https://github.com/generaltranslation/gt-react-native#readme",
59
+ "publishConfig": {
60
+ "registry": "https://registry.npmjs.org/"
61
+ },
62
+ "devDependencies": {
63
+ "@commitlint/config-conventional": "^19.8.1",
64
+ "@eslint/compat": "^1.3.2",
65
+ "@eslint/eslintrc": "^3.3.1",
66
+ "@eslint/js": "^9.35.0",
67
+ "@evilmartians/lefthook": "^1.12.3",
68
+ "@react-native-community/cli": "20.0.1",
69
+ "@react-native/babel-preset": "0.81.1",
70
+ "@react-native/eslint-config": "^0.81.1",
71
+ "@release-it/conventional-changelog": "^10.0.1",
72
+ "@types/jest": "^29.5.14",
73
+ "@types/react": "^19.1.0",
74
+ "commitlint": "^19.8.1",
75
+ "del-cli": "^6.0.0",
76
+ "eslint": "^9.35.0",
77
+ "eslint-config-prettier": "^10.1.8",
78
+ "eslint-plugin-prettier": "^5.5.4",
79
+ "jest": "^29.7.0",
80
+ "prettier": "^3.6.2",
81
+ "react": "19.1.0",
82
+ "react-native": "0.81.1",
83
+ "react-native-builder-bob": "^0.40.13",
84
+ "turbo": "^2.5.6",
85
+ "typescript": "^5.9.2"
86
+ },
87
+ "dependencies": {
88
+ "@formatjs/intl-datetimeformat": "^6.18.2",
89
+ "@formatjs/intl-displaynames": "^6.8.13",
90
+ "@formatjs/intl-getcanonicallocales": "^2.5.6",
91
+ "@formatjs/intl-listformat": "^7.7.13",
92
+ "@formatjs/intl-locale": "^4.2.13",
93
+ "@formatjs/intl-numberformat": "^8.15.6",
94
+ "@formatjs/intl-pluralrules": "^5.4.6",
95
+ "@formatjs/intl-relativetimeformat": "^11.4.13",
96
+ "@generaltranslation/react-core": "^1.0.0",
97
+ "@generaltranslation/supported-locales": "^2.0.16",
98
+ "generaltranslation": "^7.7.0"
99
+ },
100
+ "peerDependencies": {
101
+ "react": "*",
102
+ "react-native": "*"
103
+ },
104
+ "workspaces": [
105
+ "example"
106
+ ],
107
+ "packageManager": "yarn@3.6.1",
108
+ "jest": {
109
+ "preset": "react-native",
110
+ "modulePathIgnorePatterns": [
111
+ "<rootDir>/example/node_modules",
112
+ "<rootDir>/lib/"
113
+ ]
114
+ },
115
+ "commitlint": {
116
+ "extends": [
117
+ "@commitlint/config-conventional"
118
+ ]
119
+ },
120
+ "prettier": {
121
+ "quoteProps": "consistent",
122
+ "singleQuote": true,
123
+ "tabWidth": 2,
124
+ "trailingComma": "es5",
125
+ "useTabs": false
126
+ },
127
+ "react-native-builder-bob": {
128
+ "source": "src",
129
+ "output": "lib",
130
+ "targets": [
131
+ [
132
+ "module",
133
+ {
134
+ "esm": true
135
+ }
136
+ ],
137
+ [
138
+ "typescript",
139
+ {
140
+ "project": "tsconfig.build.json"
141
+ }
142
+ ]
143
+ ]
144
+ },
145
+ "codegenConfig": {
146
+ "name": "GtReactNativeSpec",
147
+ "type": "modules",
148
+ "jsSrcsDir": "./src",
149
+ "android": {
150
+ "javaPackageName": "com.gtreactnative"
151
+ }
152
+ },
153
+ "create-react-native-library": {
154
+ "languages": "kotlin-objc",
155
+ "type": "turbo-module",
156
+ "version": "0.54.5"
11
157
  }
12
158
  }
@@ -0,0 +1,10 @@
1
+ import { TurboModuleRegistry, type TurboModule } from 'react-native';
2
+
3
+ export interface Spec extends TurboModule {
4
+ multiply(a: number, b: number): number;
5
+ getNativeLocales(): string[];
6
+ nativeStoreGet(key: string): string | null;
7
+ nativeStoreSet(key: string, value: string): void;
8
+ }
9
+
10
+ export default TurboModuleRegistry.getEnforcing<Spec>('GtReactNative');
@@ -0,0 +1 @@
1
+ export const PACKAGE_NAME = 'gt-react';
package/src/index.tsx ADDED
@@ -0,0 +1,68 @@
1
+ import './utils/polyfill';
2
+ import GtReactNative from './NativeGtReactNative';
3
+
4
+ import { GTProvider } from './provider/GTProvider';
5
+ export function multiply(a: number, b: number): number {
6
+ return GtReactNative.multiply(a, b);
7
+ }
8
+
9
+ import {
10
+ T,
11
+ useGT,
12
+ useTranslations,
13
+ useDefaultLocale,
14
+ useLocale,
15
+ useRegion,
16
+ Var,
17
+ Num,
18
+ Currency,
19
+ DateTime,
20
+ Plural,
21
+ Branch,
22
+ useLocales,
23
+ useLocaleSelector,
24
+ useSetLocale,
25
+ useGTClass,
26
+ useLocaleProperties,
27
+ useRegionSelector,
28
+ useLocaleDirection,
29
+ useMessages,
30
+ msg,
31
+ decodeMsg,
32
+ decodeOptions,
33
+ } from '@generaltranslation/react-core';
34
+ import type {
35
+ DictionaryTranslationOptions,
36
+ InlineTranslationOptions,
37
+ RuntimeTranslationOptions,
38
+ } from '@generaltranslation/react-core/types';
39
+
40
+ export {
41
+ Var,
42
+ Num,
43
+ Currency,
44
+ DateTime,
45
+ T,
46
+ GTProvider,
47
+ Plural,
48
+ Branch,
49
+ useGT,
50
+ useTranslations,
51
+ useDefaultLocale,
52
+ useLocale,
53
+ useLocales,
54
+ useSetLocale,
55
+ useLocaleSelector,
56
+ useRegion,
57
+ useRegionSelector,
58
+ useGTClass,
59
+ useLocaleProperties,
60
+ useLocaleDirection,
61
+ type DictionaryTranslationOptions,
62
+ type InlineTranslationOptions,
63
+ type RuntimeTranslationOptions,
64
+ msg,
65
+ decodeMsg,
66
+ decodeOptions,
67
+ useMessages,
68
+ };
@@ -0,0 +1,20 @@
1
+ import { useDetermineLocale } from './hooks/locale/useDetermineLocale';
2
+ import type { GTProviderProps } from '../types/config';
3
+ import { GTProvider as _GTProvider } from '@generaltranslation/react-core';
4
+ import { readAuthFromEnv } from '../utils/utils';
5
+ import { useRegionState } from './hooks/useRegionState';
6
+
7
+ export function GTProvider(props: GTProviderProps): React.JSX.Element {
8
+ return (
9
+ <_GTProvider
10
+ ssr={false}
11
+ environment={__DEV__ ? 'development' : 'production'}
12
+ {...props}
13
+ readAuthFromEnv={readAuthFromEnv}
14
+ useDetermineLocale={useDetermineLocale}
15
+ useRegionState={useRegionState}
16
+ />
17
+ );
18
+ }
19
+
20
+ export default GTProvider;
@@ -0,0 +1,192 @@
1
+ import { useEffect, useState } from 'react';
2
+ import { determineLocale, resolveAliasLocale } from 'generaltranslation';
3
+ import { libraryDefaultLocale } from 'generaltranslation/internal';
4
+ import type { CustomMapping } from 'generaltranslation/types';
5
+ import type {
6
+ UseDetermineLocaleParams,
7
+ UseDetermineLocaleReturn,
8
+ } from '@generaltranslation/react-core/types';
9
+ import { getNativeLocales } from '../../../utils/getNativeLocales';
10
+ import { nativeStoreGet, nativeStoreSet } from '../../../utils/nativeStore';
11
+ import { LOCALE_KEY } from '../../../utils/constants';
12
+
13
+ export function useDetermineLocale({
14
+ locale: _locale = '',
15
+ defaultLocale = libraryDefaultLocale,
16
+ locales = [],
17
+ localeCookieName = 'generaltranslation.locale',
18
+ ssr = true, // when false, breaks server side rendering by accessing document and navigator on first render
19
+ customMapping,
20
+ }: UseDetermineLocaleParams): UseDetermineLocaleReturn {
21
+ // resolve alias locale
22
+ _locale = resolveAliasLocale(_locale, customMapping);
23
+ locales = locales.map((locale) => resolveAliasLocale(locale, customMapping));
24
+
25
+ const initializeLocale = () => {
26
+ const result = resolveAliasLocale(
27
+ ssr
28
+ ? _locale
29
+ ? determineLocale(_locale, locales, customMapping) || ''
30
+ : ''
31
+ : getNewLocale({
32
+ _locale,
33
+ locale: _locale,
34
+ locales,
35
+ defaultLocale,
36
+ localeCookieName,
37
+ customMapping,
38
+ }),
39
+ customMapping
40
+ );
41
+ return result;
42
+ };
43
+
44
+ // maintaining the state of locale
45
+ const [locale, _setLocale] = useState<string>(initializeLocale());
46
+
47
+ // Functions for setting internal locale state
48
+ const [setLocale, setLocaleWithoutSettingCookie] = createSetLocale({
49
+ locale,
50
+ locales,
51
+ defaultLocale,
52
+ localeCookieName,
53
+ _setLocale,
54
+ customMapping,
55
+ });
56
+
57
+ // check browser for locales
58
+ useEffect(() => {
59
+ const newLocale = getNewLocale({
60
+ _locale,
61
+ locale,
62
+ locales,
63
+ defaultLocale,
64
+ localeCookieName,
65
+ customMapping,
66
+ });
67
+ setLocaleWithoutSettingCookie(newLocale);
68
+ }, [
69
+ _locale,
70
+ locale,
71
+ locales,
72
+ defaultLocale,
73
+ localeCookieName,
74
+ customMapping,
75
+ setLocaleWithoutSettingCookie,
76
+ ]);
77
+
78
+ return [locale, setLocale];
79
+ }
80
+
81
+ // ----- HELPER FUNCTIONS ---- //
82
+
83
+ /**
84
+ * Choose a locale to use
85
+ * (1) use provided locale
86
+ * (2) use cookie locale
87
+ * (3) use preferred locale
88
+ * (5) fallback to defaultLocale
89
+ * Update the cookie locale to be correct
90
+ */
91
+ function getNewLocale({
92
+ _locale,
93
+ locale,
94
+ locales,
95
+ defaultLocale,
96
+ customMapping,
97
+ }: {
98
+ _locale: string;
99
+ locale: string;
100
+ locales: string[];
101
+ defaultLocale: string;
102
+ localeCookieName: string;
103
+ customMapping?: CustomMapping;
104
+ }): string {
105
+ // No change, return
106
+ if (
107
+ _locale &&
108
+ _locale === locale &&
109
+ determineLocale(_locale, locales, customMapping) === locale
110
+ ) {
111
+ return resolveAliasLocale(_locale, customMapping);
112
+ }
113
+
114
+ // Check for locale in native store
115
+ let storedLocale = nativeStoreGet(LOCALE_KEY);
116
+ if (storedLocale) {
117
+ storedLocale = resolveAliasLocale(storedLocale, customMapping);
118
+ }
119
+
120
+ // check user's configured locales
121
+ let preferredLocales = getNativeLocales();
122
+ if (preferredLocales.length === 0) preferredLocales = [defaultLocale];
123
+ preferredLocales = preferredLocales.map((l) =>
124
+ resolveAliasLocale(l, customMapping)
125
+ );
126
+
127
+ // determine locale
128
+ let newLocale =
129
+ determineLocale(
130
+ [
131
+ ...(_locale ? [_locale] : []), // prefer user passed locale
132
+ ...(storedLocale ? [storedLocale] : []), // then prefer stored locale
133
+ ...preferredLocales, // then prefer browser locale
134
+ ],
135
+ locales,
136
+ customMapping
137
+ ) || defaultLocale;
138
+ if (newLocale) {
139
+ newLocale = resolveAliasLocale(newLocale, customMapping);
140
+ }
141
+
142
+ // if stored locale not valid, change it back to whatever we use for fallback
143
+ if (storedLocale && storedLocale !== newLocale) {
144
+ nativeStoreSet(LOCALE_KEY, newLocale);
145
+ }
146
+
147
+ // return new locale
148
+ return newLocale;
149
+ }
150
+
151
+ function createSetLocale({
152
+ locale,
153
+ locales,
154
+ defaultLocale,
155
+ _setLocale,
156
+ customMapping,
157
+ }: {
158
+ locale: string;
159
+ locales: string[];
160
+ defaultLocale: string;
161
+ localeCookieName: string;
162
+ _setLocale: any;
163
+ customMapping?: CustomMapping;
164
+ }): [(newLocale: string) => void, (newLocale: string) => void] {
165
+ locale = resolveAliasLocale(locale, customMapping);
166
+ const setLocaleWithoutSettingCookie = (newLocale: string): string => {
167
+ // validate locale
168
+ const validatedLocale = resolveAliasLocale(
169
+ determineLocale(newLocale, locales, customMapping) ||
170
+ locale ||
171
+ defaultLocale,
172
+ customMapping
173
+ );
174
+ if (validatedLocale !== newLocale) {
175
+ console.warn(
176
+ `[gt-react-native] Unsupported locale: ${validatedLocale} -> ${newLocale}`
177
+ );
178
+ }
179
+ // persist locale
180
+ _setLocale(validatedLocale);
181
+
182
+ return validatedLocale;
183
+ };
184
+ // update locale and store it in cookie
185
+ const setLocale = (newLocale: string): void => {
186
+ newLocale = resolveAliasLocale(newLocale, customMapping);
187
+ setLocaleWithoutSettingCookie(newLocale);
188
+ const validatedLocale = setLocaleWithoutSettingCookie(newLocale);
189
+ nativeStoreSet(LOCALE_KEY, validatedLocale);
190
+ };
191
+ return [setLocale, setLocaleWithoutSettingCookie];
192
+ }
@@ -0,0 +1,63 @@
1
+ import { useEffect, useState } from 'react';
2
+ import type {
3
+ UseRegionStateParams,
4
+ UseRegionStateReturn,
5
+ } from '@generaltranslation/react-core/types';
6
+
7
+ function getNewRegion({
8
+ _region,
9
+ }: {
10
+ _region: string | undefined;
11
+ regionCookieName: string;
12
+ }) {
13
+ // Check for region in cookie
14
+ // const cookieRegion =
15
+ // typeof document !== 'undefined'
16
+ // ? document.cookie
17
+ // .split('; ')
18
+ // .find((row) => row.startsWith(`${regionCookieName}=`))
19
+ // ?.split('=')[1]
20
+ // : undefined;
21
+ const cookieRegion = undefined;
22
+
23
+ const newRegion = _region || cookieRegion;
24
+
25
+ // // if cookie not valid, change it to newRegion
26
+ // if (
27
+ // cookieRegion &&
28
+ // cookieRegion !== newRegion &&
29
+ // typeof document !== 'undefined'
30
+ // ) {
31
+ // document.cookie = `${regionCookieName}=${newRegion};path=/`;
32
+ // }
33
+
34
+ return newRegion;
35
+ }
36
+
37
+ export function useRegionState({
38
+ _region,
39
+ ssr,
40
+ regionCookieName,
41
+ }: UseRegionStateParams): UseRegionStateReturn {
42
+ const [region, _setRegion] = useState<string | undefined>(
43
+ ssr
44
+ ? undefined
45
+ : getNewRegion({
46
+ _region,
47
+ regionCookieName,
48
+ })
49
+ );
50
+ const setRegion = (newRegion: string | undefined) => {
51
+ _setRegion(newRegion);
52
+ // if (typeof document !== 'undefined') {
53
+ // document.cookie = `${regionCookieName}=${newRegion || ''};path=/`;
54
+ // }
55
+ };
56
+ useEffect(() => {
57
+ _setRegion(getNewRegion({ _region, regionCookieName }));
58
+ }, [_region, regionCookieName]);
59
+ return {
60
+ region,
61
+ setRegion,
62
+ };
63
+ }
@@ -0,0 +1,35 @@
1
+ import type {
2
+ RenderMethod,
3
+ Translations,
4
+ CustomLoader,
5
+ GTConfig,
6
+ } from '@generaltranslation/react-core/types';
7
+ import type { CustomMapping } from 'generaltranslation/types';
8
+
9
+ export type GTProviderProps = {
10
+ children?: React.ReactNode;
11
+ projectId?: string;
12
+ devApiKey?: string;
13
+ dictionary?: any;
14
+ locales?: string[];
15
+ defaultLocale?: string;
16
+ locale?: string;
17
+ region?: string;
18
+ cacheUrl?: string;
19
+ runtimeUrl?: string;
20
+ renderSettings?: {
21
+ method: RenderMethod;
22
+ timeout?: number;
23
+ };
24
+ _versionId?: string;
25
+ ssr?: boolean;
26
+ localeCookieName?: string;
27
+ translations?: Translations | null;
28
+ loadDictionary?: CustomLoader;
29
+ loadTranslations?: CustomLoader;
30
+ config?: GTConfig;
31
+ fallback?: React.ReactNode;
32
+ customMapping?: CustomMapping;
33
+ modelProvider?: string;
34
+ [key: string]: any;
35
+ };
@@ -0,0 +1,5 @@
1
+ // Locale key used for lookups
2
+ export const LOCALE_KEY = 'generaltranslation.locale';
3
+
4
+ // Region key used for lookups
5
+ export const REGION_KEY = 'generaltranslation.region';