Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 9 additions & 18 deletions packages/use-i18n/src/__tests__/usei18n.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,6 @@ type Locale = {
title: 'Welcome on @scaelway/ui i18n hook'
}

type NamespaceLocale = {
name: 'Name'
lastName: 'Last Name'
languages: 'Languages'
}

const wrapper =
({
loadDateLocale = async (locale: string) =>
Expand Down Expand Up @@ -98,7 +92,7 @@ describe('i18n hook', () => {
})

it('should use defaultLoad, useTranslation, switch local and translate', async () => {
const { result } = renderHook(() => useTranslation<Locale>([]), {
const { result } = renderHook(() => useTranslation([]), {
wrapper: wrapper({ defaultLocale: 'en' }),
})
// first render there is no load
Expand Down Expand Up @@ -136,7 +130,7 @@ describe('i18n hook', () => {
}) => import(`./locales/namespaces/${locale}/${namespace}.json`)

const { result } = renderHook(
() => useTranslation<NamespaceLocale>(['user', 'profile'], load),
() => useTranslation(['user', 'profile'], load),
{
wrapper: wrapper({
defaultLocale: 'en',
Expand Down Expand Up @@ -191,16 +185,13 @@ describe('i18n hook', () => {
namespace: string
}) => import(`./locales/namespaces/${locale}/${namespace}.json`)

const { result } = renderHook(
() => useTranslation<NamespaceLocale>(['user'], load),
{
wrapper: wrapper({
defaultLocale: 'fr',
enableDefaultLocale: true,
supportedLocales: ['en', 'fr'],
}),
},
)
const { result } = renderHook(() => useTranslation(['user'], load), {
wrapper: wrapper({
defaultLocale: 'fr',
enableDefaultLocale: true,
supportedLocales: ['en', 'fr'],
}),
})

// current local will be 'en' based on navigator
// await load of locales
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable react-hooks/rules-of-hooks */
import { expectError, expectType } from 'tsd-lite'
import { useI18n } from '../usei18n'

// eslint-disable-next-line react-hooks/rules-of-hooks
const { namespaceTranslation } = useI18n<{
hello: 'world'
'doe.john': 'John Doe'
Expand Down Expand Up @@ -50,7 +50,3 @@ expectType<string>(
)
expectError(scopedT3('john', {}))
expectError(scopedT3('john'))

// Required generic
const { namespaceTranslation: namespaceTranslation2 } = useI18n()
expectError(namespaceTranslation2('test'))
8 changes: 2 additions & 6 deletions packages/use-i18n/src/__typetests__/t.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable react-hooks/rules-of-hooks */
import { expectError, expectType } from 'tsd-lite'
import { useI18n, useTranslation } from '../usei18n'
import { useI18n } from '../usei18n'

// eslint-disable-next-line react-hooks/rules-of-hooks
const { t } = useI18n<{
hello: 'world'
'doe.john': 'John Doe'
Expand Down Expand Up @@ -58,7 +58,3 @@ expectType<string>(
),
}),
)

// Required generic
const { t: t2 } = useI18n()
expectError(t2('test'))
26 changes: 5 additions & 21 deletions packages/use-i18n/src/usei18n.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,6 @@ import type { ReactParamsObject, ScopedTranslateFn, TranslateFn } from './types'
const LOCALE_ITEM_STORAGE = 'locale'

type TranslationsByLocales = Record<string, BaseLocale>
type RequiredGenericContext<Locale extends BaseLocale> =
keyof Locale extends never
? Omit<Context<Locale>, 't' | 'namespaceTranslation'> & {
t: (str: 'You must pass a generic argument to useI18n()') => void
namespaceTranslation: (
str: 'You must pass a generic argument to useI18n()',
) => void
}
: Context<Locale>

const areNamespacesLoaded = (
namespaces: string[],
Expand Down Expand Up @@ -108,23 +99,19 @@ interface Context<Locale extends BaseLocale> {
// useI18n / useTranslation requires to explicitely give a Locale to use.
const I18nContext = createContext<Context<any> | undefined>(undefined)

export function useI18n<
// eslint-disable-next-line @typescript-eslint/ban-types
Locale extends BaseLocale = {},
>(): RequiredGenericContext<Locale> {
export function useI18n<Locale extends BaseLocale>(): Context<Locale> {
const context = useContext(I18nContext)
if (context === undefined) {
throw new Error('useI18n must be used within a I18nProvider')
}

return context as unknown as RequiredGenericContext<Locale>
return context as unknown as Context<Locale>
}

// eslint-disable-next-line @typescript-eslint/ban-types
export function useTranslation<Locale extends BaseLocale = {}>(
export function useTranslation<Locale extends BaseLocale>(
namespaces: string[] = [],
load: LoadTranslationsFn | undefined = undefined,
): RequiredGenericContext<Locale> & { isLoaded: boolean } {
): Context<Locale> & { isLoaded: boolean } {
const context = useContext(I18nContext)
if (context === undefined) {
throw new Error('useTranslation must be used within a I18nProvider')
Expand All @@ -143,10 +130,7 @@ export function useTranslation<Locale extends BaseLocale = {}>(
[loadedNamespaces, namespaces],
)

return {
...context,
isLoaded,
} as unknown as RequiredGenericContext<Locale> & {
return { ...context, isLoaded } as unknown as Context<Locale> & {
isLoaded: boolean
}
}
Expand Down