Skip to content

Commit

Permalink
fix: 🐛 switched to plain objects in i18n helper function
Browse files Browse the repository at this point in the history
Previously it was creating functions but that is not needed.
  • Loading branch information
Can-Sahin committed May 31, 2020
1 parent 30732a8 commit de76cf6
Show file tree
Hide file tree
Showing 10 changed files with 40 additions and 41 deletions.
2 changes: 1 addition & 1 deletion docs/building-blocks/i18n.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export function MyComponent() {
i18n.changeLanguage(language);
};
// The nested objects are intellisense supported ✅
return <div>{t(translations.HomePage.Features.someItem())}</div>;
return <div>{t(translations.HomePage.Features.someItem}</div>;
}
```
Expand Down
19 changes: 10 additions & 9 deletions internals/startingTemplate/src/locales/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { initReactI18next } from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';

import en from './en/translation.json';
import { ConvertedToFunctionsType } from './types';
import { ConvertedToObjectType } from './types';

const translationsJson = {
en: {
Expand All @@ -15,26 +15,25 @@ const translationsJson = {
export type TranslationResource = typeof en;
export type LanguageKey = keyof TranslationResource;

export const translations: ConvertedToFunctionsType<TranslationResource> = {} as any;
export const translations: ConvertedToObjectType<TranslationResource> = {} as any;

/*
* Converts the static JSON file into object where keys are identical
* but values are functions that produces the same key as string.
* Converts the static JSON file into an object where keys are identical
* but values are strings concatenated according to syntax.
* This is helpful when using the JSON file keys and still have the intellisense support
* along with type-safety
*/
const convertToFunctions = (obj: any, dict: {}, current?: string) => {
const convertLanguageJsonToObject = (obj: any, dict: {}, current?: string) => {
Object.keys(obj).forEach(key => {
const currentLookupKey = current ? `${current}.${key}` : key;
if (typeof obj[key] === 'object') {
dict[key] = {};
convertToFunctions(obj[key], dict[key], currentLookupKey);
convertLanguageJsonToObject(obj[key], dict[key], currentLookupKey);
} else {
dict[key] = () => currentLookupKey;
dict[key] = currentLookupKey;
}
});
};

export const i18n = i18next
// pass the i18n instance to react-i18next.
.use(initReactI18next)
Expand All @@ -56,5 +55,7 @@ export const i18n = i18next
escapeValue: false, // not needed for react as it escapes by default
},
},
() => convertToFunctions(en, translations),
() => {
convertLanguageJsonToObject(en, translations);
},
);
6 changes: 2 additions & 4 deletions internals/startingTemplate/src/locales/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
export type ConvertedToFunctionsType<T> = {
[P in keyof T]: T[P] extends string
? () => string
: ConvertedToFunctionsType<T[P]>;
export type ConvertedToObjectType<T> = {
[P in keyof T]: T[P] extends string ? string : ConvertedToObjectType<T[P]>;
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
},
"husky": {
"hooks": {
"pre-commit": "npm run verify-startingTemplate-changes && npm run checkTs && lint-staged",
"pre-commit": "npm run checkTs && lint-staged && npm run verify-startingTemplate-changes",
"prepare-commit-msg": "devmoji -e",
"commit-msg": "if git-branch-is dev; then commitlint -E HUSKY_GIT_PARAMS; fi"
}
Expand Down
16 changes: 8 additions & 8 deletions src/app/containers/HomePage/Features.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,9 @@ export function Features() {
<Feature>
<INTLIcon className="feature-icon" />
<Content>
<SubTitle>{t(translations.i18nFeature.title())} </SubTitle>
<SubTitle>{t(translations.i18nFeature.title)} </SubTitle>
<P>
{t(translations.i18nFeature.description())}
{t(translations.i18nFeature.description)}
<br />
<small>
(Only some of the features below are translated to demonstrate
Expand All @@ -97,9 +97,9 @@ export function Features() {
<Feature>
<RouteIcon className="feature-icon" />
<Content>
<SubTitle>{t(translations.routingFeature.title())}</SubTitle>
<SubTitle>{t(translations.routingFeature.title)}</SubTitle>
<P>
{t(translations.routingFeature.description())}
{t(translations.routingFeature.description)}
<br />
<small>
Go to our{' '}
Expand All @@ -112,15 +112,15 @@ export function Features() {
<Feature>
<InstantFeedbackIcon className="feature-icon" />
<Content>
<SubTitle>{t(translations.feedbackFeature.title())}</SubTitle>
<P>{t(translations.feedbackFeature.description())}</P>
<SubTitle>{t(translations.feedbackFeature.title)}</SubTitle>
<P>{t(translations.feedbackFeature.description)}</P>
</Content>
</Feature>
<Feature>
<ScaffoldingIcon className="feature-icon" />
<Content>
<SubTitle>{t(translations.scaffoldingFeature.title())}</SubTitle>
<P>{t(translations.scaffoldingFeature.description())}</P>
<SubTitle>{t(translations.scaffoldingFeature.title)}</SubTitle>
<P>{t(translations.scaffoldingFeature.description)}</P>
</Content>
</Feature>
<Feature>
Expand Down
4 changes: 2 additions & 2 deletions src/app/containers/LanguageSwitch/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ describe('<LanguageSwitch />', () => {

let languageSwitch = renderLanguageSwitch();
let label = languageSwitch.queryByText(
t(translations.i18nFeature.selectLanguage()),
t(translations.i18nFeature.selectLanguage),
);
expect(label).toBeInTheDocument();

Expand All @@ -35,7 +35,7 @@ describe('<LanguageSwitch />', () => {

languageSwitch = renderLanguageSwitch();
label = languageSwitch.queryByText(
t(translations.i18nFeature.selectLanguage()),
t(translations.i18nFeature.selectLanguage),
);
expect(label).toBeInTheDocument();
});
Expand Down
2 changes: 1 addition & 1 deletion src/app/containers/LanguageSwitch/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export function LanguageSwitch() {

return (
<Wrapper>
<FormLabel>{t(translations.i18nFeature.selectLanguage())}</FormLabel>
<FormLabel>{t(translations.i18nFeature.selectLanguage)}</FormLabel>
<Languages>
<Radio
id="en"
Expand Down
6 changes: 3 additions & 3 deletions src/locales/__tests__/i18n.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ describe('i18n', () => {

it('should initate i18n with translations', async () => {
const t = await i18n;
expect(
t(translations.feedbackFeature.description()).length,
).toBeGreaterThan(0);
expect(t(translations.feedbackFeature.description).length).toBeGreaterThan(
0,
);
});
});
18 changes: 10 additions & 8 deletions src/locales/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import LanguageDetector from 'i18next-browser-languagedetector';

import en from './en/translation.json';
import de from './de/translation.json';
import { ConvertedToFunctionsType } from './types';
import { ConvertedToObjectType } from './types';

const translationsJson = {
en: {
Expand All @@ -19,22 +19,22 @@ const translationsJson = {
export type TranslationResource = typeof en;
export type LanguageKey = keyof TranslationResource;

export const translations: ConvertedToFunctionsType<TranslationResource> = {} as any;
export const translations: ConvertedToObjectType<TranslationResource> = {} as any;

/*
* Converts the static JSON file into object where keys are identical
* but values are functions that produces the same key as string.
* Converts the static JSON file into an object where keys are identical
* but values are strings concatenated according to syntax.
* This is helpful when using the JSON file keys and still have the intellisense support
* along with type-safety
*/
const convertToFunctions = (obj: any, dict: {}, current?: string) => {
const convertLanguageJsonToObject = (obj: any, dict: {}, current?: string) => {
Object.keys(obj).forEach(key => {
const currentLookupKey = current ? `${current}.${key}` : key;
if (typeof obj[key] === 'object') {
dict[key] = {};
convertToFunctions(obj[key], dict[key], currentLookupKey);
convertLanguageJsonToObject(obj[key], dict[key], currentLookupKey);
} else {
dict[key] = () => currentLookupKey;
dict[key] = currentLookupKey;
}
});
};
Expand All @@ -59,5 +59,7 @@ export const i18n = i18next
escapeValue: false, // not needed for react as it escapes by default
},
},
() => convertToFunctions(en, translations),
() => {
convertLanguageJsonToObject(en, translations);
},
);
6 changes: 2 additions & 4 deletions src/locales/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
export type ConvertedToFunctionsType<T> = {
[P in keyof T]: T[P] extends string
? () => string
: ConvertedToFunctionsType<T[P]>;
export type ConvertedToObjectType<T> = {
[P in keyof T]: T[P] extends string ? string : ConvertedToObjectType<T[P]>;
};

0 comments on commit de76cf6

Please sign in to comment.