@magic-translate/react 1.17.2 → 1.18.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/README.md CHANGED
@@ -2,7 +2,26 @@
2
2
 
3
3
  [![NPM](https://img.shields.io/npm/v/@magic-translate/react.svg)](https://www.npmjs.com/package/@magic-translate/react)
4
4
  [![npm](https://img.shields.io/npm/dm/@magic-translate/react.svg)](https://www.npmjs.com/package/@magic-translate/react)
5
- ![GitHub](https://img.shields.io/github/license/omnibrain/@magic-translate/react)
5
+
6
+ React client for [Magic Translate](https://magictranslate.io), AI-powered i18n
7
+ without translation keys or language files. Write your components in one
8
+ language, wrap the text in `<T>`, and Magic Translate translates it on the fly.
9
+
10
+ ```tsx
11
+ <button>
12
+ <T>Create chord chart</T>
13
+ </button>
14
+ ```
15
+
16
+ No `t('editor.toolbar.create')`, no `en.json` / `de.json` to keep in sync, and
17
+ adding a language is one line. Translations are cached and can be edited by
18
+ hand in the dashboard.
19
+
20
+ Requires React 17 or newer. For server-side rendering with Next.js or React
21
+ Server Components, use
22
+ [`@magic-translate/react-ssr`](https://www.npmjs.com/package/@magic-translate/react-ssr).
23
+
24
+ Full docs: [magictranslate.io/docs/react](https://magictranslate.io/docs/react)
6
25
 
7
26
  ## Install
8
27
 
@@ -16,10 +35,164 @@ Or with yarn:
16
35
  yarn add @magic-translate/react
17
36
  ```
18
37
 
38
+ ## Setup
39
+
40
+ Wrap your app in `MagicTranslateProvider`. You can get an API key for free at
41
+ [magictranslate.io](https://magictranslate.io).
42
+
43
+ ```tsx
44
+ // main.tsx
45
+ import { createRoot } from 'react-dom/client';
46
+ import { MagicTranslateProvider } from '@magic-translate/react';
47
+ import App from './App';
48
+
49
+ createRoot(document.getElementById('root')!).render(
50
+ <MagicTranslateProvider apiKey="YOUR_API_KEY" language="de">
51
+ <App />
52
+ </MagicTranslateProvider>
53
+ );
54
+ ```
55
+
19
56
  ## Usage
20
57
 
21
- ## API / Props
58
+ ### `<T>` component
59
+
60
+ Wrap any text, including plain HTML, in `<T>`. The original content is shown
61
+ until its translation has loaded.
62
+
63
+ ```tsx
64
+ import { T } from '@magic-translate/react';
65
+
66
+ export const Welcome = ({ name }: { name: string }) => (
67
+ <>
68
+ <h1>
69
+ <T>Welcome to our shop</T>
70
+ </h1>
71
+ <p>
72
+ <T>
73
+ Click <a href="/sale">here</a> to see <b>today's</b> deals.
74
+ </T>
75
+ </p>
76
+ <p>
77
+ <T>Hello {name}</T>
78
+ </p>
79
+ </>
80
+ );
81
+ ```
82
+
83
+ The content is re-translated whenever it changes, for example when `name`
84
+ changes in the example above.
85
+
86
+ All translations requested at the same time are sent to the API in a single
87
+ request, and translations are cached, so you can use as many `<T>` components
88
+ as you like.
89
+
90
+ Only text and plain HTML elements are allowed inside `<T>`. React components
91
+ are not, because they cannot survive the translation; `<T>` throws if it finds
92
+ one. Translate inside the component instead, or pass the translated string down
93
+ as a prop.
94
+
95
+ ### `useTranslate`
96
+
97
+ Use `useTranslate` (or its alias `useT`) for plain strings, such as attributes,
98
+ or anywhere a component does not fit:
99
+
100
+ ```tsx
101
+ import { useTranslate } from '@magic-translate/react';
102
+
103
+ export const Search = () => {
104
+ const t = useTranslate();
105
+
106
+ return <input placeholder={t('Search products')} />;
107
+ };
108
+ ```
109
+
110
+ `t` returns the original text until the translation has loaded, and the
111
+ component re-renders once it has.
112
+
113
+ ### Variables
114
+
115
+ Wrap values that change, such as names or counts, in `v()`. The text around
116
+ them is translated once as a template, `You have {0} unread messages`, and
117
+ cached, however many different values it is shown with. The values themselves
118
+ are never sent to the API.
119
+
120
+ ```tsx
121
+ import { T, v } from '@magic-translate/react';
122
+
123
+ <T>
124
+ Hello {v(user.name)}, you have {v(count)} unread messages
125
+ </T>;
126
+ ```
127
+
128
+ The placeholders are numbered in order, and a translation can move them to
129
+ wherever the language needs them. `v()` can also hold a React component, such
130
+ as a link.
131
+
132
+ With `t`, use a tagged template. Every `${}` value is treated the same way:
133
+
134
+ ```tsx
135
+ const t = useTranslate();
136
+
137
+ t`You have ${count} unread messages`;
138
+ ```
139
+
140
+ Without `v()`, a value is translated as part of the text, so every different
141
+ value is a new translation.
142
+
143
+ ### Options per translation
144
+
145
+ Both the component and `t` can override the target language and the formality:
146
+
147
+ ```tsx
148
+ <T lang="fr" formality="formal">How are you?</T>
149
+
150
+ <input placeholder={t('Your name', { lang: 'fr', formality: 'formal' })} />
151
+ ```
152
+
153
+ ### Switching languages
154
+
155
+ `useLanguageSwitcher` reads and changes the current language. Every `<T>`
156
+ component and `t` call updates automatically.
157
+
158
+ ```tsx
159
+ import { useLanguageSwitcher } from '@magic-translate/react';
160
+
161
+ export const LanguageSwitcher = () => {
162
+ const { currentLanguage, setLanguage } = useLanguageSwitcher();
163
+
164
+ return (
165
+ <select
166
+ value={currentLanguage}
167
+ onChange={(e) => setLanguage(e.target.value as typeof currentLanguage)}
168
+ >
169
+ <option value="en">English</option>
170
+ <option value="de">Deutsch</option>
171
+ <option value="fr">Français</option>
172
+ </select>
173
+ );
174
+ };
175
+ ```
176
+
177
+ ## Configuration
178
+
179
+ `MagicTranslateProvider` accepts:
180
+
181
+ | Prop | Description |
182
+ | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
183
+ | `apiKey` | Required. Your Magic Translate API key. |
184
+ | `language` | Required. The language content is translated to, e.g. `'de'`. |
185
+ | `sourceLanguage` | The language your components are written in. Detected automatically by default; only set it if automatic detection gives wrong results. |
186
+ | `formality` | `'formal'` or `'informal'`. Not supported for all languages. Can be overridden per translation. |
187
+ | `debug` | Logs requests to the console. |
188
+
189
+ ## Other frameworks
190
+
191
+ - [`@magic-translate/react-ssr`](https://www.npmjs.com/package/@magic-translate/react-ssr): Next.js App Router and React Server Components
192
+ - [`@magic-translate/vue`](https://www.npmjs.com/package/@magic-translate/vue): Vue 3 and Nuxt
193
+ - [`@magic-translate/angular`](https://www.npmjs.com/package/@magic-translate/angular): Angular
194
+ - [`@magic-translate/js`](https://www.npmjs.com/package/@magic-translate/js): any website, with one script tag
22
195
 
23
196
  ## License
24
197
 
25
- MIT © [omnibrain](https://github.com/omnibrain)
198
+ MIT © [i42 GmbH](https://i42.ch)
@@ -1 +1 @@
1
- {"version":3,"file":"Translate.d.ts","sourceRoot":"","sources":["../../src/components/Translate.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EACZ,iBAAiB,EAKlB,MAAM,OAAO,CAAC;AAEf,OAAO,EAAE,gBAAgB,EAAe,MAAM,uBAAuB,CAAC;AAGtE,MAAM,MAAM,cAAc,GAAG,gBAAgB,CAAC;AAuB9C,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,iBAAiB,CAC7C,iBAAiB,CAAC,cAAc,CAAC,CAuFlC,CAAC;AAEF,eAAO,MAAM,CAAC,oEAAY,CAAC"}
1
+ {"version":3,"file":"Translate.d.ts","sourceRoot":"","sources":["../../src/components/Translate.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAEZ,iBAAiB,EAMlB,MAAM,OAAO,CAAC;AAEf,OAAO,EAAE,gBAAgB,EAAe,MAAM,uBAAuB,CAAC;AAItE,MAAM,MAAM,cAAc,GAAG,gBAAgB,CAAC;AA6C9C,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,iBAAiB,CAC7C,iBAAiB,CAAC,cAAc,CAAC,CAoGlC,CAAC;AAEF,eAAO,MAAM,CAAC,oEAAY,CAAC"}
@@ -1,10 +1,24 @@
1
1
  import parse from 'html-react-parser';
2
- import React, { useCallback, useEffect, useState, useRef, } from 'react';
2
+ import React, { Fragment, useCallback, useEffect, useState, useRef, } from 'react';
3
3
  import { renderToString } from 'react-dom/server';
4
4
  import { libraryName } from '@magic-translate/core';
5
5
  import { useMagicTranslate } from '../hooks/use-magic-translate';
6
+ import { extractVariables, fillPlaceholders, Variable } from './Variable';
7
+ // Values are put back as React nodes, never parsed as HTML, so a value cannot
8
+ // inject markup.
9
+ const renderTranslation = (translation, values) => values.length === 0
10
+ ? parse(translation)
11
+ : parse(translation, {
12
+ replace: (node) => {
13
+ if (node.type !== 'text' || !/\{\d+\}/.test(node.data))
14
+ return;
15
+ return (React.createElement(React.Fragment, null, fillPlaceholders(node.data, values).map((part, i) => (React.createElement(Fragment, { key: i }, part)))));
16
+ },
17
+ });
6
18
  const assertChildIsNotAReactComponent = (child) => {
7
- if ('type' in child && typeof child.type === 'function') {
19
+ if ('type' in child &&
20
+ typeof child.type === 'function' &&
21
+ child.type !== Variable) {
8
22
  let errorMsg = 'React components are not allowed inside `<T>...</T>` components.';
9
23
  if ('displayName' in child.type) {
10
24
  errorMsg += ` The component found inside the T component is ${child.type.displayName}.`;
@@ -16,6 +30,7 @@ export const Translate = ({ children, lang, formality }) => {
16
30
  const { dataLoader, language } = useMagicTranslate();
17
31
  const [translation, setTranslation] = useState(null);
18
32
  const lastRequestId = useRef(0);
33
+ const { template, values } = extractVariables(children);
19
34
  // `lang` and `formality` are destructured rather than kept as a rest object
20
35
  // so that they can be depended on by value: a rest object is a fresh
21
36
  // reference on every render and would rebuild `translate` each time.
@@ -30,6 +45,17 @@ export const Translate = ({ children, lang, formality }) => {
30
45
  });
31
46
  }, [dataLoader, lang, formality]);
32
47
  useEffect(() => {
48
+ // The values change without the template changing, so they never cause a
49
+ // new translation.
50
+ if (values.length > 0) {
51
+ React.Children.forEach(children, (child) => {
52
+ if (child && typeof child === 'object') {
53
+ assertChildIsNotAReactComponent(child);
54
+ }
55
+ });
56
+ translate(renderToString(React.createElement(React.Fragment, null, template)));
57
+ return;
58
+ }
33
59
  // single child
34
60
  if (React.Children.count(children) === 0) {
35
61
  return;
@@ -73,8 +99,8 @@ export const Translate = ({ children, lang, formality }) => {
73
99
  }
74
100
  // `language` is not read here, but a language switch has to re-translate
75
101
  // the children, so it stays an explicit trigger.
76
- }, [children, language, translate]);
77
- return React.createElement(React.Fragment, null, translation ? parse(translation) : children);
102
+ }, [children, template, values.length, language, translate]);
103
+ return React.createElement(React.Fragment, null, translation ? renderTranslation(translation, values) : children);
78
104
  };
79
105
  export const T = Translate;
80
106
  //# sourceMappingURL=Translate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Translate.js","sourceRoot":"","sources":["../../src/components/Translate.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Translate.js","sourceRoot":"","sources":["../../src/components/Translate.tsx"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ import { act, render, waitFor } from '@testing-library/react';
2
2
  import { MagicTranslateProvider } from '../context/MagicTranslateContext';
3
3
  import React, { useState } from 'react';
4
4
  import { T } from './Translate';
5
+ import { v } from './Variable';
5
6
  import { Language } from '@magic-translate/core';
6
7
  const tick = () => new Promise((resolve) => setTimeout(resolve));
7
8
  const ExampleComponent = () => React.createElement(React.Fragment, null, "Some component");
@@ -109,14 +110,9 @@ describe('Translate', () => {
109
110
  });
110
111
  it('should throw an error if there is a react component inside the translation component', async () => {
111
112
  // given
112
- try {
113
- render(React.createElement(Wrapper, null,
114
- React.createElement(T, null,
115
- React.createElement(ExampleComponent, null))));
116
- }
117
- catch (err) {
118
- expect(err.message).toContain('ExampleComponent');
119
- }
113
+ expect(() => render(React.createElement(Wrapper, null,
114
+ React.createElement(T, null,
115
+ React.createElement(ExampleComponent, null))))).toThrow('ExampleComponent');
120
116
  await act(async () => {
121
117
  await tick();
122
118
  });
@@ -125,15 +121,10 @@ describe('Translate', () => {
125
121
  });
126
122
  it('should throw an error if any child of the translate component is a react component', async () => {
127
123
  // given
128
- try {
129
- render(React.createElement(Wrapper, null,
130
- React.createElement(T, null,
131
- "test",
132
- React.createElement(ExampleComponent, null))));
133
- }
134
- catch (err) {
135
- expect(err.message).toContain('ExampleComponent');
136
- }
124
+ expect(() => render(React.createElement(Wrapper, null,
125
+ React.createElement(T, null,
126
+ "test",
127
+ React.createElement(ExampleComponent, null))))).toThrow('ExampleComponent');
137
128
  await act(async () => {
138
129
  await tick();
139
130
  });
@@ -200,5 +191,143 @@ describe('Translate', () => {
200
191
  expect(mockFn).toHaveBeenCalledTimes(2);
201
192
  });
202
193
  });
194
+ describe('variables', () => {
195
+ it('should send a template with numbered placeholders', async () => {
196
+ // given
197
+ render(React.createElement(Wrapper, null,
198
+ React.createElement(T, null,
199
+ "You have ",
200
+ v(3),
201
+ " unread messages")));
202
+ await act(async () => {
203
+ await tick();
204
+ });
205
+ // then
206
+ expect(mockFn).toHaveBeenCalledWith([
207
+ { text: 'You have {0} unread messages' },
208
+ ]);
209
+ });
210
+ it('should number the placeholders in order, including inside HTML', async () => {
211
+ // given
212
+ render(React.createElement(Wrapper, null,
213
+ React.createElement(T, null,
214
+ "Hello ",
215
+ React.createElement("b", null, v('Ann')),
216
+ ", you have ",
217
+ v(2),
218
+ " messages")));
219
+ await act(async () => {
220
+ await tick();
221
+ });
222
+ // then
223
+ expect(mockFn).toHaveBeenCalledWith([
224
+ { text: 'Hello <b>{0}</b>, you have {1} messages' },
225
+ ]);
226
+ });
227
+ it('should put the values into the translation', async () => {
228
+ // given
229
+ const { getByTestId } = render(React.createElement(Wrapper, null,
230
+ React.createElement("div", { "data-testid": "wrapper" },
231
+ React.createElement(T, null,
232
+ "Hello ",
233
+ React.createElement("b", null, v('Ann')),
234
+ ", you have ",
235
+ v(2),
236
+ " messages"))));
237
+ await act(async () => {
238
+ await tick();
239
+ });
240
+ // then
241
+ await waitFor(() => expect(getByTestId('wrapper').innerHTML).toBe('Translated: Hello <b>Ann</b>, you have 2 messages'));
242
+ });
243
+ it('should put the values where the translation moved them', async () => {
244
+ // given
245
+ const reorderingLoader = () => (content) => Promise.resolve(content.map(() => '{1} Nachrichten für {0}'));
246
+ const { getByTestId } = render(React.createElement(MagicTranslateProvider, { _loaderFactory: reorderingLoader, language: lang, apiKey: "test-api-key" },
247
+ React.createElement("div", { "data-testid": "wrapper" },
248
+ React.createElement(T, null,
249
+ "Hello ",
250
+ v('Ann'),
251
+ ", you have ",
252
+ v(2),
253
+ " messages"))));
254
+ await act(async () => {
255
+ await tick();
256
+ });
257
+ // then
258
+ await waitFor(() => expect(getByTestId('wrapper').textContent).toBe('2 Nachrichten für Ann'));
259
+ });
260
+ it('should show the values before the translation has loaded', () => {
261
+ // given
262
+ const { getByTestId } = render(React.createElement(Wrapper, null,
263
+ React.createElement("div", { "data-testid": "wrapper" },
264
+ React.createElement(T, null,
265
+ "You have ",
266
+ v(3),
267
+ " unread messages"))));
268
+ // then
269
+ expect(getByTestId('wrapper').textContent).toBe('You have 3 unread messages');
270
+ });
271
+ it('should insert a value as text, not as HTML', async () => {
272
+ // given
273
+ const { getByTestId } = render(React.createElement(Wrapper, null,
274
+ React.createElement("div", { "data-testid": "wrapper" },
275
+ React.createElement(T, null,
276
+ "Hello ",
277
+ v('<img src=x onerror=alert(1)>')))));
278
+ await act(async () => {
279
+ await tick();
280
+ });
281
+ // then
282
+ await waitFor(() => expect(getByTestId('wrapper').textContent).toBe('Translated: Hello <img src=x onerror=alert(1)>'));
283
+ expect(getByTestId('wrapper').querySelector('img')).toBeNull();
284
+ });
285
+ it('should allow a react component as a value', async () => {
286
+ // given
287
+ const { getByTestId } = render(React.createElement(Wrapper, null,
288
+ React.createElement("div", { "data-testid": "wrapper" },
289
+ React.createElement(T, null,
290
+ "See ",
291
+ v(React.createElement(ExampleComponent, null))))));
292
+ await act(async () => {
293
+ await tick();
294
+ });
295
+ // then
296
+ expect(mockFn).toHaveBeenCalledWith([{ text: 'See {0}' }]);
297
+ await waitFor(() => expect(getByTestId('wrapper').textContent).toBe('Translated: See Some component'));
298
+ });
299
+ it('should not translate again when only a value changes', async () => {
300
+ // given
301
+ const Counter = () => {
302
+ const [count, setCount] = useState(1);
303
+ return (React.createElement(React.Fragment, null,
304
+ React.createElement("button", { onClick: () => setCount(count + 1) }, "add"),
305
+ React.createElement("div", { "data-testid": "wrapper" },
306
+ React.createElement(T, null,
307
+ "You have ",
308
+ v(count),
309
+ " unread messages"))));
310
+ };
311
+ const { getByRole, getByTestId } = render(React.createElement(Wrapper, null,
312
+ React.createElement(Counter, null)));
313
+ await act(async () => {
314
+ await tick();
315
+ });
316
+ // when
317
+ await act(async () => {
318
+ getByRole('button').click();
319
+ await tick();
320
+ });
321
+ // then
322
+ expect(mockFn).toHaveBeenCalledTimes(1);
323
+ expect(getByTestId('wrapper').textContent).toBe('Translated: You have 2 unread messages');
324
+ });
325
+ it('should still reject other react components', () => {
326
+ expect(() => render(React.createElement(Wrapper, null,
327
+ React.createElement(T, null,
328
+ v(1),
329
+ React.createElement(ExampleComponent, null))))).toThrow('ExampleComponent');
330
+ });
331
+ });
203
332
  });
204
333
  //# sourceMappingURL=Translate.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Translate.test.js","sourceRoot":"","sources":["../../src/components/Translate.test.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Translate.test.js","sourceRoot":"","sources":["../../src/components/Translate.test.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import React, { ReactElement, ReactNode } from 'react';
2
+ export interface VariableProps {
3
+ value: ReactNode;
4
+ }
5
+ export declare const Variable: ({ value }: VariableProps) => React.JSX.Element;
6
+ /**
7
+ * Marks a value inside `<T>` that should not be translated, such as a name or a
8
+ * count. The text around it is translated once as a template, e.g.
9
+ * `You have {0} unread messages`, and cached no matter what the value is.
10
+ *
11
+ * ```tsx
12
+ * <T>You have {v(count)} unread messages</T>
13
+ * ```
14
+ */
15
+ export declare const v: (value: ReactNode) => ReactElement<VariableProps>;
16
+ /**
17
+ * Replaces every `v()` in `children`, including those nested in HTML elements,
18
+ * with a numbered placeholder. Placeholders are numbered in the order they
19
+ * appear, so the same `<T>` always produces the same template.
20
+ */
21
+ export declare const extractVariables: (children: ReactNode) => {
22
+ template: ReactNode;
23
+ values: ReactNode[];
24
+ };
25
+ /**
26
+ * Puts the values back into a translated text. A placeholder without a value is
27
+ * left as it is.
28
+ */
29
+ export declare const fillPlaceholders: <V>(text: string, values: readonly V[]) => (string | V)[];
30
+ //# sourceMappingURL=Variable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Variable.d.ts","sourceRoot":"","sources":["../../src/components/Variable.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,SAAS,CAAC;CAClB;AAED,eAAO,MAAM,QAAQ,GAAI,WAAW,aAAa,sBAAiB,CAAC;AAEnE;;;;;;;;GAQG;AACH,eAAO,MAAM,CAAC,GAAI,OAAO,SAAS,KAAG,YAAY,CAAC,aAAa,CAE9D,CAAC;AAOF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAC3B,UAAU,SAAS,KAClB;IAAE,QAAQ,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,SAAS,EAAE,CAAA;CAsC5C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,GAAI,CAAC,EAChC,MAAM,MAAM,EACZ,QAAQ,SAAS,CAAC,EAAE,KACnB,CAAC,MAAM,GAAG,CAAC,CAAC,EAYd,CAAC"}
@@ -0,0 +1,68 @@
1
+ import React from 'react';
2
+ export const Variable = ({ value }) => React.createElement(React.Fragment, null, value);
3
+ /**
4
+ * Marks a value inside `<T>` that should not be translated, such as a name or a
5
+ * count. The text around it is translated once as a template, e.g.
6
+ * `You have {0} unread messages`, and cached no matter what the value is.
7
+ *
8
+ * ```tsx
9
+ * <T>You have {v(count)} unread messages</T>
10
+ * ```
11
+ */
12
+ export const v = (value) => (React.createElement(Variable, { value: value }));
13
+ const PLACEHOLDER = /\{(\d+)\}/g;
14
+ const isVariable = (node) => React.isValidElement(node) && node.type === Variable;
15
+ /**
16
+ * Replaces every `v()` in `children`, including those nested in HTML elements,
17
+ * with a numbered placeholder. Placeholders are numbered in the order they
18
+ * appear, so the same `<T>` always produces the same template.
19
+ */
20
+ export const extractVariables = (children) => {
21
+ const values = [];
22
+ const walk = (nodes) =>
23
+ // Adjacent text is joined so the template reads "You have {0} messages"
24
+ // rather than having React's `<!-- -->` separators between the parts.
25
+ (React.Children.map(nodes, (node) => {
26
+ if (isVariable(node)) {
27
+ values.push(node.props.value);
28
+ return `{${values.length - 1}}`;
29
+ }
30
+ if (React.isValidElement(node) &&
31
+ typeof node.type === 'string' &&
32
+ node.props.children !== undefined) {
33
+ return React.cloneElement(node, undefined, ...walk(node.props.children));
34
+ }
35
+ return node;
36
+ }) ?? []).reduce((joined, node) => {
37
+ const last = joined[joined.length - 1];
38
+ const isText = typeof node === 'string' || typeof node === 'number';
39
+ if (isText && (typeof last === 'string' || typeof last === 'number')) {
40
+ joined[joined.length - 1] = `${last}${node}`;
41
+ }
42
+ else {
43
+ joined.push(node);
44
+ }
45
+ return joined;
46
+ }, []);
47
+ const template = walk(children);
48
+ return { template: values.length > 0 ? template : children, values };
49
+ };
50
+ /**
51
+ * Puts the values back into a translated text. A placeholder without a value is
52
+ * left as it is.
53
+ */
54
+ export const fillPlaceholders = (text, values) => {
55
+ const parts = [];
56
+ // `split` with a capturing group puts the placeholder numbers at odd indexes.
57
+ text.split(PLACEHOLDER).forEach((part, i) => {
58
+ if (i % 2 === 0) {
59
+ if (part)
60
+ parts.push(part);
61
+ return;
62
+ }
63
+ const index = Number(part);
64
+ parts.push(index < values.length ? values[index] : `{${part}}`);
65
+ });
66
+ return parts;
67
+ };
68
+ //# sourceMappingURL=Variable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Variable.js","sourceRoot":"","sources":["../../src/components/Variable.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkC,MAAM,OAAO,CAAC;AAMvD,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,EAAE,KAAK,EAAiB,EAAE,EAAE,CAAC,0CAAG,KAAK,CAAI,CAAC;AAEnE;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,KAAgB,EAA+B,EAAE,CAAC,CAClE,oBAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,GAAI,CAC3B,CAAC;AAEF,MAAM,WAAW,GAAG,YAAY,CAAC;AAEjC,MAAM,UAAU,GAAG,CAAC,IAAe,EAAuC,EAAE,CAC1E,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC;AAEvD;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,QAAmB,EAC2B,EAAE;IAChD,MAAM,MAAM,GAAgB,EAAE,CAAC;IAE/B,MAAM,IAAI,GAAG,CAAC,KAAgB,EAAe,EAAE;IAC7C,wEAAwE;IACxE,sEAAsE;IACtE,CACE,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE;QACjC,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC9B,OAAO,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC;QAClC,CAAC;QACD,IACE,KAAK,CAAC,cAAc,CAA2B,IAAI,CAAC;YACpD,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;YAC7B,IAAI,CAAC,KAAK,CAAC,QAAQ,KAAK,SAAS,EACjC,CAAC;YACD,OAAO,KAAK,CAAC,YAAY,CACvB,IAAI,EACJ,SAAS,EACT,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAC7B,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,IAAI,EAAE,CACT,CAAC,MAAM,CAAc,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;QACrC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACvC,MAAM,MAAM,GAAG,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,IAAI,KAAK,QAAQ,CAAC;QACpE,IAAI,MAAM,IAAI,CAAC,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,IAAI,KAAK,QAAQ,CAAC,EAAE,CAAC;YACrE,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC;QAC/C,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC,EAAE,EAAE,CAAC,CAAC;IAET,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;IAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;AACvE,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,IAAY,EACZ,MAAoB,EACJ,EAAE;IAClB,MAAM,KAAK,GAAmB,EAAE,CAAC;IACjC,8EAA8E;IAC9E,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QAC1C,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAChB,IAAI,IAAI;gBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3B,OAAO;QACT,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IACH,OAAO,KAAK,CAAC;AACf,CAAC,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import DataLoader from 'dataloader';
2
2
  import React, { createContext, useMemo, useState, } from 'react';
3
- import { cacheKeyFn, defaultLoaderFactory as defaultLoaderFactory, libraryWebsite, } from '@magic-translate/core';
3
+ import { cacheKeyFn, defaultLoaderFactory, libraryWebsite, } from '@magic-translate/core';
4
4
  export const MagicTranslateContext = createContext(null);
5
5
  export const MagicTranslateProvider = ({ language: passedLanguage, sourceLanguage, debug, apiKey, children, _loaderFactory = defaultLoaderFactory, _apiUrl, formality, }) => {
6
6
  if (!apiKey) {
@@ -1 +1 @@
1
- {"version":3,"file":"MagicTranslateContext.js","sourceRoot":"","sources":["../../src/context/MagicTranslateContext.tsx"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,EAAE,EACZ,aAAa,EAEb,OAAO,EACP,QAAQ,GACT,MAAM,OAAO,CAAC;AACf,OAAO,EACL,UAAU,EAGV,oBAAoB,IAAI,oBAAoB,EAE5C,cAAc,GAGf,MAAM,uBAAuB,CAAC;AAiC/B,MAAM,CAAC,MAAM,qBAAqB,GAChC,aAAa,CAAoC,IAAI,CAAC,CAAC;AAEzD,MAAM,CAAC,MAAM,sBAAsB,GAE/B,CAAC,EACH,QAAQ,EAAE,cAAc,EACxB,cAAc,EACd,KAAK,EACL,MAAM,EACN,QAAQ,EACR,cAAc,GAAG,oBAAoB,EACrC,OAAO,EACP,SAAS,GACV,EAAE,EAAE;IACH,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,sCAAsC,cAAc,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,MAAM,CAAC,mBAAmB,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAmB,IAAI,CAAC,CAAC;IAE5E,MAAM,QAAQ,GAAG,OAAO,CACtB,GAAG,EAAE,CAAC,mBAAmB,IAAI,cAAc,EAC3C,CAAC,cAAc,EAAE,mBAAmB,CAAC,CACtC,CAAC;IAEF,MAAM,KAAK,GAAG,OAAO,CACnB,GAAG,EAAE,CAAC,CAAC;QACL,UAAU,EAAE,IAAI,UAAU,CACxB,cAAc,CAAC;YACb,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,MAAM;YACN,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,cAAc;YAC1B,MAAM,EAAE,OAAO;YACf,SAAS;SACV,CAAC,EACF;YACE,UAAU,EAAE,UAAU,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,CAAC;SACzD,CACF;QACD,QAAQ;QACR,cAAc;QACd,MAAM;QACN,WAAW;KACZ,CAAC,EACF;QACE,cAAc;QACd,QAAQ;QACR,cAAc;QACd,KAAK;QACL,MAAM;QACN,OAAO;QACP,SAAS;KACV,CACF,CAAC;IAEF,OAAO,CACL,oBAAC,qBAAqB,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,IACzC,QAAQ,CACsB,CAClC,CAAC;AACJ,CAAC,CAAC"}
1
+ {"version":3,"file":"MagicTranslateContext.js","sourceRoot":"","sources":["../../src/context/MagicTranslateContext.tsx"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,EAAE,EACZ,aAAa,EAEb,OAAO,EACP,QAAQ,GACT,MAAM,OAAO,CAAC;AACf,OAAO,EACL,UAAU,EAGV,oBAAoB,EAEpB,cAAc,GAGf,MAAM,uBAAuB,CAAC;AAiC/B,MAAM,CAAC,MAAM,qBAAqB,GAChC,aAAa,CAAoC,IAAI,CAAC,CAAC;AAEzD,MAAM,CAAC,MAAM,sBAAsB,GAE/B,CAAC,EACH,QAAQ,EAAE,cAAc,EACxB,cAAc,EACd,KAAK,EACL,MAAM,EACN,QAAQ,EACR,cAAc,GAAG,oBAAoB,EACrC,OAAO,EACP,SAAS,GACV,EAAE,EAAE;IACH,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,sCAAsC,cAAc,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,MAAM,CAAC,mBAAmB,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAmB,IAAI,CAAC,CAAC;IAE5E,MAAM,QAAQ,GAAG,OAAO,CACtB,GAAG,EAAE,CAAC,mBAAmB,IAAI,cAAc,EAC3C,CAAC,cAAc,EAAE,mBAAmB,CAAC,CACtC,CAAC;IAEF,MAAM,KAAK,GAAG,OAAO,CACnB,GAAG,EAAE,CAAC,CAAC;QACL,UAAU,EAAE,IAAI,UAAU,CACxB,cAAc,CAAC;YACb,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,MAAM;YACN,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,cAAc;YAC1B,MAAM,EAAE,OAAO;YACf,SAAS;SACV,CAAC,EACF;YACE,UAAU,EAAE,UAAU,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,CAAC;SACzD,CACF;QACD,QAAQ;QACR,cAAc;QACd,MAAM;QACN,WAAW;KACZ,CAAC,EACF;QACE,cAAc;QACd,QAAQ;QACR,cAAc;QACd,KAAK;QACL,MAAM;QACN,OAAO;QACP,SAAS;KACV,CACF,CAAC;IAEF,OAAO,CACL,oBAAC,qBAAqB,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,IACzC,QAAQ,CACsB,CAClC,CAAC;AACJ,CAAC,CAAC"}