Skip to content

Commit

Permalink
(@fluent/react) Add changeLocales and currentLocales on provider
Browse files Browse the repository at this point in the history
  • Loading branch information
macabeus committed Jul 8, 2020
1 parent f41d910 commit 05ffc2c
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 23 deletions.
5 changes: 5 additions & 0 deletions fluent-react/example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Localized } from "@fluent/react";
import { FluentDateTime } from "@fluent/bundle";
import { Hello } from "./Hello";
import { SignIn } from "./SignIn";
import { LanguageSelector } from "./LanguageSelector";

export function App() {
let [date] = useState(() => new Date());
Expand Down Expand Up @@ -37,5 +38,9 @@ export function App() {
</Localized>

<SignIn />

<hr />

<LanguageSelector />
</>;
}
17 changes: 17 additions & 0 deletions fluent-react/example/src/LanguageSelector.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from "react";
import { useLocalization } from "@fluent/react";
import { AVAILABLE_LOCALES } from "./l10n";

export function LanguageSelector() {
const { changeLocales, currentLocales } = useLocalization()

return (
<select
onChange={event => changeLocales([event.target.value])}
value={currentLocales[0]}>
{Object.entries(AVAILABLE_LOCALES).map(
([code, name]) => <option key={code} value={code}>{name}</option>
)}
</select>
);
}
19 changes: 4 additions & 15 deletions fluent-react/example/src/l10n.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { ReactLocalization, LocalizationProvider } from "@fluent/react";
const ftl = require("../public/*.ftl");

const DEFAULT_LOCALE = "en-US";
const AVAILABLE_LOCALES = {
export const AVAILABLE_LOCALES = {
"en-US": "English",
"pl": "Polish",
};
Expand All @@ -33,7 +33,6 @@ interface AppLocalizationProviderProps {
}

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

useEffect(() => {
Expand All @@ -46,7 +45,6 @@ export function AppLocalizationProvider(props: AppLocalizationProviderProps) {
Object.keys(AVAILABLE_LOCALES),
{ defaultLocale: DEFAULT_LOCALE }
);
setCurrentLocales(currentLocales);

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

return <>
<LocalizationProvider l10n={l10n}>
return (
<LocalizationProvider l10n={l10n} changeLocales={changeLocales} initialLocales={navigator.languages}>
{Children.only(props.children)}
</LocalizationProvider>

<hr />
<select
onChange={event => changeLocales([event.target.value])}
value={currentLocales[0]}>
{Object.entries(AVAILABLE_LOCALES).map(
([code, name]) => <option key={code} value={code}>{name}</option>
)}
</select>
</>;
);
}
8 changes: 7 additions & 1 deletion fluent-react/src/context.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { createContext } from "react";
import { ReactLocalization } from "./localization";

export let FluentContext = createContext(new ReactLocalization([], null));
const defaultValue = {
l10n: new ReactLocalization([], null),
changeLocales: (_changeLocales: string[]) => undefined as void,
currentLocales: [] as string[],
};

export let FluentContext = createContext(defaultValue);
2 changes: 1 addition & 1 deletion fluent-react/src/localized.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export interface LocalizedProps {
*/
export function Localized(props: LocalizedProps): ReactElement {
const { id, attrs, vars, elems, children: child = null } = props;
const l10n = useContext(FluentContext);
const { l10n } = useContext(FluentContext);

// Validate that the child element isn't an array
if (Array.isArray(child)) {
Expand Down
17 changes: 15 additions & 2 deletions fluent-react/src/provider.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { createElement, ReactNode, ReactElement } from "react";
import { createElement, ReactNode, ReactElement, useState } from "react";
import PropTypes from "prop-types";
import { FluentContext } from "./context";
import { ReactLocalization } from "./localization";

interface LocalizationProviderProps {
children?: ReactNode;
l10n: ReactLocalization;
changeLocales: (locales: string[]) => void;
initialLocales: string[];
}

/*
Expand All @@ -27,10 +29,21 @@ interface LocalizationProviderProps {
export function LocalizationProvider(
props: LocalizationProviderProps
): ReactElement {
let [locales, setLocales] = useState(props.initialLocales);

function changeLocales(locales: string[]) {
props.changeLocales(locales);
setLocales(locales);
}

return createElement(
FluentContext.Provider,
{
value: props.l10n
value: {
l10n: props.l10n,
changeLocales: changeLocales,
currentLocales: locales
}
},
props.children
);
Expand Down
6 changes: 3 additions & 3 deletions fluent-react/src/use_localization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { ReactLocalization } from "./localization";
/*
* The `useLocalization` hook returns the FluentContext
*/
type useLocalization = () => { l10n: ReactLocalization }
type useLocalization = () => { l10n: ReactLocalization, changeLocales: (locales: string[]) => void, currentLocales: string[] }
export const useLocalization: useLocalization = () => {
const l10n = useContext(FluentContext);
const { l10n, changeLocales, currentLocales } = useContext(FluentContext);

return { l10n };
return { l10n, changeLocales, currentLocales };
};
2 changes: 1 addition & 1 deletion fluent-react/src/with_localization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export function withLocalization<P extends WithLocalizationProps>(
Inner: ComponentType<P>
): ComponentType<WithoutLocalizationProps<P>> {
function WithLocalization(props: WithoutLocalizationProps<P>): ReactElement {
const l10n = useContext(FluentContext);
const { l10n } = useContext(FluentContext);
// Re-bind getString to trigger a re-render of Inner.
const getString = l10n.getString.bind(l10n);
return createElement(Inner, { getString, ...props } as P);
Expand Down

0 comments on commit 05ffc2c

Please sign in to comment.