|
1 | 1 | import { useContext } from "react"; |
2 | 2 | import { FluentContext } from "./context"; |
3 | 3 | import { ReactLocalization } from "./localization"; |
4 | | -import { FluentArgument, FluentBundle } from "@fluent/bundle"; |
5 | 4 |
|
6 | | -type Message = Exclude<ReturnType<FluentBundle["getMessage"]>, undefined> |
7 | | - |
8 | | -// Using ReactLocalization and a id, return its bundle and message object |
9 | | -// if both exists, otherwise return null for boths |
10 | | -type getBundleAndMessage = ( |
11 | | - (l10n: ReactLocalization, id: string) => |
12 | | - ({ bundle: FluentBundle; msg: Message } | { bundle: null; msg: null }) |
13 | | -) |
14 | | -const getBundleAndMessage: getBundleAndMessage = (l10n, id) => { |
15 | | - const bundle = l10n.getBundle(id); |
16 | | - const msg = bundle?.getMessage(id); |
17 | | - |
18 | | - if (bundle === null || msg === undefined) { |
19 | | - return { bundle: null, msg: null }; |
20 | | - } |
21 | | - |
22 | | - return { bundle, msg }; |
| 5 | +// Implementation of null object pattern for ReactLocalization |
| 6 | +const fallbackL10n: ReactLocalization = { |
| 7 | + getString: id => id, |
| 8 | + getBundle: () => null, |
| 9 | + bundles: [], |
| 10 | + parseMarkup: null, |
| 11 | + reportError: () => undefined, |
23 | 12 | }; |
24 | 13 |
|
25 | | -type TFunction = (id: string, vars?: Record<string, FluentArgument>) => string |
26 | | -type TAttributesFunction = ( |
27 | | - (id: string, vars?: Record<string, FluentArgument>) => |
28 | | - { [key in string]: string } |
29 | | -) |
30 | | - |
31 | | -type useTranslate = () => { t: TFunction; tAttributes: TAttributesFunction } |
32 | | - |
33 | 14 | /* |
34 | | - * The `useTranslate` hook uses the FluentContext to return two functions |
35 | | - * to get the translated messages from Fluent's bundle: |
36 | | - * - t: get the root message from the given id |
37 | | - * - tAttributes: get the attributes message from the given id |
38 | | - */ |
| 15 | +* The `useTranslate` hook returns the FluentContext |
| 16 | +*/ |
| 17 | +type useTranslate = () => { l10n: ReactLocalization } |
39 | 18 | export const useTranslate: useTranslate = () => { |
40 | 19 | const l10n = useContext(FluentContext); |
41 | 20 |
|
42 | 21 | if (!l10n) { |
43 | | - // Return fallbacks functions |
44 | | - const t: TFunction = () => ""; |
45 | | - const tAttributes: TAttributesFunction = () => ({}); |
46 | | - |
47 | | - return { t, tAttributes }; |
| 22 | + return { l10n: fallbackL10n }; |
48 | 23 | } |
49 | 24 |
|
50 | | - const t: TFunction = (id, vars) => { |
51 | | - const { bundle, msg } = getBundleAndMessage(l10n, id); |
52 | | - |
53 | | - if (bundle === null || msg === null) { |
54 | | - // Return as fallback an empty string. |
55 | | - return ""; |
56 | | - } |
57 | | - |
58 | | - // Format the message and return that |
59 | | - const errors: Array<Error> = []; |
60 | | - const msgValue = msg.value || ""; |
61 | | - const messageFormatted = bundle.formatPattern(msgValue, vars, errors); |
62 | | - |
63 | | - errors.forEach(error => l10n.reportError(error)); |
64 | | - |
65 | | - return messageFormatted; |
66 | | - }; |
67 | | - |
68 | | - const tAttributes: TAttributesFunction = (id, vars) => { |
69 | | - const { bundle, msg } = getBundleAndMessage(l10n, id); |
70 | | - |
71 | | - if (bundle === null || msg === null) { |
72 | | - // Return as fallback an empty object. |
73 | | - return {}; |
74 | | - } |
75 | | - |
76 | | - // Format all atributes and return that |
77 | | - const errors: Array<Error> = []; |
78 | | - const messagesFormatted = Object |
79 | | - .keys(msg.attributes) |
80 | | - .reduce( |
81 | | - (acc, key) => { |
82 | | - acc[key] = bundle.formatPattern(msg.attributes[key], vars, errors); |
83 | | - return acc; |
84 | | - }, |
85 | | - {} as { [key in string]: string } |
86 | | - ); |
87 | | - |
88 | | - errors.forEach(error => l10n.reportError(error)); |
89 | | - |
90 | | - return messagesFormatted; |
91 | | - }; |
92 | | - |
93 | | - return { t, tAttributes }; |
| 25 | + return { l10n }; |
94 | 26 | }; |
95 | 27 |
|
96 | 28 | export default useTranslate; |
0 commit comments