langsys-js-react 0.6.7 → 0.7.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 +35 -0
- package/README-SSR.md +144 -170
- package/README.md +339 -34
- package/dist/app-zQKL7-vo.d.mts +61 -0
- package/dist/app-zQKL7-vo.d.ts +61 -0
- package/dist/babel.d.mts +122 -0
- package/dist/babel.d.ts +122 -0
- package/dist/babel.js +547 -0
- package/dist/babel.js.map +1 -0
- package/dist/babel.mjs +545 -0
- package/dist/babel.mjs.map +1 -0
- package/dist/index.d.mts +140 -76
- package/dist/index.d.ts +140 -76
- package/dist/index.js +502 -97
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +423 -89
- package/dist/index.mjs.map +1 -1
- package/dist/next-loader.d.mts +8 -0
- package/dist/next-loader.d.ts +8 -0
- package/dist/next-loader.js +623 -0
- package/dist/next-loader.js.map +1 -0
- package/dist/next-loader.mjs +621 -0
- package/dist/next-loader.mjs.map +1 -0
- package/dist/next.d.mts +15 -0
- package/dist/next.d.ts +15 -0
- package/dist/next.js +41 -0
- package/dist/next.js.map +1 -0
- package/dist/next.mjs +37 -0
- package/dist/next.mjs.map +1 -0
- package/dist/server.d.mts +36 -0
- package/dist/server.d.ts +36 -0
- package/dist/server.js +57 -0
- package/dist/server.js.map +1 -0
- package/dist/server.mjs +25 -0
- package/dist/server.mjs.map +1 -0
- package/dist/vite.d.mts +14 -0
- package/dist/vite.d.ts +14 -0
- package/dist/vite.js +623 -0
- package/dist/vite.js.map +1 -0
- package/dist/vite.mjs +621 -0
- package/dist/vite.mjs.map +1 -0
- package/package.json +38 -3
package/dist/index.mjs
CHANGED
|
@@ -1,16 +1,45 @@
|
|
|
1
|
-
import { createSignal, tSignal, currentlyLoadedLocale, sTranslations, Translate as Translate$1, Phrase as Phrase$1
|
|
2
|
-
export { LangsysAppAPI, canonicalizeLocale, createSignal, currentlyLoadedLocale, sTranslations, tSignal as t } from 'langsys-js-typescript';
|
|
3
|
-
import
|
|
1
|
+
import { LangsysApp, scopeFromSeed, createSignal, tSignal, currentlyLoadedLocale, sTranslations, writeEnabled, notifyNavigation, renderServerMessage, renderBlock, currentRequestScope, CONTENT_BLOCK_MARKER_ATTR, PHRASE_MARKER_ATTR, registerBlock, warnUnregistered, isTranslationExcluded, warnUnrenderedBlock, Translate as Translate$1, Phrase as Phrase$1 } from 'langsys-js-typescript';
|
|
2
|
+
export { DEFAULT_SERVER_MESSAGE_CATEGORY, LangsysAppAPI, LangsysConfigurationError, LegacyFormatError, SnapshotError, canonicalizeLocale, createSignal, currentlyLoadedLocale, inCategory, interpolate, isCategoryRef, localeHeaders, notifyNavigation, renderServerMessage, resolveServerMessages, sTranslations, setWriteGrant, tSignal as t } from 'langsys-js-typescript';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { createContext, useState, useInsertionEffect, createElement, useContext, useSyncExternalStore, useEffect, useMemo, useRef, isValidElement, cloneElement, Fragment, Children } from 'react';
|
|
5
|
+
import { NON_TRANSLATABLE_ELEMENTS } from 'langsys-js-typescript/pure';
|
|
4
6
|
|
|
5
7
|
// src/index.ts
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
var SeedScope = createContext(null);
|
|
9
|
+
var noSubscription = () => () => {
|
|
10
|
+
};
|
|
11
|
+
function useServerSnapshotWindow() {
|
|
12
|
+
return useSyncExternalStore(
|
|
13
|
+
noSubscription,
|
|
14
|
+
() => false,
|
|
15
|
+
() => true
|
|
16
|
+
);
|
|
8
17
|
}
|
|
18
|
+
function useSeedScopeRunner() {
|
|
19
|
+
const scope = useContext(SeedScope);
|
|
20
|
+
const inWindow = useServerSnapshotWindow();
|
|
21
|
+
return scope && inWindow ? (fn) => scope.run(fn) : (fn) => fn();
|
|
22
|
+
}
|
|
23
|
+
function LangsysProvider({ seed, children }) {
|
|
24
|
+
const [scope] = useState(() => seed ? scopeFromSeed(seed) : null);
|
|
25
|
+
useInsertionEffect(() => {
|
|
26
|
+
if (seed) LangsysApp.seedCatalog(seed.catalog, seed.locale, seed);
|
|
27
|
+
}, []);
|
|
28
|
+
return createElement(SeedScope.Provider, { value: scope }, children);
|
|
29
|
+
}
|
|
30
|
+
var LangsysApp2 = LangsysApp;
|
|
9
31
|
function createLocaleStore(initial = "en-US") {
|
|
10
32
|
return createSignal(initial);
|
|
11
33
|
}
|
|
34
|
+
|
|
35
|
+
// src/adapters.ts
|
|
36
|
+
function useSignal(signal) {
|
|
37
|
+
const scope = useContext(SeedScope);
|
|
38
|
+
return useSyncExternalStore(signal.subscribe, signal.get, scope ? () => scope.run(signal.get) : signal.get);
|
|
39
|
+
}
|
|
12
40
|
function useT() {
|
|
13
|
-
|
|
41
|
+
const scope = useContext(SeedScope);
|
|
42
|
+
return useSyncExternalStore(tSignal.subscribe, tSignal.get, scope ? () => scope.t : tSignal.get);
|
|
14
43
|
}
|
|
15
44
|
function useCurrentLocale() {
|
|
16
45
|
return useSignal(currentlyLoadedLocale);
|
|
@@ -23,123 +52,428 @@ function useLocaleStore(initial = "en-US") {
|
|
|
23
52
|
const locale = useSignal(store);
|
|
24
53
|
return [locale, store.set, store];
|
|
25
54
|
}
|
|
55
|
+
var writeEnabledServerSnapshot = () => void 0;
|
|
56
|
+
function useWriteEnabled() {
|
|
57
|
+
return useSyncExternalStore(writeEnabled.subscribe, writeEnabled.get, writeEnabledServerSnapshot);
|
|
58
|
+
}
|
|
59
|
+
function useNotifyNavigation(location) {
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
notifyNavigation();
|
|
62
|
+
}, [location]);
|
|
63
|
+
}
|
|
64
|
+
function useRenderServerMessage() {
|
|
65
|
+
const t = useT();
|
|
66
|
+
const inSeedScope = useSeedScopeRunner();
|
|
67
|
+
return useMemo(
|
|
68
|
+
() => (entry, category) => inSeedScope(() => renderServerMessage(entry, category)),
|
|
69
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
70
|
+
[t]
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
function DontTranslate({ tag = "span", className, children }) {
|
|
74
|
+
return createElement(
|
|
75
|
+
tag,
|
|
76
|
+
{ translate: "no", "data-ls-dont-translate": "", className },
|
|
77
|
+
children
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// src/block-nodes.ts
|
|
82
|
+
var PORTAL = /* @__PURE__ */ Symbol.for("react.portal");
|
|
83
|
+
var PROP_TO_ATTR = { className: "class", htmlFor: "for" };
|
|
84
|
+
function attrValue(value) {
|
|
85
|
+
if (typeof value === "function" || typeof value === "object" || value === void 0 || value === false) return void 0;
|
|
86
|
+
return value === true ? "" : String(value);
|
|
87
|
+
}
|
|
88
|
+
function attrsOf(props) {
|
|
89
|
+
const out = {};
|
|
90
|
+
for (const [name, value] of Object.entries(props)) {
|
|
91
|
+
if (name === "children" || name === "key" || name === "ref") continue;
|
|
92
|
+
const attr = attrValue(value);
|
|
93
|
+
if (attr !== void 0) out[PROP_TO_ATTR[name] ?? name] = attr;
|
|
94
|
+
}
|
|
95
|
+
return Object.keys(out).length ? out : void 0;
|
|
96
|
+
}
|
|
97
|
+
var CONTEXT = /* @__PURE__ */ Symbol.for("react.context");
|
|
98
|
+
var read = React.use;
|
|
99
|
+
function isContext(node) {
|
|
100
|
+
return typeof node === "object" && node !== null && node.$$typeof === CONTEXT;
|
|
101
|
+
}
|
|
102
|
+
function isUsable(node) {
|
|
103
|
+
if (typeof node !== "object" || node === null) return false;
|
|
104
|
+
return typeof node.then === "function" || node.$$typeof === CONTEXT;
|
|
105
|
+
}
|
|
106
|
+
function isParamValue(value) {
|
|
107
|
+
return typeof value === "string" || typeof value === "number" || typeof value === "boolean" || isDate(value);
|
|
108
|
+
}
|
|
109
|
+
function isDate(value) {
|
|
110
|
+
return Object.prototype.toString.call(value) === "[object Date]";
|
|
111
|
+
}
|
|
112
|
+
var oneShotItems = /* @__PURE__ */ new WeakMap();
|
|
113
|
+
function itemsOf(list) {
|
|
114
|
+
if (list[Symbol.iterator]() !== list) return Array.from(list);
|
|
115
|
+
let items = oneShotItems.get(list);
|
|
116
|
+
if (!items) oneShotItems.set(list, items = Array.from(list));
|
|
117
|
+
return items;
|
|
118
|
+
}
|
|
119
|
+
function isIterable(node) {
|
|
120
|
+
return typeof node === "object" && node !== null && !isValidElement(node) && typeof node[Symbol.iterator] === "function";
|
|
121
|
+
}
|
|
122
|
+
function isPortal(node) {
|
|
123
|
+
return typeof node === "object" && node !== null && node.$$typeof === PORTAL;
|
|
124
|
+
}
|
|
125
|
+
function toBlockNodes(children) {
|
|
126
|
+
const elements = [];
|
|
127
|
+
const portals = [];
|
|
128
|
+
const nested = [];
|
|
129
|
+
let failure;
|
|
130
|
+
function mapLevel(level, parent) {
|
|
131
|
+
const out = [];
|
|
132
|
+
const visit = (node) => {
|
|
133
|
+
if (failure || node === null || node === void 0 || typeof node === "boolean") return;
|
|
134
|
+
if (typeof node === "string" || typeof node === "number" || typeof node === "bigint") {
|
|
135
|
+
out.push({ text: String(node) });
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (Array.isArray(node)) return node.forEach(visit);
|
|
139
|
+
if (isPortal(node)) {
|
|
140
|
+
if (parent === null) portals.push(node);
|
|
141
|
+
else nested[parent].push(node);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
if (!isValidElement(node)) {
|
|
145
|
+
failure = `an unsupported child (${typeof node})`;
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
const props = node.props;
|
|
149
|
+
if (node.type === DontTranslate) return visit(DontTranslate(props));
|
|
150
|
+
if (typeof node.type !== "string") {
|
|
151
|
+
failure = "a component, provider, lazy or Suspense child, whose DOM is unknown until React renders it";
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (props.dangerouslySetInnerHTML) {
|
|
155
|
+
failure = "dangerouslySetInnerHTML, an HTML string rather than a tree";
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
const index = elements.push(node) - 1;
|
|
159
|
+
nested[index] = [];
|
|
160
|
+
const kids = mapLevel(props.children, index);
|
|
161
|
+
const attrs = attrsOf(props);
|
|
162
|
+
out.push({ tag: node.type, ...attrs ? { attrs } : {}, ...kids.length ? { children: kids } : {} });
|
|
163
|
+
};
|
|
164
|
+
Children.toArray(withoutFragments(level)).forEach(visit);
|
|
165
|
+
return out;
|
|
166
|
+
}
|
|
167
|
+
const nodes = mapLevel(children, null);
|
|
168
|
+
return failure ? { ok: false, reason: failure } : { ok: true, nodes, elements, portals, nested };
|
|
169
|
+
}
|
|
170
|
+
var ATTR_TO_PROP = { class: "className", for: "htmlFor" };
|
|
171
|
+
var literally = (text) => text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
172
|
+
function propFor(attr, props) {
|
|
173
|
+
const same = new RegExp(`^${literally(attr)}$`, "i");
|
|
174
|
+
return ATTR_TO_PROP[attr] ?? Object.keys(props).find((name) => same.test(name)) ?? attr;
|
|
175
|
+
}
|
|
176
|
+
function toReactNodes(nodes, elements, nested = []) {
|
|
177
|
+
return nodes.flatMap((node) => {
|
|
178
|
+
if ("text" in node) return [node.text];
|
|
179
|
+
if ("comment" in node) return [];
|
|
180
|
+
const original = elements[node.source];
|
|
181
|
+
const originalProps = original.props;
|
|
182
|
+
const changed = {};
|
|
183
|
+
for (const [attr, value] of Object.entries(node.attrs)) {
|
|
184
|
+
if (value === true) continue;
|
|
185
|
+
const prop = propFor(attr, originalProps);
|
|
186
|
+
if ((attrValue(originalProps[prop]) ?? "") !== value) changed[prop] = value;
|
|
187
|
+
}
|
|
188
|
+
const kids = [...toReactNodes(node.children, elements, nested), ...nested[node.source] ?? []];
|
|
189
|
+
return [kids.length ? cloneElement(original, changed, ...kids) : cloneElement(original, { ...changed, children: void 0 })];
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
function hasRuntimeValues(children, skipExcluded = false) {
|
|
193
|
+
let run = [];
|
|
194
|
+
const flush = () => {
|
|
195
|
+
const hit = run.filter((p) => String(p).trim() !== "").length > 1;
|
|
196
|
+
run = [];
|
|
197
|
+
return hit;
|
|
198
|
+
};
|
|
199
|
+
for (const c of [...inRun(children), null]) {
|
|
200
|
+
if (typeof c === "string" || typeof c === "number" || typeof c === "bigint") {
|
|
201
|
+
run.push(c);
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
if (flush()) return true;
|
|
205
|
+
if (!isValidElement(c)) continue;
|
|
206
|
+
const node = c.type === DontTranslate ? DontTranslate(c.props) : c;
|
|
207
|
+
if (typeof node.type !== "string") continue;
|
|
208
|
+
const props = node.props;
|
|
209
|
+
if (skipExcluded && opaqueInPhrase(node.type, props)) continue;
|
|
210
|
+
if (hasRuntimeValues(props.children, skipExcluded)) return true;
|
|
211
|
+
}
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
function withoutFragments(node) {
|
|
215
|
+
if (read && isContext(node)) return withoutFragments(read(node));
|
|
216
|
+
if (Array.isArray(node)) return node.map(withoutFragments);
|
|
217
|
+
if (isIterable(node)) return Array.from(node, withoutFragments);
|
|
218
|
+
if (isValidElement(node) && node.type === Fragment) return [withoutFragments(node.props.children)];
|
|
219
|
+
return node;
|
|
220
|
+
}
|
|
221
|
+
function inRun(level) {
|
|
222
|
+
return Children.toArray(withoutFragments(level));
|
|
223
|
+
}
|
|
224
|
+
function opaqueInPhrase(tag, props) {
|
|
225
|
+
return NON_TRANSLATABLE_ELEMENTS.includes(tag) || isTranslationExcluded(attributeReader(tag, attrsOf(props)));
|
|
226
|
+
}
|
|
227
|
+
function attributeReader(tagName, attrs) {
|
|
228
|
+
const valueOf = (name) => Object.entries(attrs ?? {}).find(([key]) => key === name)?.[1];
|
|
229
|
+
return { tagName, getAttribute: (name) => valueOf(name) ?? null, hasAttribute: (name) => valueOf(name) !== void 0 };
|
|
230
|
+
}
|
|
231
|
+
function withNodeParams(children, given) {
|
|
232
|
+
const nodes = {};
|
|
233
|
+
const rest = {};
|
|
234
|
+
const props = /* @__PURE__ */ Object.create(null);
|
|
235
|
+
for (const [name, param] of Object.entries(given)) {
|
|
236
|
+
const value = read && isUsable(param) ? read(param) : param;
|
|
237
|
+
if (value === null || value === void 0) rest[name] = "";
|
|
238
|
+
else if (typeof value === "bigint") rest[name] = String(value);
|
|
239
|
+
else if (isParamValue(value)) rest[name] = value;
|
|
240
|
+
else {
|
|
241
|
+
nodes[name] = isIterable(value) && !Array.isArray(value) ? itemsOf(value) : value;
|
|
242
|
+
props[`%${name}%`] = props[`{${name}}`] = value;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
const names = Object.keys(nodes);
|
|
246
|
+
if (!names.length) return { children, params: rest };
|
|
247
|
+
const alternatives = names.map(literally).join("|");
|
|
248
|
+
const split = new RegExp(`%(${alternatives})%|(%[A-Za-z_][A-Za-z0-9_]*%)|\\{(${alternatives})\\}`);
|
|
249
|
+
const inText = /* @__PURE__ */ new Set();
|
|
250
|
+
const ownProps = (element) => {
|
|
251
|
+
let out;
|
|
252
|
+
for (const [prop, value] of Object.entries(element)) {
|
|
253
|
+
if (prop === "children" || typeof value !== "string") continue;
|
|
254
|
+
if (value in props) (out ??= {})[prop] = props[value];
|
|
255
|
+
else {
|
|
256
|
+
for (const match of value.matchAll(new RegExp(split.source, "g"))) {
|
|
257
|
+
const name = match[1] ?? match[3];
|
|
258
|
+
if (name !== void 0) inText.add(name);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return out;
|
|
263
|
+
};
|
|
264
|
+
const visit = (node) => {
|
|
265
|
+
if (typeof node === "string") {
|
|
266
|
+
const parts = node.split(new RegExp(split.source, "g"));
|
|
267
|
+
const out = [];
|
|
268
|
+
let text = "";
|
|
269
|
+
for (let i = 0; i < parts.length; i += 4) {
|
|
270
|
+
text += parts[i] + (parts[i + 2] ?? "");
|
|
271
|
+
const name = parts[i + 1] ?? parts[i + 3];
|
|
272
|
+
if (name === void 0) continue;
|
|
273
|
+
if (text) out.push(text);
|
|
274
|
+
text = "";
|
|
275
|
+
out.push(createElement(Fragment, { key: i + 1 }, nodes[name]));
|
|
276
|
+
}
|
|
277
|
+
if (out.length === 0) return node;
|
|
278
|
+
if (text) out.push(text);
|
|
279
|
+
return out;
|
|
280
|
+
}
|
|
281
|
+
if (Array.isArray(node)) {
|
|
282
|
+
const kids2 = node.map(visit);
|
|
283
|
+
return kids2.some((kid, i) => kid !== node[i]) ? kids2 : node;
|
|
284
|
+
}
|
|
285
|
+
if (!isValidElement(node)) return node;
|
|
286
|
+
if (typeof node.type !== "string" && node.type !== Fragment && node.type !== DontTranslate) return node;
|
|
287
|
+
const attrs = typeof node.type === "string" ? ownProps(node.props) : void 0;
|
|
288
|
+
const own = node.props.children;
|
|
289
|
+
if (own === void 0) return attrs ? cloneElement(node, attrs) : node;
|
|
290
|
+
const kids = Array.isArray(own) ? own.map(visit) : [visit(own)];
|
|
291
|
+
const same = Array.isArray(own) ? kids.every((kid, i) => kid === own[i]) : kids[0] === own;
|
|
292
|
+
return same && !attrs ? node : cloneElement(node, attrs, ...kids);
|
|
293
|
+
};
|
|
294
|
+
const rendered = visit(children);
|
|
295
|
+
for (const name of inText) rest[name] = String(props[`%${name}%`]);
|
|
296
|
+
return { children: rendered, params: rest };
|
|
297
|
+
}
|
|
298
|
+
var BlockCategory = createContext(void 0);
|
|
299
|
+
function useUnitCategory(named, namedPrevious) {
|
|
300
|
+
const block = useContext(BlockCategory);
|
|
301
|
+
const outerCategory = block?.category;
|
|
302
|
+
const outerPrevious = block?.previousCategory;
|
|
303
|
+
return useMemo(() => {
|
|
304
|
+
if (named !== void 0 || !block) return { category: named ?? "", previousCategory: namedPrevious };
|
|
305
|
+
return { category: block.category, previousCategory: namedPrevious ?? block.previousCategory };
|
|
306
|
+
}, [named, namedPrevious, block !== void 0, outerCategory, outerPrevious]);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// src/components/Translate.tsx
|
|
26
310
|
function Translate({
|
|
27
|
-
category
|
|
311
|
+
category: named,
|
|
312
|
+
previousCategory: namedPrevious,
|
|
28
313
|
custom_id = "",
|
|
29
314
|
label = "",
|
|
30
|
-
params,
|
|
315
|
+
params: given,
|
|
31
316
|
tag = "translate",
|
|
32
317
|
className,
|
|
33
|
-
children
|
|
318
|
+
children: content,
|
|
319
|
+
"data-ls-unnamed": unmarked
|
|
34
320
|
}) {
|
|
321
|
+
const unit = useUnitCategory(named, namedPrevious);
|
|
322
|
+
const { category, previousCategory } = unit;
|
|
323
|
+
const { children, params } = given ? withNodeParams(content, given) : { children: content, params: given };
|
|
324
|
+
const t = useT();
|
|
35
325
|
const hostRef = useRef(null);
|
|
36
326
|
const instanceRef = useRef(void 0);
|
|
327
|
+
const mapped = toBlockNodes(children);
|
|
328
|
+
const unnamedValues = unmarked !== void 0 || hasRuntimeValues(children);
|
|
329
|
+
const options = {
|
|
330
|
+
category,
|
|
331
|
+
...previousCategory === void 0 || previousCategory === null ? {} : { previousCategory },
|
|
332
|
+
params,
|
|
333
|
+
label,
|
|
334
|
+
...custom_id ? { id: custom_id } : {},
|
|
335
|
+
...unnamedValues ? { register: false } : {}
|
|
336
|
+
};
|
|
337
|
+
const inSeedScope = useSeedScopeRunner();
|
|
338
|
+
const rendered = mapped.ok ? inSeedScope(() => renderBlock(mapped.nodes, options)) : null;
|
|
339
|
+
const scope = currentRequestScope();
|
|
340
|
+
const register = (host) => {
|
|
341
|
+
if (!mapped.ok || !rendered || rendered.shape === "empty") return;
|
|
342
|
+
if (unnamedValues) warnUnnamed(unmarked !== void 0);
|
|
343
|
+
void registerBlock(mapped.nodes, { ...options, host });
|
|
344
|
+
};
|
|
345
|
+
if (scope) {
|
|
346
|
+
register();
|
|
347
|
+
if (!mapped.ok) warnUnrenderedBlock(mapped.reason);
|
|
348
|
+
}
|
|
349
|
+
const blockKey = rendered ? `${category}\0${custom_id}\0${rendered.customId}` : null;
|
|
350
|
+
useEffect(() => {
|
|
351
|
+
register(hostRef.current ?? void 0);
|
|
352
|
+
}, [t, blockKey, tag]);
|
|
37
353
|
useEffect(() => {
|
|
38
354
|
const host = hostRef.current;
|
|
39
|
-
if (!host) return;
|
|
40
|
-
|
|
355
|
+
if (mapped.ok || !host) return;
|
|
356
|
+
if (unnamedValues) warnUnnamed(unmarked !== void 0);
|
|
357
|
+
const instance = new Translate$1(host, {
|
|
358
|
+
category,
|
|
359
|
+
...previousCategory === void 0 || previousCategory === null ? {} : { previousCategory },
|
|
360
|
+
custom_id,
|
|
361
|
+
label,
|
|
362
|
+
params,
|
|
363
|
+
...unnamedValues ? { register: false } : {}
|
|
364
|
+
});
|
|
41
365
|
instanceRef.current = instance;
|
|
42
366
|
return () => {
|
|
43
367
|
instance.destroy();
|
|
44
368
|
instanceRef.current = void 0;
|
|
45
369
|
};
|
|
46
|
-
}, [category, custom_id, label]);
|
|
370
|
+
}, [mapped.ok, category, previousCategory, custom_id, label, tag]);
|
|
47
371
|
useEffect(() => {
|
|
48
372
|
instanceRef.current?.setParams(params);
|
|
49
373
|
});
|
|
50
|
-
|
|
374
|
+
if (mapped.ok && rendered) {
|
|
375
|
+
return createElement(
|
|
376
|
+
tag,
|
|
377
|
+
{ ref: hostRef, className, ...rendered.hostAttrs },
|
|
378
|
+
...toReactNodes(rendered.nodes, mapped.elements, mapped.nested),
|
|
379
|
+
...mapped.portals
|
|
380
|
+
);
|
|
381
|
+
}
|
|
382
|
+
return createElement(
|
|
383
|
+
tag,
|
|
384
|
+
{ ref: hostRef, className, ...custom_id ? { [CONTENT_BLOCK_MARKER_ATTR]: custom_id } : {} },
|
|
385
|
+
createElement(
|
|
386
|
+
BlockCategory.Provider,
|
|
387
|
+
{ value: unit },
|
|
388
|
+
...children !== content && Array.isArray(children) ? children : [children]
|
|
389
|
+
)
|
|
390
|
+
);
|
|
51
391
|
}
|
|
52
|
-
function
|
|
392
|
+
function warnUnnamed(unmarked) {
|
|
393
|
+
warnUnregistered(
|
|
394
|
+
unmarked ? "a value the build transform left as written: inside MathML or SVG, <script> or <style>, or an element that holds text only" : "a value the build transform did not name: it is not enabled (langsys-js-react/vite, /babel or /next), or the value is a conditional, which it leaves as written"
|
|
395
|
+
);
|
|
396
|
+
}
|
|
397
|
+
function Phrase({
|
|
398
|
+
category: named,
|
|
399
|
+
previousCategory: namedPrevious,
|
|
400
|
+
params: given = {},
|
|
401
|
+
tag = "span",
|
|
402
|
+
className,
|
|
403
|
+
children: content,
|
|
404
|
+
"data-ls-unnamed": unmarked
|
|
405
|
+
}) {
|
|
406
|
+
const inherited = useUnitCategory(named, namedPrevious);
|
|
407
|
+
const { category, previousCategory } = inherited;
|
|
408
|
+
const { children, params } = withNodeParams(content, given ?? {});
|
|
409
|
+
const t = useT();
|
|
53
410
|
const hostRef = useRef(null);
|
|
54
411
|
const instanceRef = useRef(void 0);
|
|
412
|
+
const mapped = toBlockNodes(children);
|
|
413
|
+
const unit = mapped.ok ? [{ tag, attrs: { [PHRASE_MARKER_ATTR]: "" }, children: mapped.nodes }] : null;
|
|
414
|
+
const unnamedValues = unmarked !== void 0 || hasRuntimeValues(children, true);
|
|
415
|
+
const moved = previousCategory === void 0 || previousCategory === null ? {} : { previousCategory };
|
|
416
|
+
const options = { category, ...moved, params, ...unnamedValues ? { register: false } : {} };
|
|
417
|
+
const inSeedScope = useSeedScopeRunner();
|
|
418
|
+
const rendered = unit ? inSeedScope(() => renderBlock(unit, options)) : null;
|
|
419
|
+
const scope = currentRequestScope();
|
|
420
|
+
const register = (host2) => {
|
|
421
|
+
if (!unit) return;
|
|
422
|
+
if (unnamedValues) warnUnnamed2(unmarked !== void 0);
|
|
423
|
+
void registerBlock(unit, { ...options, host: host2 });
|
|
424
|
+
};
|
|
425
|
+
if (scope) {
|
|
426
|
+
register();
|
|
427
|
+
if (!mapped.ok) warnUnrenderedBlock(mapped.reason);
|
|
428
|
+
}
|
|
55
429
|
useEffect(() => {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
430
|
+
register(hostRef.current ?? void 0);
|
|
431
|
+
}, [t, category, rendered ? JSON.stringify(unit) : null]);
|
|
432
|
+
useEffect(() => {
|
|
433
|
+
const host2 = hostRef.current;
|
|
434
|
+
if (mapped.ok || !host2) return;
|
|
435
|
+
if (unnamedValues) warnUnnamed2(unmarked !== void 0);
|
|
436
|
+
const instance = new Phrase$1(host2, {
|
|
437
|
+
category,
|
|
438
|
+
...moved,
|
|
439
|
+
params,
|
|
440
|
+
...unnamedValues ? { register: false } : {}
|
|
441
|
+
});
|
|
59
442
|
instanceRef.current = instance;
|
|
60
443
|
return () => {
|
|
61
444
|
instance.destroy();
|
|
62
445
|
instanceRef.current = void 0;
|
|
63
446
|
};
|
|
64
|
-
}, [category]);
|
|
447
|
+
}, [mapped.ok, category, previousCategory, tag]);
|
|
65
448
|
useEffect(() => {
|
|
66
449
|
instanceRef.current?.setParams(params);
|
|
67
450
|
});
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
451
|
+
const host = rendered?.nodes[0];
|
|
452
|
+
if (mapped.ok && host && "tag" in host) {
|
|
453
|
+
const { class: _class, ...hostAttrs } = host.attrs;
|
|
454
|
+
return createElement(
|
|
455
|
+
tag,
|
|
456
|
+
{ ref: hostRef, className, ...hostAttrs },
|
|
457
|
+
...toReactNodes(host.children, [createElement(tag), ...mapped.elements], [[], ...mapped.nested]),
|
|
458
|
+
...mapped.portals
|
|
459
|
+
);
|
|
460
|
+
}
|
|
71
461
|
return createElement(
|
|
72
462
|
tag,
|
|
73
|
-
{
|
|
74
|
-
|
|
463
|
+
{ ref: hostRef, className, [PHRASE_MARKER_ATTR]: "" },
|
|
464
|
+
createElement(
|
|
465
|
+
BlockCategory.Provider,
|
|
466
|
+
{ value: inherited },
|
|
467
|
+
...children !== content && Array.isArray(children) ? children : [children]
|
|
468
|
+
)
|
|
469
|
+
);
|
|
470
|
+
}
|
|
471
|
+
function warnUnnamed2(unmarked) {
|
|
472
|
+
warnUnregistered(
|
|
473
|
+
unmarked ? "a value the build transform left as written in a phrase whose values are all marked: in a translated <svg>, or an element that holds text only" : "a value the build transform did not name: it is not enabled (langsys-js-react/vite, /babel or /next), or the value is a conditional, which it leaves as written"
|
|
75
474
|
);
|
|
76
475
|
}
|
|
77
476
|
|
|
78
|
-
|
|
79
|
-
var LangsysAppReact = class {
|
|
80
|
-
/** Initialize Langsys. Pass a `Signal<string>` (from `createLocaleStore`) as `UserLocaleStore`. */
|
|
81
|
-
init(config) {
|
|
82
|
-
return LangsysApp$1.init(config);
|
|
83
|
-
}
|
|
84
|
-
get Translations() {
|
|
85
|
-
return LangsysApp$1.Translations;
|
|
86
|
-
}
|
|
87
|
-
get translationsLoadingPromise() {
|
|
88
|
-
return LangsysApp$1.translationsLoadingPromise;
|
|
89
|
-
}
|
|
90
|
-
/** Current translation function. Reads fresh state on every call (not reactive on its own — use `useT()` in components). */
|
|
91
|
-
get t() {
|
|
92
|
-
return LangsysApp$1.t;
|
|
93
|
-
}
|
|
94
|
-
get debug() {
|
|
95
|
-
return LangsysApp$1.debug;
|
|
96
|
-
}
|
|
97
|
-
refresh() {
|
|
98
|
-
return LangsysApp$1.refresh();
|
|
99
|
-
}
|
|
100
|
-
getCountries(inLocale) {
|
|
101
|
-
return LangsysApp$1.getCountries(inLocale);
|
|
102
|
-
}
|
|
103
|
-
getCountryName(forCountryCode, inLocale) {
|
|
104
|
-
return LangsysApp$1.getCountryName(forCountryCode, inLocale);
|
|
105
|
-
}
|
|
106
|
-
getCurrencies(inLocale) {
|
|
107
|
-
return LangsysApp$1.getCurrencies(inLocale);
|
|
108
|
-
}
|
|
109
|
-
getCurrencyName(forCurrencyCode, inLocale) {
|
|
110
|
-
return LangsysApp$1.getCurrencyName(forCurrencyCode, inLocale);
|
|
111
|
-
}
|
|
112
|
-
getDialCodes(inLocale) {
|
|
113
|
-
return LangsysApp$1.getDialCodes(inLocale);
|
|
114
|
-
}
|
|
115
|
-
getLocales(inLocale) {
|
|
116
|
-
return LangsysApp$1.getLocales(inLocale);
|
|
117
|
-
}
|
|
118
|
-
getLocalesFlat(inLocale) {
|
|
119
|
-
return LangsysApp$1.getLocalesFlat(inLocale);
|
|
120
|
-
}
|
|
121
|
-
getLocalesData(inLocale, forceRefresh) {
|
|
122
|
-
return LangsysApp$1.getLocalesData(inLocale, forceRefresh);
|
|
123
|
-
}
|
|
124
|
-
getLocalesFormat(format = "", inLocale) {
|
|
125
|
-
return LangsysApp$1.getLocalesFormat(format, inLocale);
|
|
126
|
-
}
|
|
127
|
-
getLocaleName(forLocale, shortName, inLocale) {
|
|
128
|
-
return LangsysApp$1.getLocaleName(forLocale, shortName, inLocale);
|
|
129
|
-
}
|
|
130
|
-
getLocaleNameWithLookup(forLocale, shortName, inLocale) {
|
|
131
|
-
return LangsysApp$1.getLocaleNameWithLookup(forLocale, shortName, inLocale);
|
|
132
|
-
}
|
|
133
|
-
/** @deprecated use `getLocaleNameWithLookup` or `getLocaleName` */
|
|
134
|
-
getLanguageName(forLocale, shortName, inLocale) {
|
|
135
|
-
return LangsysApp$1.getLanguageName(forLocale, shortName, inLocale);
|
|
136
|
-
}
|
|
137
|
-
detectPreferredLocale(acceptLanguageHeader, supportedLocales) {
|
|
138
|
-
return LangsysApp$1.detectPreferredLocale(acceptLanguageHeader, supportedLocales);
|
|
139
|
-
}
|
|
140
|
-
};
|
|
141
|
-
var LangsysApp = new LangsysAppReact();
|
|
142
|
-
|
|
143
|
-
export { DontTranslate, LangsysApp, Phrase, Translate, createLocaleStore, useCurrentLocale, useLocaleStore, useSignal, useT, useTranslations };
|
|
477
|
+
export { DontTranslate, LangsysApp2 as LangsysApp, LangsysProvider, Phrase, Translate, createLocaleStore, useCurrentLocale, useLocaleStore, useNotifyNavigation, useRenderServerMessage, useSignal, useT, useTranslations, useWriteEnabled };
|
|
144
478
|
//# sourceMappingURL=index.mjs.map
|
|
145
479
|
//# sourceMappingURL=index.mjs.map
|