@tooinfinity/lingua-react 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.
package/CHANGELOG.md ADDED
@@ -0,0 +1,21 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [1.0.0] - 2025-01-14
9
+
10
+ ### Added
11
+
12
+ - `useTranslations` hook for accessing Laravel Lingua translations in React components
13
+ - `__()` translation function with support for dot notation keys (e.g., `messages.welcome`)
14
+ - Parameter replacement support using Laravel's `:placeholder` syntax
15
+ - `locale` - current locale accessor (defaults to `'en'`)
16
+ - `locales` - available locales array accessor (defaults to `['en']`)
17
+ - Full TypeScript support with exported `LinguaProps` and `TranslateFunction` types
18
+ - Support for React 18+ and React 19+
19
+ - Support for @inertiajs/react 1.0+ and 2.0+
20
+ - ESM and CommonJS dual package distribution
21
+ - Source maps for debugging
package/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 TouwfiQ Meghlaoui <touwfiqdev@gmail.com> tooinfinity
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,104 @@
1
+ # @tooinfinity/lingua-react
2
+
3
+ React bindings for [Laravel Lingua](https://github.com/tooinfinity/lingua) - seamless translations with Inertia.js.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @tooinfinity/lingua-react
9
+ ```
10
+
11
+ ## Requirements
12
+
13
+ - React 18+ or 19+
14
+ - @inertiajs/react 1.0+ or 2.0+
15
+ - Laravel Lingua (PHP package)
16
+
17
+ ## Usage
18
+
19
+ ### Basic Translation
20
+
21
+ ```tsx
22
+ import { useTranslations } from '@tooinfinity/lingua-react';
23
+
24
+ function Welcome() {
25
+ const { __, locale, locales } = useTranslations();
26
+
27
+ return (
28
+ <div>
29
+ <p>Current locale: {locale}</p>
30
+ <h1>{__('messages.welcome')}</h1>
31
+ <p>{__('messages.greeting', { name: 'John' })}</p>
32
+ </div>
33
+ );
34
+ }
35
+ ```
36
+
37
+ ### Available Returns
38
+
39
+ | Property | Type | Description |
40
+ |----------|------|-------------|
41
+ | `__` | `(key: string, replacements?: Record<string, string \| number>) => string` | Translation function (Laravel convention) |
42
+ | `locale` | `string` | Current locale (default: `'en'`) |
43
+ | `locales` | `string[]` | Available locales (default: `['en']`) |
44
+
45
+ ### Translation Keys
46
+
47
+ Use dot notation for nested translations:
48
+
49
+ ```tsx
50
+ // For translation file: { "messages": { "hello": "Hello :name" } }
51
+ __('messages.hello', { name: 'World' }) // "Hello World"
52
+ ```
53
+
54
+ ### Locale Switcher Example
55
+
56
+ ```tsx
57
+ import { useTranslations } from '@tooinfinity/lingua-react';
58
+ import { router } from '@inertiajs/react';
59
+
60
+ function LocaleSwitcher() {
61
+ const { locale, locales } = useTranslations();
62
+
63
+ const switchLocale = (newLocale: string) => {
64
+ router.post('/locale', { locale: newLocale });
65
+ };
66
+
67
+ return (
68
+ <select value={locale} onChange={(e) => switchLocale(e.target.value)}>
69
+ {locales.map((loc) => (
70
+ <option key={loc} value={loc}>
71
+ {loc.toUpperCase()}
72
+ </option>
73
+ ))}
74
+ </select>
75
+ );
76
+ }
77
+ ```
78
+
79
+ ## TypeScript
80
+
81
+ Full TypeScript support with exported types:
82
+
83
+ ```tsx
84
+ import type { LinguaProps, TranslateFunction } from '@tooinfinity/lingua-react';
85
+ ```
86
+
87
+ ## Development
88
+
89
+ ```bash
90
+ # Install dependencies
91
+ npm install
92
+
93
+ # Type check
94
+ npm run typecheck
95
+
96
+ # Build
97
+ npm run build
98
+
99
+ # Watch mode
100
+ npm run dev
101
+ ```
102
+ ## License
103
+
104
+ The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
@@ -0,0 +1,3 @@
1
+ export { useTranslations } from './useTranslations';
2
+ export type { LinguaProps, TranslateFunction } from './types';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("@inertiajs/react");function u(){const{props:n}=i.usePage(),e=n.lingua;return{__:(o,s)=>{const c=o.split(".");let t=e==null?void 0:e.translations;for(const r of c){if(t==null)break;t=t[r]}return typeof t!="string"?o:s?Object.entries(s).reduce((r,[l,a])=>r.replace(new RegExp(`:${l}`,"g"),String(a)),t):t},locale:(e==null?void 0:e.locale)??"en",locales:(e==null?void 0:e.locales)??["en"]}}exports.useTranslations=u;
2
+ //# sourceMappingURL=lingua-react.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lingua-react.cjs","sources":["../src/useTranslations.ts"],"sourcesContent":["import { usePage } from '@inertiajs/react';\n\ninterface LinguaData {\n locale: string;\n locales: string[];\n translations: Record<string, any>;\n}\n\nexport function useTranslations() {\n const { props } = usePage<{ lingua?: LinguaData; [key: string]: unknown }>();\n const lingua = props.lingua;\n\n const __ = (key: string, replacements?: Record<string, string | number>): string => {\n const keys = key.split('.');\n let value: any = lingua?.translations;\n \n for (const k of keys) {\n if (value === undefined || value === null) break;\n value = value[k];\n }\n \n if (typeof value !== 'string') return key;\n \n if (replacements) {\n return Object.entries(replacements).reduce(\n (str, [k, v]) => str.replace(new RegExp(`:${k}`, 'g'), String(v)),\n value\n );\n }\n \n return value;\n };\n\n return {\n __,\n locale: lingua?.locale ?? 'en',\n locales: lingua?.locales ?? ['en'],\n };\n}\n"],"names":["useTranslations","props","usePage","lingua","key","replacements","keys","value","k","str","v"],"mappings":"oHAQO,SAASA,GAAkB,CAChC,KAAM,CAAE,MAAAC,CAAA,EAAUC,UAAA,EACZC,EAASF,EAAM,OAuBrB,MAAO,CACL,GAtBS,CAACG,EAAaC,IAA2D,CAClF,MAAMC,EAAOF,EAAI,MAAM,GAAG,EAC1B,IAAIG,EAAaJ,GAAA,YAAAA,EAAQ,aAEzB,UAAWK,KAAKF,EAAM,CACpB,GAA2BC,GAAU,KAAM,MAC3CA,EAAQA,EAAMC,CAAC,CACjB,CAEA,OAAI,OAAOD,GAAU,SAAiBH,EAElCC,EACK,OAAO,QAAQA,CAAY,EAAE,OAClC,CAACI,EAAK,CAACD,EAAGE,CAAC,IAAMD,EAAI,QAAQ,IAAI,OAAO,IAAID,CAAC,GAAI,GAAG,EAAG,OAAOE,CAAC,CAAC,EAChEH,CAAA,EAIGA,CACT,EAIE,QAAQJ,GAAA,YAAAA,EAAQ,SAAU,KAC1B,SAASA,GAAA,YAAAA,EAAQ,UAAW,CAAC,IAAI,CAAA,CAErC"}
@@ -0,0 +1,24 @@
1
+ import { usePage as i } from "@inertiajs/react";
2
+ function u() {
3
+ const { props: s } = i(), e = s.lingua;
4
+ return {
5
+ __: (r, n) => {
6
+ const c = r.split(".");
7
+ let t = e == null ? void 0 : e.translations;
8
+ for (const o of c) {
9
+ if (t == null) break;
10
+ t = t[o];
11
+ }
12
+ return typeof t != "string" ? r : n ? Object.entries(n).reduce(
13
+ (o, [l, f]) => o.replace(new RegExp(`:${l}`, "g"), String(f)),
14
+ t
15
+ ) : t;
16
+ },
17
+ locale: (e == null ? void 0 : e.locale) ?? "en",
18
+ locales: (e == null ? void 0 : e.locales) ?? ["en"]
19
+ };
20
+ }
21
+ export {
22
+ u as useTranslations
23
+ };
24
+ //# sourceMappingURL=lingua-react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lingua-react.js","sources":["../src/useTranslations.ts"],"sourcesContent":["import { usePage } from '@inertiajs/react';\n\ninterface LinguaData {\n locale: string;\n locales: string[];\n translations: Record<string, any>;\n}\n\nexport function useTranslations() {\n const { props } = usePage<{ lingua?: LinguaData; [key: string]: unknown }>();\n const lingua = props.lingua;\n\n const __ = (key: string, replacements?: Record<string, string | number>): string => {\n const keys = key.split('.');\n let value: any = lingua?.translations;\n \n for (const k of keys) {\n if (value === undefined || value === null) break;\n value = value[k];\n }\n \n if (typeof value !== 'string') return key;\n \n if (replacements) {\n return Object.entries(replacements).reduce(\n (str, [k, v]) => str.replace(new RegExp(`:${k}`, 'g'), String(v)),\n value\n );\n }\n \n return value;\n };\n\n return {\n __,\n locale: lingua?.locale ?? 'en',\n locales: lingua?.locales ?? ['en'],\n };\n}\n"],"names":["useTranslations","props","usePage","lingua","key","replacements","keys","value","k","str","v"],"mappings":";AAQO,SAASA,IAAkB;AAChC,QAAM,EAAE,OAAAC,EAAA,IAAUC,EAAA,GACZC,IAASF,EAAM;AAuBrB,SAAO;AAAA,IACL,IAtBS,CAACG,GAAaC,MAA2D;AAClF,YAAMC,IAAOF,EAAI,MAAM,GAAG;AAC1B,UAAIG,IAAaJ,KAAA,gBAAAA,EAAQ;AAEzB,iBAAWK,KAAKF,GAAM;AACpB,YAA2BC,KAAU,KAAM;AAC3C,QAAAA,IAAQA,EAAMC,CAAC;AAAA,MACjB;AAEA,aAAI,OAAOD,KAAU,WAAiBH,IAElCC,IACK,OAAO,QAAQA,CAAY,EAAE;AAAA,QAClC,CAACI,GAAK,CAACD,GAAGE,CAAC,MAAMD,EAAI,QAAQ,IAAI,OAAO,IAAID,CAAC,IAAI,GAAG,GAAG,OAAOE,CAAC,CAAC;AAAA,QAChEH;AAAA,MAAA,IAIGA;AAAA,IACT;AAAA,IAIE,SAAQJ,KAAA,gBAAAA,EAAQ,WAAU;AAAA,IAC1B,UAASA,KAAA,gBAAAA,EAAQ,YAAW,CAAC,IAAI;AAAA,EAAA;AAErC;"}
@@ -0,0 +1,7 @@
1
+ export interface LinguaProps {
2
+ locale: string;
3
+ locales: string[];
4
+ translations: Record<string, any>;
5
+ }
6
+ export type TranslateFunction = (key: string, replacements?: Record<string, string | number>) => string;
7
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACnC;AAED,MAAM,MAAM,iBAAiB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,KAAK,MAAM,CAAC"}
@@ -0,0 +1,6 @@
1
+ export declare function useTranslations(): {
2
+ __: (key: string, replacements?: Record<string, string | number>) => string;
3
+ locale: string;
4
+ locales: string[];
5
+ };
6
+ //# sourceMappingURL=useTranslations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTranslations.d.ts","sourceRoot":"","sources":["../src/useTranslations.ts"],"names":[],"mappings":"AAQA,wBAAgB,eAAe;cAIZ,MAAM,iBAAiB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,KAAG,MAAM;;;EA0BjF"}
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@tooinfinity/lingua-react",
3
+ "version": "1.0.0",
4
+ "description": "React bindings for Laravel Lingua - translations made easy with Inertia.js",
5
+ "type": "module",
6
+ "main": "./dist/lingua-react.cjs",
7
+ "module": "./dist/lingua-react.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/lingua-react.js"
14
+ },
15
+ "require": {
16
+ "types": "./dist/index.d.ts",
17
+ "default": "./dist/lingua-react.cjs"
18
+ }
19
+ }
20
+ },
21
+ "sideEffects": false,
22
+ "files": [
23
+ "dist",
24
+ "CHANGELOG.md"
25
+ ],
26
+ "engines": {
27
+ "node": ">=18.0.0"
28
+ },
29
+ "scripts": {
30
+ "build": "vite build && tsc --emitDeclarationOnly",
31
+ "dev": "vite build --watch",
32
+ "typecheck": "tsc --noEmit",
33
+ "prepublishOnly": "npm run build"
34
+ },
35
+ "keywords": [
36
+ "laravel",
37
+ "lingua",
38
+ "react",
39
+ "inertia",
40
+ "i18n",
41
+ "translations",
42
+ "localization"
43
+ ],
44
+ "author": "TooInfinity",
45
+ "license": "MIT",
46
+ "repository": {
47
+ "type": "git",
48
+ "url": "git+https://github.com/tooinfinity/lingua-react.git"
49
+ },
50
+ "bugs": {
51
+ "url": "https://github.com/tooinfinity/lingua-react/issues"
52
+ },
53
+ "homepage": "https://github.com/tooinfinity/lingua-react#readme",
54
+ "peerDependencies": {
55
+ "@inertiajs/react": "^1.0.0 || ^2.0.0",
56
+ "react": "^18.0.0 || ^19.0.0"
57
+ },
58
+ "devDependencies": {
59
+ "@inertiajs/react": "^2.0.0",
60
+ "@types/node": "^25.0.8",
61
+ "@types/react": "^18.2.0",
62
+ "react": "^18.2.0",
63
+ "typescript": "^5.3.0",
64
+ "vite": "^6.0.0",
65
+ "vite-plugin-dts": "^4.0.0"
66
+ }
67
+ }