From 1edbd6e4737d1e72d50111816b23877d4d9e45fa Mon Sep 17 00:00:00 2001 From: Felix Beceic Date: Wed, 8 Mar 2023 18:20:51 +0100 Subject: [PATCH] #65 Improve Intl utilities & extend intlDictionary --- libs/intl/src/Intl.tsx | 28 ++++++++++++++++------------ libs/intl/src/IntlProvider.tsx | 27 ++++++++++++++++----------- libs/intl/src/intlDictionary.js | 3 +++ libs/intl/src/useIntlContext.tsx | 10 +++++++--- 4 files changed, 42 insertions(+), 26 deletions(-) diff --git a/libs/intl/src/Intl.tsx b/libs/intl/src/Intl.tsx index 4c7565a..3bc1cae 100644 --- a/libs/intl/src/Intl.tsx +++ b/libs/intl/src/Intl.tsx @@ -40,17 +40,21 @@ interface IntlProps { } export default function Intl({ name, params, children }: IntlProps) { - const { lang, dictionary, intlUtil } = useIntlContext(); - - if (!dictionary?.translations?.[lang]?.[name] && !dictionary?.messages?.[name]) { - return <>{name}; + const intlContext = useIntlContext(); + + if (intlContext) { + const { lang, dictionary, intlUtil } = intlContext; + if (!dictionary?.translations?.[lang]?.[name] && !dictionary?.messages?.[name]) { + return <>{name}; + } + + return ( + <> + {intlUtil.translate({ name, params, render: children }).map((it, i) => ( + {it} + ))} + + ); } - - return ( - <> - {intlUtil.translate({ name, params, render: children }).map((it, i) => ( - {it} - ))} - - ); + return <>; } diff --git a/libs/intl/src/IntlProvider.tsx b/libs/intl/src/IntlProvider.tsx index cacce72..65ae6c9 100644 --- a/libs/intl/src/IntlProvider.tsx +++ b/libs/intl/src/IntlProvider.tsx @@ -17,6 +17,7 @@ import * as React from "react"; +import _ from "lodash"; import { IntlContext as ReactIntlContext, IntlProvider as ReactIntlProvider, IntlShape } from "react-intl"; import { createNamedContext } from "@tiller-ds/util"; @@ -32,6 +33,7 @@ export type CommonKeys = { autocompleteNoResults?: string; selectNoResults?: string; paginationSummary?: string; + pageResizerSummary?: string; }; type IntlProviderProps = { @@ -47,7 +49,7 @@ type IntlProviderProps = { dictionary?: Dictionary; /** - * Similar to dictionary prop, but serves as a function which generally receives your dictionary as a return value. + * Similar to dictionary prop, but represents a promise which returns your dictionary. */ loadDictionary?: ((lang: string) => Promise) | undefined; @@ -80,20 +82,23 @@ export type IntlContextType = IntlValue & { intl: IntlShape; }; +const defaultKeyConfig: CommonKeys = { + required: "required", + autocompleteNoTags: "autocomplete.noTags", + autocompleteAddTag: "autocomplete.addTag", + autocompleteNoResults: "autocomplete.noResults", + selectNoResults: "select.noResults", + paginationSummary: "pagination.summary", + pageResizerSummary: "pageResizer.summary", +}; + export const IntlContext = createNamedContext("IntlContext"); export function useIntl( language: string, dict: Dictionary | undefined = intlDictionary, loadDictionary: ((lang: string) => Promise) | undefined, - keyConfig: CommonKeys = { - required: "required", - autocompleteNoTags: "autocomplete.noTags", - autocompleteAddTag: "autocomplete.addTag", - autocompleteNoResults: "autocomplete.noResults", - selectNoResults: "select.noResults", - paginationSummary: "pagination.summary", - }, + keyConfig: CommonKeys = defaultKeyConfig, ): IntlValue { const [lang, setLang] = React.useState(language); const [dictionary, setDictionary] = React.useState(dict || ({} as Dictionary)); @@ -133,9 +138,9 @@ export function useIntl( changeLang, dictionary, intlUtil: new IntlUtil(dictionary, lang), - commonKeys: keyConfig, + commonKeys: _.merge(defaultKeyConfig, keyConfig), }), - [lang, dictionary, changeLang], + [lang, changeLang, dictionary, keyConfig], ); } diff --git a/libs/intl/src/intlDictionary.js b/libs/intl/src/intlDictionary.js index a3738be..b70f81b 100644 --- a/libs/intl/src/intlDictionary.js +++ b/libs/intl/src/intlDictionary.js @@ -6,6 +6,7 @@ export default { "autocomplete.noResults": "No results for:", "select.noResults": "No results", "pagination.summary": "Showing {from} to {to} of {total} results", + "pageResizer.summary": "Show {pageSizeSelect} results per page", }, translations: { hr: { @@ -15,6 +16,7 @@ export default { "autocomplete.noResults": "Nema rezultata za:", "select.noResults": "Nema rezultata", "pagination.summary": "Prikazuje se {from} do {to} od {total} rezultata", + "pageResizer.summary": "Prikaži {pageSizeSelect} rezultata po stranici", }, en: { required: "Required field", @@ -23,6 +25,7 @@ export default { "autocomplete.noResults": "No results for:", "select.noResults": "No results", "pagination.summary": "Showing {from} to {to} of {total} results", + "pageResizer.summary": "Show {pageSizeSelect} results per page", }, }, }; diff --git a/libs/intl/src/useIntlContext.tsx b/libs/intl/src/useIntlContext.tsx index 1a364a2..76d13a0 100644 --- a/libs/intl/src/useIntlContext.tsx +++ b/libs/intl/src/useIntlContext.tsx @@ -1,13 +1,17 @@ import * as React from "react"; -import { IntlContext } from "./IntlProvider"; +import { IntlContext, IntlContextType } from "./IntlProvider"; -export function useIntlContext() { +export function useIntlContext(returnDefault?: boolean) { const context = React.useContext(IntlContext); - if (!context) { + if (!context && !returnDefault) { return undefined; } + if (!context && returnDefault) { + return { lang: "en" } as IntlContextType; + } + return context; }