Skip to content

Commit 8f5685d

Browse files
committed
(@fluent/react) Add changeLocales and currentLocales on provider
1 parent f41d910 commit 8f5685d

File tree

8 files changed

+53
-23
lines changed

8 files changed

+53
-23
lines changed

fluent-react/example/src/App.tsx

+5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Localized } from "@fluent/react";
33
import { FluentDateTime } from "@fluent/bundle";
44
import { Hello } from "./Hello";
55
import { SignIn } from "./SignIn";
6+
import { ChangeLocale } from "./ChangeLocale";
67

78
export function App() {
89
let [date] = useState(() => new Date());
@@ -37,5 +38,9 @@ export function App() {
3738
</Localized>
3839

3940
<SignIn />
41+
42+
<hr />
43+
44+
<ChangeLocale />
4045
</>;
4146
}
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import React from "react";
2+
import { useLocalization } from "@fluent/react";
3+
import { AVAILABLE_LOCALES } from "./l10n";
4+
5+
export function ChangeLocale() {
6+
const { changeLocales, currentLocales } = useLocalization()
7+
8+
return (
9+
<select
10+
onChange={event => changeLocales([event.target.value])}
11+
value={currentLocales[0]}>
12+
{Object.entries(AVAILABLE_LOCALES).map(
13+
([code, name]) => <option key={code} value={code}>{name}</option>
14+
)}
15+
</select>
16+
);
17+
}

fluent-react/example/src/l10n.tsx

+4-15
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { ReactLocalization, LocalizationProvider } from "@fluent/react";
88
const ftl = require("../public/*.ftl");
99

1010
const DEFAULT_LOCALE = "en-US";
11-
const AVAILABLE_LOCALES = {
11+
export const AVAILABLE_LOCALES = {
1212
"en-US": "English",
1313
"pl": "Polish",
1414
};
@@ -33,7 +33,6 @@ interface AppLocalizationProviderProps {
3333
}
3434

3535
export function AppLocalizationProvider(props: AppLocalizationProviderProps) {
36-
let [currentLocales, setCurrentLocales] = useState([DEFAULT_LOCALE]);
3736
let [l10n, setL10n] = useState<ReactLocalization | null>(null);
3837

3938
useEffect(() => {
@@ -46,7 +45,6 @@ export function AppLocalizationProvider(props: AppLocalizationProviderProps) {
4645
Object.keys(AVAILABLE_LOCALES),
4746
{ defaultLocale: DEFAULT_LOCALE }
4847
);
49-
setCurrentLocales(currentLocales);
5048

5149
let fetchedMessages = await Promise.all(
5250
currentLocales.map(fetchMessages)
@@ -60,18 +58,9 @@ export function AppLocalizationProvider(props: AppLocalizationProviderProps) {
6058
return <div>Loading…</div>;
6159
}
6260

63-
return <>
64-
<LocalizationProvider l10n={l10n}>
61+
return (
62+
<LocalizationProvider l10n={l10n} changeLocales={changeLocales} initialLocales={navigator.languages}>
6563
{Children.only(props.children)}
6664
</LocalizationProvider>
67-
68-
<hr />
69-
<select
70-
onChange={event => changeLocales([event.target.value])}
71-
value={currentLocales[0]}>
72-
{Object.entries(AVAILABLE_LOCALES).map(
73-
([code, name]) => <option key={code} value={code}>{name}</option>
74-
)}
75-
</select>
76-
</>;
65+
);
7766
}

fluent-react/src/context.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
import { createContext } from "react";
22
import { ReactLocalization } from "./localization";
33

4-
export let FluentContext = createContext(new ReactLocalization([], null));
4+
const defaultValue = {
5+
l10n: new ReactLocalization([], null),
6+
changeLocales: (_changeLocales: string[]) => undefined as void,
7+
currentLocales: [] as string[],
8+
};
9+
10+
export let FluentContext = createContext(defaultValue);

fluent-react/src/localized.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export interface LocalizedProps {
4747
*/
4848
export function Localized(props: LocalizedProps): ReactElement {
4949
const { id, attrs, vars, elems, children: child = null } = props;
50-
const l10n = useContext(FluentContext);
50+
const { l10n } = useContext(FluentContext);
5151

5252
// Validate that the child element isn't an array
5353
if (Array.isArray(child)) {

fluent-react/src/provider.ts

+15-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
import { createElement, ReactNode, ReactElement } from "react";
1+
import { createElement, ReactNode, ReactElement, useState } from "react";
22
import PropTypes from "prop-types";
33
import { FluentContext } from "./context";
44
import { ReactLocalization } from "./localization";
55

66
interface LocalizationProviderProps {
77
children?: ReactNode;
88
l10n: ReactLocalization;
9+
changeLocales: (locales: string[]) => void;
10+
initialLocales: string[];
911
}
1012

1113
/*
@@ -27,10 +29,21 @@ interface LocalizationProviderProps {
2729
export function LocalizationProvider(
2830
props: LocalizationProviderProps
2931
): ReactElement {
32+
let [locales, setLocales] = useState(props.initialLocales);
33+
34+
function changeLocales(locales: string[]) {
35+
props.changeLocales(locales);
36+
setLocales(locales);
37+
}
38+
3039
return createElement(
3140
FluentContext.Provider,
3241
{
33-
value: props.l10n
42+
value: {
43+
l10n: props.l10n,
44+
changeLocales: changeLocales,
45+
currentLocales: locales
46+
}
3447
},
3548
props.children
3649
);

fluent-react/src/use_localization.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import { ReactLocalization } from "./localization";
55
/*
66
* The `useLocalization` hook returns the FluentContext
77
*/
8-
type useLocalization = () => { l10n: ReactLocalization }
8+
type useLocalization = () => { l10n: ReactLocalization, changeLocales: (locales: string[]) => void, currentLocales: string[] }
99
export const useLocalization: useLocalization = () => {
10-
const l10n = useContext(FluentContext);
10+
const { l10n, changeLocales, currentLocales } = useContext(FluentContext);
1111

12-
return { l10n };
12+
return { l10n, changeLocales, currentLocales };
1313
};

fluent-react/src/with_localization.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export function withLocalization<P extends WithLocalizationProps>(
1616
Inner: ComponentType<P>
1717
): ComponentType<WithoutLocalizationProps<P>> {
1818
function WithLocalization(props: WithoutLocalizationProps<P>): ReactElement {
19-
const l10n = useContext(FluentContext);
19+
const { l10n } = useContext(FluentContext);
2020
// Re-bind getString to trigger a re-render of Inner.
2121
const getString = l10n.getString.bind(l10n);
2222
return createElement(Inner, { getString, ...props } as P);

0 commit comments

Comments
 (0)