@bstage-sdk/react 0.8.6 → 0.9.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/dist/index.cjs +59 -40
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +56 -36
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -154,38 +154,55 @@ function registerTemplate(template) {
|
|
|
154
154
|
|
|
155
155
|
// src/hooks/useNavigation.ts
|
|
156
156
|
var import_react4 = require("react");
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
157
|
+
var import_core2 = require("@bstage-sdk/core");
|
|
158
|
+
|
|
159
|
+
// src/hooks/navigationActions.ts
|
|
160
|
+
function withQuery(path, params) {
|
|
161
|
+
return path + (params ? "?" + new URLSearchParams(params).toString() : "");
|
|
162
|
+
}
|
|
163
|
+
function createNavigationActions(frameBridge, platformBridge) {
|
|
164
|
+
if (frameBridge) {
|
|
165
|
+
const send = (type, payload) => {
|
|
166
|
+
frameBridge.request(type, payload).catch(() => {
|
|
167
|
+
});
|
|
168
|
+
};
|
|
169
|
+
return {
|
|
170
|
+
navigate: (path, params) => send("navigate", { path: withQuery(path, params) }),
|
|
171
|
+
goBack: () => send("back", {}),
|
|
172
|
+
openExternal: (url) => send("openExternal", { url })
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
return {
|
|
176
|
+
navigate: (path, params) => {
|
|
177
|
+
if (platformBridge) {
|
|
178
|
+
platformBridge.emit("navigate", { path, params });
|
|
164
179
|
} else {
|
|
165
|
-
|
|
166
|
-
window.location.href = path + query;
|
|
180
|
+
window.location.href = withQuery(path, params);
|
|
167
181
|
}
|
|
168
182
|
},
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
if (bridge) {
|
|
173
|
-
bridge.emit("go-back", {});
|
|
174
|
-
} else {
|
|
175
|
-
window.history.back();
|
|
176
|
-
}
|
|
177
|
-
}, [bridge]);
|
|
178
|
-
const openExternal = (0, import_react4.useCallback)(
|
|
179
|
-
(url) => {
|
|
180
|
-
if (bridge) {
|
|
181
|
-
bridge.emit("open-external", { url });
|
|
183
|
+
goBack: () => {
|
|
184
|
+
if (platformBridge) {
|
|
185
|
+
platformBridge.emit("go-back", {});
|
|
182
186
|
} else {
|
|
183
|
-
window.
|
|
187
|
+
window.history.back();
|
|
184
188
|
}
|
|
185
189
|
},
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
190
|
+
openExternal: (url) => {
|
|
191
|
+
if (platformBridge) {
|
|
192
|
+
platformBridge.emit("open-external", { url });
|
|
193
|
+
} else {
|
|
194
|
+
window.open(url, "_blank");
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// src/hooks/useNavigation.ts
|
|
201
|
+
function useNavigation() {
|
|
202
|
+
const ctx = (0, import_react4.useContext)(BstageContext);
|
|
203
|
+
const bridge = ctx?.bridge;
|
|
204
|
+
const frameBridge = (0, import_core2.getFrameBridge)();
|
|
205
|
+
return (0, import_react4.useMemo)(() => createNavigationActions(frameBridge, bridge), [frameBridge, bridge]);
|
|
189
206
|
}
|
|
190
207
|
|
|
191
208
|
// src/hooks/usePlatformEvent.ts
|
|
@@ -242,7 +259,7 @@ function hashString(str) {
|
|
|
242
259
|
|
|
243
260
|
// src/hooks/useLocale.ts
|
|
244
261
|
var import_react9 = require("react");
|
|
245
|
-
var
|
|
262
|
+
var import_core3 = require("@bstage-sdk/core");
|
|
246
263
|
|
|
247
264
|
// src/LocaleProvider.tsx
|
|
248
265
|
var import_react8 = require("react");
|
|
@@ -266,14 +283,14 @@ function BstageLocaleProvider({
|
|
|
266
283
|
// src/hooks/useLocale.ts
|
|
267
284
|
function useLocale() {
|
|
268
285
|
const target = useLocaleTarget();
|
|
269
|
-
const subscribe = (0, import_react9.useCallback)((onChange) => (0,
|
|
270
|
-
const getSnapshot = (0, import_react9.useCallback)(() => (0,
|
|
271
|
-
const current = (0, import_react9.useSyncExternalStore)(subscribe, getSnapshot, () =>
|
|
286
|
+
const subscribe = (0, import_react9.useCallback)((onChange) => (0, import_core3.observeLocale)(onChange, target), [target]);
|
|
287
|
+
const getSnapshot = (0, import_react9.useCallback)(() => (0, import_core3.readLocale)(target), [target]);
|
|
288
|
+
const current = (0, import_react9.useSyncExternalStore)(subscribe, getSnapshot, () => import_core3.DEFAULT_LANGUAGE);
|
|
272
289
|
return { current };
|
|
273
290
|
}
|
|
274
291
|
|
|
275
292
|
// src/hooks/useMessages.ts
|
|
276
|
-
var
|
|
293
|
+
var import_core4 = require("@bstage-sdk/core");
|
|
277
294
|
|
|
278
295
|
// src/devWarn.ts
|
|
279
296
|
var warned = /* @__PURE__ */ new Set();
|
|
@@ -300,7 +317,7 @@ function useMessages(messages) {
|
|
|
300
317
|
`useMessages\uC758 t('${String(key)}', ...) 2\uBC88\uC9F8 \uC778\uC790\uB294 \uBCF4\uAC04 \uD30C\uB77C\uBBF8\uD130 \uAC1D\uCCB4\uC785\uB2C8\uB2E4. fallback \uBB38\uC790\uC5F4\uC740 \uBB34\uC2DC\uB429\uB2C8\uB2E4.`
|
|
301
318
|
);
|
|
302
319
|
}
|
|
303
|
-
const dict = messages[current] ?? messages[
|
|
320
|
+
const dict = messages[current] ?? messages[import_core4.DEFAULT_LANGUAGE] ?? Object.values(messages)[0] ?? {};
|
|
304
321
|
const template = dict[key] ?? key;
|
|
305
322
|
return interpolate(template, params);
|
|
306
323
|
};
|
|
@@ -308,7 +325,7 @@ function useMessages(messages) {
|
|
|
308
325
|
|
|
309
326
|
// src/hooks/useBstageTranslations.ts
|
|
310
327
|
var import_react10 = require("react");
|
|
311
|
-
var
|
|
328
|
+
var import_core5 = require("@bstage-sdk/core");
|
|
312
329
|
var requiredDepth = /* @__PURE__ */ new Map();
|
|
313
330
|
function useBstageTranslations() {
|
|
314
331
|
const { current } = useLocale();
|
|
@@ -317,6 +334,8 @@ function useBstageTranslations() {
|
|
|
317
334
|
const [dicts, setDicts] = (0, import_react10.useState)();
|
|
318
335
|
const [depth, setDepth] = (0, import_react10.useState)(() => requiredDepth.get(depthKey) ?? 1);
|
|
319
336
|
const pendingRef = (0, import_react10.useRef)(false);
|
|
337
|
+
const [translationsRevision, setTranslationsRevision] = (0, import_react10.useState)(0);
|
|
338
|
+
(0, import_react10.useEffect)(() => (0, import_core5.observeTranslations)(() => setTranslationsRevision((n) => n + 1)), []);
|
|
320
339
|
(0, import_react10.useEffect)(() => {
|
|
321
340
|
setDicts(void 0);
|
|
322
341
|
setDepth(requiredDepth.get(depthKey) ?? 1);
|
|
@@ -324,8 +343,8 @@ function useBstageTranslations() {
|
|
|
324
343
|
}, [depthKey]);
|
|
325
344
|
(0, import_react10.useEffect)(() => {
|
|
326
345
|
let active = true;
|
|
327
|
-
const chain = (0,
|
|
328
|
-
Promise.all(chain.map((locale) => (0,
|
|
346
|
+
const chain = (0, import_core5.resolveTranslationChain)(current).slice(0, depth);
|
|
347
|
+
Promise.all(chain.map((locale) => (0, import_core5.fetchTranslations)(locale, target).catch(() => ({})))).then((loaded) => {
|
|
329
348
|
if (!active) return;
|
|
330
349
|
setDicts(loaded);
|
|
331
350
|
pendingRef.current = false;
|
|
@@ -335,7 +354,7 @@ function useBstageTranslations() {
|
|
|
335
354
|
return () => {
|
|
336
355
|
active = false;
|
|
337
356
|
};
|
|
338
|
-
}, [current, target, depth]);
|
|
357
|
+
}, [current, target, depth, translationsRevision]);
|
|
339
358
|
const requestFallback = (0, import_react10.useCallback)(
|
|
340
359
|
(chainLength) => {
|
|
341
360
|
if (pendingRef.current) return;
|
|
@@ -353,10 +372,10 @@ function useBstageTranslations() {
|
|
|
353
372
|
);
|
|
354
373
|
const resolveRaw = (0, import_react10.useCallback)(
|
|
355
374
|
(key) => {
|
|
356
|
-
const resolved = dicts ? (0,
|
|
375
|
+
const resolved = dicts ? (0, import_core5.pickTranslation)(dicts, key) : void 0;
|
|
357
376
|
if (resolved !== void 0) return resolved;
|
|
358
377
|
if (dicts) {
|
|
359
|
-
const chain = (0,
|
|
378
|
+
const chain = (0, import_core5.resolveTranslationChain)(current);
|
|
360
379
|
if (dicts.length < chain.length) {
|
|
361
380
|
requestFallback(chain.length);
|
|
362
381
|
} else if (process.env.NODE_ENV !== "production") {
|
|
@@ -387,14 +406,14 @@ function useBstageTranslations() {
|
|
|
387
406
|
`'${String(key)}'\uB294 \uB9AC\uCE58\uD14D\uC2A4\uD2B8(<0>\u2026</0>) \uBB38\uAD6C\uC785\uB2C8\uB2E4. t()\uB294 \uBB38\uC790\uC5F4\uC744 \uBC18\uD658\uD558\uBBC0\uB85C \uD0DC\uADF8\uAC00 \uAE00\uC790\uB85C \uBCF4\uC785\uB2C8\uB2E4 \u2014 tNode('${String(key)}', { tags: { 0: <a href="\u2026" /> } })\uB97C \uC4F0\uC138\uC694.`
|
|
388
407
|
);
|
|
389
408
|
}
|
|
390
|
-
return (0,
|
|
409
|
+
return (0, import_core5.interpolateTranslation)(raw ?? key, params);
|
|
391
410
|
},
|
|
392
411
|
[resolveRaw]
|
|
393
412
|
);
|
|
394
413
|
const tNode = (0, import_react10.useCallback)(
|
|
395
414
|
(key, options) => {
|
|
396
415
|
const raw = resolveRaw(key) ?? key;
|
|
397
|
-
const tokens = (0,
|
|
416
|
+
const tokens = (0, import_core5.parseRichText)(raw, options?.params);
|
|
398
417
|
return tokens.map((token, i) => {
|
|
399
418
|
if (token.type === "text") return token.value;
|
|
400
419
|
const element = options?.tags?.[token.index];
|
package/dist/index.d.cts
CHANGED
|
@@ -75,9 +75,11 @@ interface NavigationActions {
|
|
|
75
75
|
/** 외부 URL을 새 탭으로 열기. */
|
|
76
76
|
openExternal: (url: string) => void;
|
|
77
77
|
}
|
|
78
|
+
|
|
78
79
|
/**
|
|
79
80
|
* 플랫폼 네비게이션 hook.
|
|
80
81
|
*
|
|
82
|
+
* 격리 프레임(`__bstage_bridge__` 있음)에서는 호스트에 브리지 요청을 보내고,
|
|
81
83
|
* 플랫폼에 임베드된 상태에서는 PlatformBridge를 통해 네비게이션하고,
|
|
82
84
|
* 로컬 dev 환경 등 BstageContext가 없을 때는 브라우저 네이티브 API로 fallback한다.
|
|
83
85
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -75,9 +75,11 @@ interface NavigationActions {
|
|
|
75
75
|
/** 외부 URL을 새 탭으로 열기. */
|
|
76
76
|
openExternal: (url: string) => void;
|
|
77
77
|
}
|
|
78
|
+
|
|
78
79
|
/**
|
|
79
80
|
* 플랫폼 네비게이션 hook.
|
|
80
81
|
*
|
|
82
|
+
* 격리 프레임(`__bstage_bridge__` 있음)에서는 호스트에 브리지 요청을 보내고,
|
|
81
83
|
* 플랫폼에 임베드된 상태에서는 PlatformBridge를 통해 네비게이션하고,
|
|
82
84
|
* 로컬 dev 환경 등 BstageContext가 없을 때는 브라우저 네이티브 API로 fallback한다.
|
|
83
85
|
*
|
package/dist/index.js
CHANGED
|
@@ -118,39 +118,56 @@ function registerTemplate(template) {
|
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
// src/hooks/useNavigation.ts
|
|
121
|
-
import {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
121
|
+
import { useMemo, useContext as useContext2 } from "react";
|
|
122
|
+
import { getFrameBridge } from "@bstage-sdk/core";
|
|
123
|
+
|
|
124
|
+
// src/hooks/navigationActions.ts
|
|
125
|
+
function withQuery(path, params) {
|
|
126
|
+
return path + (params ? "?" + new URLSearchParams(params).toString() : "");
|
|
127
|
+
}
|
|
128
|
+
function createNavigationActions(frameBridge, platformBridge) {
|
|
129
|
+
if (frameBridge) {
|
|
130
|
+
const send = (type, payload) => {
|
|
131
|
+
frameBridge.request(type, payload).catch(() => {
|
|
132
|
+
});
|
|
133
|
+
};
|
|
134
|
+
return {
|
|
135
|
+
navigate: (path, params) => send("navigate", { path: withQuery(path, params) }),
|
|
136
|
+
goBack: () => send("back", {}),
|
|
137
|
+
openExternal: (url) => send("openExternal", { url })
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
return {
|
|
141
|
+
navigate: (path, params) => {
|
|
142
|
+
if (platformBridge) {
|
|
143
|
+
platformBridge.emit("navigate", { path, params });
|
|
129
144
|
} else {
|
|
130
|
-
|
|
131
|
-
window.location.href = path + query;
|
|
145
|
+
window.location.href = withQuery(path, params);
|
|
132
146
|
}
|
|
133
147
|
},
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
if (bridge) {
|
|
138
|
-
bridge.emit("go-back", {});
|
|
139
|
-
} else {
|
|
140
|
-
window.history.back();
|
|
141
|
-
}
|
|
142
|
-
}, [bridge]);
|
|
143
|
-
const openExternal = useCallback(
|
|
144
|
-
(url) => {
|
|
145
|
-
if (bridge) {
|
|
146
|
-
bridge.emit("open-external", { url });
|
|
148
|
+
goBack: () => {
|
|
149
|
+
if (platformBridge) {
|
|
150
|
+
platformBridge.emit("go-back", {});
|
|
147
151
|
} else {
|
|
148
|
-
window.
|
|
152
|
+
window.history.back();
|
|
149
153
|
}
|
|
150
154
|
},
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
155
|
+
openExternal: (url) => {
|
|
156
|
+
if (platformBridge) {
|
|
157
|
+
platformBridge.emit("open-external", { url });
|
|
158
|
+
} else {
|
|
159
|
+
window.open(url, "_blank");
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// src/hooks/useNavigation.ts
|
|
166
|
+
function useNavigation() {
|
|
167
|
+
const ctx = useContext2(BstageContext);
|
|
168
|
+
const bridge = ctx?.bridge;
|
|
169
|
+
const frameBridge = getFrameBridge();
|
|
170
|
+
return useMemo(() => createNavigationActions(frameBridge, bridge), [frameBridge, bridge]);
|
|
154
171
|
}
|
|
155
172
|
|
|
156
173
|
// src/hooks/usePlatformEvent.ts
|
|
@@ -206,7 +223,7 @@ function hashString(str) {
|
|
|
206
223
|
}
|
|
207
224
|
|
|
208
225
|
// src/hooks/useLocale.ts
|
|
209
|
-
import { useCallback
|
|
226
|
+
import { useCallback, useSyncExternalStore } from "react";
|
|
210
227
|
import { readLocale, observeLocale, DEFAULT_LANGUAGE } from "@bstage-sdk/core";
|
|
211
228
|
|
|
212
229
|
// src/LocaleProvider.tsx
|
|
@@ -231,8 +248,8 @@ function BstageLocaleProvider({
|
|
|
231
248
|
// src/hooks/useLocale.ts
|
|
232
249
|
function useLocale() {
|
|
233
250
|
const target = useLocaleTarget();
|
|
234
|
-
const subscribe =
|
|
235
|
-
const getSnapshot =
|
|
251
|
+
const subscribe = useCallback((onChange) => observeLocale(onChange, target), [target]);
|
|
252
|
+
const getSnapshot = useCallback(() => readLocale(target), [target]);
|
|
236
253
|
const current = useSyncExternalStore(subscribe, getSnapshot, () => DEFAULT_LANGUAGE);
|
|
237
254
|
return { current };
|
|
238
255
|
}
|
|
@@ -272,9 +289,10 @@ function useMessages(messages) {
|
|
|
272
289
|
}
|
|
273
290
|
|
|
274
291
|
// src/hooks/useBstageTranslations.ts
|
|
275
|
-
import { cloneElement, useCallback as
|
|
292
|
+
import { cloneElement, useCallback as useCallback2, useEffect as useEffect4, useRef as useRef3, useState as useState2 } from "react";
|
|
276
293
|
import {
|
|
277
294
|
fetchTranslations,
|
|
295
|
+
observeTranslations,
|
|
278
296
|
interpolateTranslation,
|
|
279
297
|
parseRichText,
|
|
280
298
|
pickTranslation,
|
|
@@ -288,6 +306,8 @@ function useBstageTranslations() {
|
|
|
288
306
|
const [dicts, setDicts] = useState2();
|
|
289
307
|
const [depth, setDepth] = useState2(() => requiredDepth.get(depthKey) ?? 1);
|
|
290
308
|
const pendingRef = useRef3(false);
|
|
309
|
+
const [translationsRevision, setTranslationsRevision] = useState2(0);
|
|
310
|
+
useEffect4(() => observeTranslations(() => setTranslationsRevision((n) => n + 1)), []);
|
|
291
311
|
useEffect4(() => {
|
|
292
312
|
setDicts(void 0);
|
|
293
313
|
setDepth(requiredDepth.get(depthKey) ?? 1);
|
|
@@ -306,8 +326,8 @@ function useBstageTranslations() {
|
|
|
306
326
|
return () => {
|
|
307
327
|
active = false;
|
|
308
328
|
};
|
|
309
|
-
}, [current, target, depth]);
|
|
310
|
-
const requestFallback =
|
|
329
|
+
}, [current, target, depth, translationsRevision]);
|
|
330
|
+
const requestFallback = useCallback2(
|
|
311
331
|
(chainLength) => {
|
|
312
332
|
if (pendingRef.current) return;
|
|
313
333
|
pendingRef.current = true;
|
|
@@ -322,7 +342,7 @@ function useBstageTranslations() {
|
|
|
322
342
|
},
|
|
323
343
|
[depthKey]
|
|
324
344
|
);
|
|
325
|
-
const resolveRaw =
|
|
345
|
+
const resolveRaw = useCallback2(
|
|
326
346
|
(key) => {
|
|
327
347
|
const resolved = dicts ? pickTranslation(dicts, key) : void 0;
|
|
328
348
|
if (resolved !== void 0) return resolved;
|
|
@@ -341,7 +361,7 @@ function useBstageTranslations() {
|
|
|
341
361
|
},
|
|
342
362
|
[dicts, current, requestFallback]
|
|
343
363
|
);
|
|
344
|
-
const t =
|
|
364
|
+
const t = useCallback2(
|
|
345
365
|
(key, params) => {
|
|
346
366
|
if (process.env.NODE_ENV !== "production") {
|
|
347
367
|
if (typeof params === "string") {
|
|
@@ -362,7 +382,7 @@ function useBstageTranslations() {
|
|
|
362
382
|
},
|
|
363
383
|
[resolveRaw]
|
|
364
384
|
);
|
|
365
|
-
const tNode =
|
|
385
|
+
const tNode = useCallback2(
|
|
366
386
|
(key, options) => {
|
|
367
387
|
const raw = resolveRaw(key) ?? key;
|
|
368
388
|
const tokens = parseRichText(raw, options?.params);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bstage-sdk/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "bstage SDK React bindings — create b.stage templates with React",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"dist"
|
|
31
31
|
],
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@bstage-sdk/core": "0.
|
|
33
|
+
"@bstage-sdk/core": "0.9.0"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
36
|
"react": ">=18",
|