@nerimity/solid-i18lite 1.5.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021-2023
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,223 @@
1
+ # i18next for Solid
2
+
3
+ ![npm (scoped)](https://img.shields.io/npm/v/@nerimity/solid-i18lite?color=seagreen)
4
+ [![codecov](https://codecov.io/gh/nerimity/solid-i18lite/branch/main/graph/badge.svg?token=RGWEZWK8T2)](https://codecov.io/gh/nerimity/solid-i18lite)
5
+ [![npm bundle size](https://img.shields.io/bundlephobia/minzip/@nerimity/solid-i18lite)](https://bundlephobia.com/package/@nerimity/solid-i18lite)
6
+
7
+ The purpose of this library is to provide ability to support [i18next](https://www.i18next.com/) library in Solid applications
8
+ with `<TransProvider />` and `<Trans />` components.
9
+
10
+ ## Table of Contents
11
+
12
+ 1. [Usage](#usage)
13
+ 1. [Simple Example](#simple-example)
14
+ 1. [Add Resources](#add-resources)
15
+ 1. [Change a Language](#change-a-language)
16
+ 1. [T Function](#t-function)
17
+ 1. [Interpolation](#interpolation)
18
+ 1. [Nested JSX](#nested-jsx)
19
+ 1. [API](#api)
20
+ 1. [Components](#components)
21
+ 1. [Utilities](#utilities)
22
+
23
+ ## Usage
24
+
25
+ Installation:
26
+
27
+ ```sh
28
+ npm install @nerimity/solid-i18lite i18next --save
29
+ ```
30
+
31
+ ### Simple Example
32
+
33
+ `<TransProvider />` must wrap Solid application's most parent component (e.g. `<App />`). `<Trans />` component's `key` property is mandatory.
34
+
35
+ Default value can be wrapped with `<Trans />` component or set with `options` or `children` property.
36
+
37
+ ```tsx
38
+ // esm
39
+ import { TransProvider, Trans } from '@nerimity/solid-i18lite';
40
+
41
+ // cjs
42
+ const { TransProvider, Trans } = require('@nerimity/solid-i18lite');
43
+
44
+ render(() => (
45
+ <TransProvider>
46
+ <App>
47
+ <Trans key="greeting" />
48
+ {/* or */}
49
+ <Trans key="greeting">Hello!</Trans>
50
+ {/* or */}
51
+ <Trans key="greeting" options={{ defaultValue: 'Hello!' }} />
52
+ {/* or */}
53
+ <Trans key="greeting" options="Hello!" />
54
+ {/* or */}
55
+ <Trans key="greeting" children="Hello!" />
56
+ </App>
57
+ </TransProvider>
58
+ ));
59
+ ```
60
+
61
+ ### Add Resources
62
+
63
+ Resources can be added on initialization with `options` property in `<TransProvider />` or
64
+ by calling `addResources` method from `TransContext`, which can be got with `useTransContext()`.
65
+
66
+ ```tsx
67
+ import { Trans, TransProvider, useTransContext } from '@nerimity/solid-18lite';
68
+
69
+ const resources = {
70
+ lt: {...},
71
+ pl: {...},
72
+ };
73
+
74
+ render(() => <TransProvider options={{ resources }} children={<App />} />, container);
75
+
76
+ {/* or */}
77
+
78
+ const Component = () => {
79
+ const [, actions] = useTransContext();
80
+ actions.addResources('lt', 'translation', resources.lt);
81
+ actions.addResources('pl', 'translation', resources.pl);
82
+
83
+ return <Trans key="greeting">Hello!</Trans>;
84
+ };
85
+ ```
86
+
87
+ ### Change a Language
88
+
89
+ Default language can be provided to `<TransProvider />` with `lng` or `options` property.
90
+
91
+ `options.lng` overrides `lng` property.
92
+
93
+ ```tsx
94
+ <TransProvider lng="lt" children={...} />
95
+ <TransProvider options={{lng: 'pl'}} children={...} />
96
+ ```
97
+
98
+ To change a language you need to use `TransContext` and call `changeLanguage`.
99
+
100
+ ```tsx
101
+ import { useTransContext } from '@nerimity/solid-18lite';
102
+
103
+ const Component = () => {
104
+ const [, { changeLanguage }] = useTransContext();
105
+
106
+ return (
107
+ <article>
108
+ <button type="button" onClick={() => changeLanguage('en')}>
109
+ English
110
+ </button>
111
+ <button type="button" onClick={() => changeLanguage('lt')}>
112
+ Lietuvių
113
+ </button>
114
+ </article>
115
+ );
116
+ };
117
+ ```
118
+
119
+ ### T Function
120
+
121
+ **i18next** have `t` function, which is essential and sometimes there is need to use it without `<Trans />` component.
122
+ `TransContext` provides it in case you need it.
123
+
124
+ ```tsx
125
+ const Component = () => {
126
+ const [t] = useTransContext();
127
+ const messages = {
128
+ get greeting() {
129
+ return t('greeting', 'Hello!');
130
+ },
131
+ get bye() {
132
+ return t('bye', 'Bye!');
133
+ },
134
+ };
135
+
136
+ return <>{isLogin() ? messages.greeting : messages.bye}</>;
137
+ };
138
+ ```
139
+
140
+ ## Interpolation
141
+
142
+ Default interpolation uses `{{` and `}}` as prefix and suffix. Solid uses `{` and `}` for properties propagation. In that case
143
+ messages with default interpolation must be put as string. Placeholder values should be provided
144
+ through `options` property of `<Trans />` component.
145
+
146
+ ```tsx
147
+ <Trans key="greeting" options={{ name: 'John Doe' }}>
148
+ {'Hello {{name}}!'}
149
+ </Trans>
150
+ ```
151
+
152
+ **i18next** also allows to define custom interpolation prefix and suffix.
153
+
154
+ ```tsx
155
+ const resources = { lt: { greeting: 'Labas, ##name##!' } };
156
+ const interpolation = { prefix: '##', suffix: '##' };
157
+
158
+ <TransProvider options={{ interpolation, resources }}>
159
+ <Trans key="greeting" options={{ name: 'John Doe' }}>
160
+ Hello ##name##!
161
+ </Trans>
162
+ </TransProvider>;
163
+ ```
164
+
165
+ ### Nested JSX
166
+
167
+ This library supports nested JSX messages, like [react-i18next](https://react.i18next.com/latest/trans-component). If you want use this feature, you need to install [html-parse-string](https://github.com/ryansolid/html-parse-string) separately:
168
+
169
+ ```sh
170
+ npm i html-parse-string
171
+ ```
172
+
173
+ Then you can define your translation strings, like described in [How to get the correct translation string?](https://react.i18next.com/latest/trans-component#how-to-get-the-correct-translation-string).
174
+
175
+ ```tsx
176
+ const resources = {
177
+ lt: { translation: { greeting_nested: '<0>Sveiki, {{fullName}}! </0><1>Tavo profilis</1>.' } },
178
+ };
179
+
180
+ <TransProvider options={{ interpolation, resources }}>
181
+ <Trans key="greeting_nested" options={{ name: 'John Doe' }}>
182
+ {'Hello {{ name }}! '}
183
+ <a href="/profile">Your Profile</a>.
184
+ </Trans>
185
+ </TransProvider>;
186
+ ```
187
+
188
+ Keep in mind that elements, with interpolation, must be a string, e.g: `'Hello {{name}}!'`.
189
+
190
+ ## API
191
+
192
+ ### Components
193
+
194
+ #### `<TransProvider />`
195
+
196
+ | Property | Description | Required |
197
+ | -------- | ------------------------------------------------------------------------------------------------ | -------- |
198
+ | instance | i18next instance, see: [i18n](https://www.i18next.com/overview/api) | No |
199
+ | lng | default language, `options.lng` overrides it | No |
200
+ | options | i18next init options, see: [InitOptions](https://www.i18next.com/overview/configuration-options) | No |
201
+
202
+ #### `<Trans />`
203
+
204
+ | Property | Description | Required |
205
+ | -------- | ------------------------------------------------------------------------------------------------------------------------- | -------- |
206
+ | key | translation key or keys [TFunctionKeys](https://www.i18next.com/translation-function/essentials) | Yes |
207
+ | options | t function's options, see: [TOptions \| string](https://www.i18next.com/translation-function/essentials#overview-options) | No |
208
+
209
+ ### Utilities
210
+
211
+ #### `useTransContext`
212
+
213
+ `useTransContext` function returns `TransContext` as array: `[TFunction, TransProviderActions]`.
214
+
215
+ The first item is `t` function, second - the list of actions, which are listed below.
216
+
217
+ `TransProviderActions`
218
+
219
+ | Function | Description |
220
+ | ------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ |
221
+ | addResources(<br/>&nbsp;&nbsp;lng, <br/>&nbsp;&nbsp;ns, <br/>&nbsp;&nbsp;resources, <br/>&nbsp;&nbsp;bundleOptions?: { deep?; overwrite? }<br/>) | adds translation resources, see [addResourcesBundle](https://www.i18next.com/overview/api#addresourcebundle) |
222
+ | changeLanguage(lng) | changes language and sets new t function |
223
+ | getI18next | returns **i18next** instance, see [i18n](https://www.i18next.com/overview/api) |
@@ -0,0 +1,142 @@
1
+ import { createComponent as I, memo as v } from "solid-js/web";
2
+ import { useContext as P, createContext as w, createSignal as L, children as $ } from "solid-js";
3
+ let S = {}, E = "translation", x = "";
4
+ const T = { resources: {}, interpolation: { prefix: "{{", suffix: "}}" } };
5
+ let f = T;
6
+ const R = (t) => t.replace(/[-|\\{}()[\]^$+*?.]/g, (e) => e === "-" ? "\\x2d" : `\\${e}`), m = /* @__PURE__ */ new Map(), M = (t, e) => {
7
+ if (!t) return "";
8
+ const n = f?.interpolation, r = n?.prefix ?? "{{", s = n?.suffix ?? "}}", a = r + "|" + s;
9
+ let o = m.get(a);
10
+ if (!o) {
11
+ const i = R(r), u = R(s);
12
+ o = new RegExp(`${i}\\s*(\\w+)\\s*${u}`, "g"), m.set(a, o);
13
+ }
14
+ return t.replace(o, (i, u) => Object.prototype.hasOwnProperty.call(e, u) ? e[u] : i);
15
+ }, h = (t, e, n) => {
16
+ let r = j(c.language, E, t) ?? (typeof e == "string" ? e : t);
17
+ return n || typeof e == "object" && e !== null ? M(r, n || e) : r;
18
+ }, B = (t, e) => {
19
+ S[t] = e;
20
+ }, F = (t, e) => {
21
+ f = T, t && (f = { ...t, interpolation: t?.interpolation || {} }, f.interpolation.prefix = t.interpolation?.prefix || "{{", f.interpolation.suffix = t.interpolation?.suffix || "}}"), x = t?.lng || "", c.store = { data: f.resources || {} }, f.resources = {}, e?.(null, h);
22
+ }, J = (t) => (x = t, Promise.resolve(h)), b = (t, e, n = !0) => {
23
+ const r = t;
24
+ for (const s in e) {
25
+ const a = r[s], o = e[s];
26
+ o && typeof o == "object" && !Array.isArray(o) ? ((typeof a != "object" || Array.isArray(a)) && (r[s] = {}), b(r[s], o, n)) : (n || a === void 0) && (r[s] = o);
27
+ }
28
+ return t;
29
+ }, V = (t, e, n, r = !0, s = !0) => {
30
+ c.store = c.store || { data: {} }, c.store.data = c.store.data || {}, c.store.data[t] = c.store.data[t] || {}, c.store.data[t][e] = c.store.data[t][e] || {};
31
+ const a = c.store.data[t][e], o = n;
32
+ return r ? b(a, o, s) : c.store.data[t][e] = s ? o : { ...o, ...a }, (S.loaded || (() => {
33
+ }))(t, e), c;
34
+ }, j = (t, e, n, r) => {
35
+ const s = c.store;
36
+ if (!s) return;
37
+ const a = s.data?.[t];
38
+ if (!a) return;
39
+ const o = a[e];
40
+ if (!o || typeof o == "string") return;
41
+ const i = r?.keySeparator ?? c.options?.keySeparator ?? ".";
42
+ if (i === !1) return o[n];
43
+ const u = String(i);
44
+ if (n.indexOf(u) === -1) return o[n];
45
+ let l = o, y = 0;
46
+ for (let d = 0; d <= n.length; d++)
47
+ if (d === n.length || n[d] === u) {
48
+ const C = n.slice(y, d);
49
+ if (l == null || !(C in l)) return;
50
+ l = l[C], y = d + 1;
51
+ }
52
+ return l;
53
+ }, X = () => c, c = {
54
+ get language() {
55
+ return x;
56
+ },
57
+ createInstance: X,
58
+ t: h,
59
+ on: B,
60
+ init: F,
61
+ changeLanguage: J,
62
+ addResourceBundle: V,
63
+ options: f,
64
+ getResource: j
65
+ }, A = w();
66
+ function H(t, e) {
67
+ const [n, r] = L(e.resources ? t.t : () => null);
68
+ t.on("loaded", () => r(() => t.t)), t.init(e, (o, i) => r(() => i));
69
+ async function s(o) {
70
+ const i = await t.changeLanguage(o);
71
+ r(() => i);
72
+ }
73
+ function a(o, i, u, l = {}) {
74
+ return t.addResourceBundle(o, i, u, l.deep, l.overwrite);
75
+ }
76
+ return [((...o) => n().apply(null, o)), {
77
+ addResources: a,
78
+ getI18next: () => t,
79
+ changeLanguage: s
80
+ }];
81
+ }
82
+ const K = () => P(A), Y = (t) => I(A.Provider, {
83
+ get value() {
84
+ return H(t.instance || c, {
85
+ lng: t.lng,
86
+ ...t.options
87
+ });
88
+ },
89
+ get children() {
90
+ return t.children;
91
+ }
92
+ }), g = (t, { prefix: e, suffix: n }) => t.includes(e) && t.includes(n), W = (t, { interpolation: e }) => (n, r) => typeof n == "string" ? g(n, e) ? t.children[r].children?.[0].content : t.children[r].content : (n.textContent = t.children[r].children?.[0].content, n), _ = !globalThis.window, q = (t, e, n) => (r) => {
93
+ const s = typeof r;
94
+ if (s === "string" && g(r, e.interpolation)) return t(r, n.options);
95
+ if (s === "object") {
96
+ const a = r.textContent ?? r.t;
97
+ a && g(a, e.interpolation) && (r[_ ? "t" : "textContent"] = t(a, n.options));
98
+ }
99
+ return r;
100
+ };
101
+ let p;
102
+ (async () => {
103
+ try {
104
+ p = (await import("html-parse-string")).parse;
105
+ } catch {
106
+ }
107
+ })();
108
+ const z = () => {
109
+ console.error(
110
+ "In order to use JSX nesting, install %chtml-parse-string",
111
+ "font-weight: 700",
112
+ "https://github.com/ryansolid/html-parse-string."
113
+ );
114
+ }, G = ({ i18n: { options: t }, t: e, props: n }, r) => {
115
+ const s = e(n.key, n.options);
116
+ if (!n.children) return s;
117
+ if (s === n.key) return r.map(q(e, t, n));
118
+ if (!p) {
119
+ z();
120
+ return;
121
+ }
122
+ try {
123
+ const [a] = p(`<0>${s}</0>`);
124
+ return r.map(W(a, t));
125
+ } catch (a) {
126
+ console.error(a);
127
+ }
128
+ }, Z = (t) => {
129
+ const [e, {
130
+ getI18next: n
131
+ }] = K();
132
+ return v(() => v(() => typeof t.children == "string")() ? e(t.key, t.children, t.options) : G({
133
+ i18n: n(),
134
+ t: e,
135
+ props: t
136
+ }, $(() => t.children)()));
137
+ };
138
+ export {
139
+ Z as Trans,
140
+ Y as TransProvider,
141
+ K as useTransContext
142
+ };
package/dist/ssr.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";var L=Object.create;var T=Object.defineProperty;var $=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var M=Object.getPrototypeOf,E=Object.prototype.hasOwnProperty;var J=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of m(e))!E.call(t,o)&&o!==n&&T(t,o,{get:()=>e[o],enumerable:!(r=$(e,o))||r.enumerable});return t};var q=(t,e,n)=>(n=t!=null?L(M(t)):{},J(e||!t||!t.__esModule?T(n,"default",{value:t,enumerable:!0}):n,t));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const g=require("solid-js"),B=require("solid-js/web");let R={},F="translation",h="";const P={resources:{},interpolation:{prefix:"{{",suffix:"}}"}};let f=P;const S=t=>t.replace(/[-|\\{}()[\]^$+*?.]/g,e=>e==="-"?"\\x2d":`\\${e}`),b=new Map,V=(t,e)=>{if(!t)return"";const n=f?.interpolation,r=n?.prefix??"{{",o=n?.suffix??"}}",a=r+"|"+o;let s=b.get(a);if(!s){const i=S(r),u=S(o);s=new RegExp(`${i}\\s*(\\w+)\\s*${u}`,"g"),b.set(a,s)}return t.replace(s,(i,u)=>Object.prototype.hasOwnProperty.call(e,u)?e[u]:i)},y=(t,e,n)=>{let r=w(c.language,F,t)??(typeof e=="string"?e:t);return n||typeof e=="object"&&e!==null?V(r,n||e):r},X=(t,e)=>{R[t]=e},H=(t,e)=>{f=P,t&&(f={...t,interpolation:t?.interpolation||{}},f.interpolation.prefix=t.interpolation?.prefix||"{{",f.interpolation.suffix=t.interpolation?.suffix||"}}"),h=t?.lng||"",c.store={data:f.resources||{}},f.resources={},e?.(null,y)},K=t=>(h=t,Promise.resolve(y)),j=(t,e,n=!0)=>{const r=t;for(const o in e){const a=r[o],s=e[o];s&&typeof s=="object"&&!Array.isArray(s)?((typeof a!="object"||Array.isArray(a))&&(r[o]={}),j(r[o],s,n)):(n||a===void 0)&&(r[o]=s)}return t},W=(t,e,n,r=!0,o=!0)=>{c.store=c.store||{data:{}},c.store.data=c.store.data||{},c.store.data[t]=c.store.data[t]||{},c.store.data[t][e]=c.store.data[t][e]||{};const a=c.store.data[t][e],s=n;return r?j(a,s,o):c.store.data[t][e]=o?s:{...s,...a},(R.loaded||(()=>{}))(t,e),c},w=(t,e,n,r)=>{const o=c.store;if(!o)return;const a=o.data?.[t];if(!a)return;const s=a[e];if(!s||typeof s=="string")return;const i=r?.keySeparator??c.options?.keySeparator??".";if(i===!1)return s[n];const u=String(i);if(n.indexOf(u)===-1)return s[n];let l=s,v=0;for(let d=0;d<=n.length;d++)if(d===n.length||n[d]===u){const C=n.slice(v,d);if(l==null||!(C in l))return;l=l[C],v=d+1}return l},_=()=>c,c={get language(){return h},createInstance:_,t:y,on:X,init:H,changeLanguage:K,addResourceBundle:W,options:f,getResource:w},A=g.createContext();function z(t,e){const[n,r]=g.createSignal(e.resources?t.t:()=>null);t.on("loaded",()=>r(()=>t.t)),t.init(e,(s,i)=>r(()=>i));async function o(s){const i=await t.changeLanguage(s);r(()=>i)}function a(s,i,u,l={}){return t.addResourceBundle(s,i,u,l.deep,l.overwrite)}return[((...s)=>n().apply(null,s)),{addResources:a,getI18next:()=>t,changeLanguage:o}]}const I=()=>g.useContext(A),G=t=>B.createComponent(A.Provider,{get value(){return z(t.instance||c,{lng:t.lng,...t.options})},get children(){return t.children}}),x=(t,{prefix:e,suffix:n})=>t.includes(e)&&t.includes(n),Q=(t,{interpolation:e})=>(n,r)=>typeof n=="string"?x(n,e)?t.children[r].children?.[0].content:t.children[r].content:(n.textContent=t.children[r].children?.[0].content,n),U=!globalThis.window,Y=(t,e,n)=>r=>{const o=typeof r;if(o==="string"&&x(r,e.interpolation))return t(r,n.options);if(o==="object"){const a=r.textContent??r.t;a&&x(a,e.interpolation)&&(r[U?"t":"textContent"]=t(a,n.options))}return r};let p;(async()=>{try{p=(await import("html-parse-string")).parse}catch{}})();const Z=()=>{console.error("In order to use JSX nesting, install %chtml-parse-string","font-weight: 700","https://github.com/ryansolid/html-parse-string.")},k=({i18n:{options:t},t:e,props:n},r)=>{const o=e(n.key,n.options);if(!n.children)return o;if(o===n.key)return r.map(Y(e,t,n));if(!p){Z();return}try{const[a]=p(`<0>${o}</0>`);return r.map(Q(a,t))}catch(a){console.error(a)}},N=t=>{const[e,{getI18next:n}]=I();return typeof t.children=="string"?e(t.key,t.children,t.options):k({i18n:n(),t:e,props:t},g.children(()=>t.children)())};exports.Trans=N;exports.TransProvider=G;exports.useTransContext=I;
package/dist/ssr.mjs ADDED
@@ -0,0 +1,142 @@
1
+ import { useContext as A, createContext as I, createSignal as P, children as w } from "solid-js";
2
+ import { createComponent as L } from "solid-js/web";
3
+ let S = {}, $ = "translation", x = "";
4
+ const T = { resources: {}, interpolation: { prefix: "{{", suffix: "}}" } };
5
+ let f = T;
6
+ const v = (t) => t.replace(/[-|\\{}()[\]^$+*?.]/g, (e) => e === "-" ? "\\x2d" : `\\${e}`), R = /* @__PURE__ */ new Map(), E = (t, e) => {
7
+ if (!t) return "";
8
+ const n = f?.interpolation, r = n?.prefix ?? "{{", s = n?.suffix ?? "}}", a = r + "|" + s;
9
+ let o = R.get(a);
10
+ if (!o) {
11
+ const i = v(r), u = v(s);
12
+ o = new RegExp(`${i}\\s*(\\w+)\\s*${u}`, "g"), R.set(a, o);
13
+ }
14
+ return t.replace(o, (i, u) => Object.prototype.hasOwnProperty.call(e, u) ? e[u] : i);
15
+ }, h = (t, e, n) => {
16
+ let r = m(c.language, $, t) ?? (typeof e == "string" ? e : t);
17
+ return n || typeof e == "object" && e !== null ? E(r, n || e) : r;
18
+ }, M = (t, e) => {
19
+ S[t] = e;
20
+ }, B = (t, e) => {
21
+ f = T, t && (f = { ...t, interpolation: t?.interpolation || {} }, f.interpolation.prefix = t.interpolation?.prefix || "{{", f.interpolation.suffix = t.interpolation?.suffix || "}}"), x = t?.lng || "", c.store = { data: f.resources || {} }, f.resources = {}, e?.(null, h);
22
+ }, F = (t) => (x = t, Promise.resolve(h)), b = (t, e, n = !0) => {
23
+ const r = t;
24
+ for (const s in e) {
25
+ const a = r[s], o = e[s];
26
+ o && typeof o == "object" && !Array.isArray(o) ? ((typeof a != "object" || Array.isArray(a)) && (r[s] = {}), b(r[s], o, n)) : (n || a === void 0) && (r[s] = o);
27
+ }
28
+ return t;
29
+ }, J = (t, e, n, r = !0, s = !0) => {
30
+ c.store = c.store || { data: {} }, c.store.data = c.store.data || {}, c.store.data[t] = c.store.data[t] || {}, c.store.data[t][e] = c.store.data[t][e] || {};
31
+ const a = c.store.data[t][e], o = n;
32
+ return r ? b(a, o, s) : c.store.data[t][e] = s ? o : { ...o, ...a }, (S.loaded || (() => {
33
+ }))(t, e), c;
34
+ }, m = (t, e, n, r) => {
35
+ const s = c.store;
36
+ if (!s) return;
37
+ const a = s.data?.[t];
38
+ if (!a) return;
39
+ const o = a[e];
40
+ if (!o || typeof o == "string") return;
41
+ const i = r?.keySeparator ?? c.options?.keySeparator ?? ".";
42
+ if (i === !1) return o[n];
43
+ const u = String(i);
44
+ if (n.indexOf(u) === -1) return o[n];
45
+ let l = o, y = 0;
46
+ for (let d = 0; d <= n.length; d++)
47
+ if (d === n.length || n[d] === u) {
48
+ const C = n.slice(y, d);
49
+ if (l == null || !(C in l)) return;
50
+ l = l[C], y = d + 1;
51
+ }
52
+ return l;
53
+ }, V = () => c, c = {
54
+ get language() {
55
+ return x;
56
+ },
57
+ createInstance: V,
58
+ t: h,
59
+ on: M,
60
+ init: B,
61
+ changeLanguage: F,
62
+ addResourceBundle: J,
63
+ options: f,
64
+ getResource: m
65
+ }, j = I();
66
+ function X(t, e) {
67
+ const [n, r] = P(e.resources ? t.t : () => null);
68
+ t.on("loaded", () => r(() => t.t)), t.init(e, (o, i) => r(() => i));
69
+ async function s(o) {
70
+ const i = await t.changeLanguage(o);
71
+ r(() => i);
72
+ }
73
+ function a(o, i, u, l = {}) {
74
+ return t.addResourceBundle(o, i, u, l.deep, l.overwrite);
75
+ }
76
+ return [((...o) => n().apply(null, o)), {
77
+ addResources: a,
78
+ getI18next: () => t,
79
+ changeLanguage: s
80
+ }];
81
+ }
82
+ const H = () => A(j), U = (t) => L(j.Provider, {
83
+ get value() {
84
+ return X(t.instance || c, {
85
+ lng: t.lng,
86
+ ...t.options
87
+ });
88
+ },
89
+ get children() {
90
+ return t.children;
91
+ }
92
+ }), g = (t, { prefix: e, suffix: n }) => t.includes(e) && t.includes(n), K = (t, { interpolation: e }) => (n, r) => typeof n == "string" ? g(n, e) ? t.children[r].children?.[0].content : t.children[r].content : (n.textContent = t.children[r].children?.[0].content, n), W = !globalThis.window, _ = (t, e, n) => (r) => {
93
+ const s = typeof r;
94
+ if (s === "string" && g(r, e.interpolation)) return t(r, n.options);
95
+ if (s === "object") {
96
+ const a = r.textContent ?? r.t;
97
+ a && g(a, e.interpolation) && (r[W ? "t" : "textContent"] = t(a, n.options));
98
+ }
99
+ return r;
100
+ };
101
+ let p;
102
+ (async () => {
103
+ try {
104
+ p = (await import("html-parse-string")).parse;
105
+ } catch {
106
+ }
107
+ })();
108
+ const q = () => {
109
+ console.error(
110
+ "In order to use JSX nesting, install %chtml-parse-string",
111
+ "font-weight: 700",
112
+ "https://github.com/ryansolid/html-parse-string."
113
+ );
114
+ }, z = ({ i18n: { options: t }, t: e, props: n }, r) => {
115
+ const s = e(n.key, n.options);
116
+ if (!n.children) return s;
117
+ if (s === n.key) return r.map(_(e, t, n));
118
+ if (!p) {
119
+ q();
120
+ return;
121
+ }
122
+ try {
123
+ const [a] = p(`<0>${s}</0>`);
124
+ return r.map(K(a, t));
125
+ } catch (a) {
126
+ console.error(a);
127
+ }
128
+ }, Y = (t) => {
129
+ const [e, {
130
+ getI18next: n
131
+ }] = H();
132
+ return typeof t.children == "string" ? e(t.key, t.children, t.options) : z({
133
+ i18n: n(),
134
+ t: e,
135
+ props: t
136
+ }, w(() => t.children)());
137
+ };
138
+ export {
139
+ Y as Trans,
140
+ U as TransProvider,
141
+ H as useTransContext
142
+ };
@@ -0,0 +1,7 @@
1
+ import { type ParentComponent } from 'solid-js';
2
+ import type { TOptions } from './i18Lite';
3
+ export type TransProps = {
4
+ key: string;
5
+ options?: TOptions;
6
+ };
7
+ export declare const Trans: ParentComponent<TransProps>;
@@ -0,0 +1,13 @@
1
+ import { type ParentComponent } from 'solid-js';
2
+ import { type InitOptions, type TFunction, type i18n } from './i18Lite';
3
+ export type TransProviderActions = {
4
+ addResources(lng: string, ns: string, resources: any): i18n;
5
+ changeLanguage(lng: string): Promise<void>;
6
+ getI18next(): i18n;
7
+ };
8
+ export declare const useTransContext: () => [TFunction, TransProviderActions];
9
+ export declare const TransProvider: ParentComponent<{
10
+ instance?: i18n;
11
+ lng?: string;
12
+ options?: InitOptions;
13
+ }>;
@@ -0,0 +1,50 @@
1
+ export type $Dictionary<T = unknown> = {
2
+ [key: string]: T;
3
+ };
4
+ export type ResourceKey = string | {
5
+ [key: string]: any;
6
+ };
7
+ export interface ResourceLanguage {
8
+ [namespace: string]: ResourceKey;
9
+ }
10
+ export interface Resource {
11
+ [language: string]: ResourceLanguage;
12
+ }
13
+ export interface InterpolationOptions {
14
+ prefix?: string;
15
+ suffix?: string;
16
+ }
17
+ export interface InitOptions {
18
+ resources: Resource;
19
+ lng?: string;
20
+ interpolation?: InterpolationOptions;
21
+ keySeparator?: false | string;
22
+ nsSeparator?: false | string;
23
+ defaultNS?: string;
24
+ ignoreJSONStructure?: boolean;
25
+ }
26
+ export interface TOptionsBase {
27
+ lng?: string;
28
+ }
29
+ export type TOptions<TInterpolationMap extends object = $Dictionary> = TOptionsBase & TInterpolationMap;
30
+ export type TFunction = {
31
+ (key: string, options?: {}): string;
32
+ (key: string, defaultValue: string, options?: {}): string;
33
+ (key: string, arg2?: string | {}, arg3?: {}): string;
34
+ };
35
+ export interface i18n {
36
+ language: string;
37
+ getResource: (lng: string, ns: string, key: string, options?: any) => any;
38
+ createInstance: () => i18n;
39
+ t: TFunction;
40
+ on: (...args: any[]) => void;
41
+ init: (options?: InitOptions, callback?: (error: any, t: TFunction) => void) => void;
42
+ changeLanguage: (lng: string) => Promise<TFunction>;
43
+ addResourceBundle(lng: string, ns: string, resources: any, deep?: boolean, overwrite?: boolean): i18n;
44
+ store?: {
45
+ data: Resource;
46
+ };
47
+ options?: InitOptions;
48
+ }
49
+ declare const instance: i18n;
50
+ export default instance;
@@ -0,0 +1,2 @@
1
+ export { Trans, type TransProps } from './Trans';
2
+ export { TransProvider, useTransContext, type TransProviderActions } from './TransProvider';
@@ -0,0 +1,2 @@
1
+ import type { InterpolationOptions } from '../i18Lite';
2
+ export declare const hasInterpolation: (value: string, { prefix, suffix }: InterpolationOptions) => boolean;
@@ -0,0 +1,3 @@
1
+ import type { IDom } from 'html-parse-string';
2
+ import type { InitOptions } from '../i18Lite';
3
+ export declare const replaceElements: (ast: IDom, { interpolation }: InitOptions) => (child: Node, index: number) => string | Node;
@@ -0,0 +1,10 @@
1
+ import type { parse } from 'html-parse-string';
2
+ import type { ParentProps } from 'solid-js';
3
+ import type { TFunction, i18n } from '../i18Lite';
4
+ import type { TransProps } from '../Trans';
5
+ export declare let parseHTML: typeof parse;
6
+ export declare const translateJSX: ({ i18n: { options }, t, props }: {
7
+ t: TFunction;
8
+ props: ParentProps<TransProps>;
9
+ i18n: i18n;
10
+ }, children: Node[]) => string | any[];
@@ -0,0 +1,3 @@
1
+ import type { InitOptions, TFunction } from '../i18Lite';
2
+ import type { TransProps } from '../Trans';
3
+ export declare const translateWithInterpolation: (t: TFunction, options: InitOptions, props: TransProps) => (item: any) => any;
package/package.json ADDED
@@ -0,0 +1,74 @@
1
+ {
2
+ "author": "SupertigerDev",
3
+ "description": "i18next for SolidJS",
4
+ "devDependencies": {
5
+ "@babel/plugin-transform-runtime": "^7.28.3",
6
+ "@babel/preset-typescript": "^7.27.1",
7
+ "@solidjs/testing-library": "^0.8.10",
8
+ "@types/jest": "^30.0.0",
9
+ "babel-preset-solid": "^1.9.9",
10
+ "html-parse-string": "^0.0.9",
11
+ "i18next-http-backend": "^3.0.2",
12
+ "jest": "^30.2.0",
13
+ "jest-environment-jsdom": "^30.2.0",
14
+ "solid-jest": "^0.2.0",
15
+ "solid-js": "^1.9.9",
16
+ "typescript": "^5.9.3",
17
+ "vite": "^7.1.9",
18
+ "vite-plugin-solid": "^2.11.9"
19
+ },
20
+ "exports": {
21
+ ".": {
22
+ "types": "./dist/types/index.d.ts",
23
+ "browser": {
24
+ "default": "./dist/browser.mjs"
25
+ },
26
+ "import": "./dist/ssr.mjs",
27
+ "require": "./dist/ssr.js"
28
+ }
29
+ },
30
+ "files": [
31
+ "dist",
32
+ "CHANGELOG.md"
33
+ ],
34
+ "keywords": [
35
+ "i18n",
36
+ "i18next",
37
+ "internationalization",
38
+ "intl",
39
+ "language",
40
+ "localization",
41
+ "solid",
42
+ "solid-js",
43
+ "solidjs",
44
+ "translate",
45
+ "translations"
46
+ ],
47
+ "license": "MIT",
48
+ "main": "./dist/ssr.js",
49
+ "module": "./dist/ssr.mjs",
50
+ "name": "@nerimity/solid-i18lite",
51
+ "peerDependencies": {
52
+ "html-parse-string": "<=1.x",
53
+ "solid-js": ">=1.8.x"
54
+ },
55
+ "peerDependenciesMeta": {
56
+ "html-parse-string": {
57
+ "optional": true
58
+ }
59
+ },
60
+ "repository": "github:nerimity/solid-i18lite",
61
+ "scripts": {
62
+ "build:browser": "vite build --config vite.browser.config.js",
63
+ "build:docs": "vite build --config vite.docs.config.js",
64
+ "build:ssr": "vite build --config vite.ssr.config.js",
65
+ "build:types": "tsc --project tsconfig.types.json",
66
+ "docs": "vite --config vite.docs.config.js",
67
+ "test": "jest --coverage",
68
+ "test:dev": "jest"
69
+ },
70
+ "sideEffects": false,
71
+ "type": "module",
72
+ "types": "./dist/types/index.d.ts",
73
+ "version": "1.5.0"
74
+ }