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
5 changes: 5 additions & 0 deletions .changeset/breezy-yaks-taste.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@scaleway/use-i18n": minor
---

fix: typing issue and force use of string array with at least one element for namespaces in useTranslation hook
12 changes: 6 additions & 6 deletions biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,16 @@
"attributePosition": "auto",
"includes": [
"**",
"!**/.next/",
"!**/coverage/",
"!**/node_modules/",
"!**/storybook-static",
"!**/dist/",
"!**/.next/*",
"!**/coverage/*",
"!**/node_modules/*",
"!**/storybook-static/*",
"!**/dist/*",
"!**/pnpm-lock.yaml",
"!**/package.json",
"!**/CHANGELOG.md",
"!**/*.snap",
"!**/__snapshots__/"
"!**/__snapshots__/*"
]
},
"javascript": {
Expand Down
58 changes: 33 additions & 25 deletions packages/use-i18n/src/__tests__/usei18n.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ describe('i18n hook', () => {
const spy = vi.spyOn(console, 'error')
spy.mockImplementation(() => {})

expect(() => renderHook(() => useTranslation())).toThrow(
expect(() => renderHook(() => useTranslation(['test']))).toThrow(
new Error('useTranslation must be used within a I18nProvider'),
)
spy.mockRestore()
Expand All @@ -133,34 +133,41 @@ describe('i18n hook', () => {
spy.mockRestore()
})

it('should use defaultLoad, useTranslation, switch local and translate', async () => {
const { result } = renderHook(() => useTranslation<Locale, Locales>([]), {
wrapper: wrapper({ defaultLocale: 'en' }),
})
// first render there is no load
expect(result.current.t('title')).toEqual('')
it(
'should use defaultLoad, useTranslation, switch local and translate',
async () => {
const { result } = renderHook(
() => useTranslation<Locale, Locales>(['test']),
{
wrapper: wrapper({ defaultLocale: 'en' }),
},
)
// first render there is no load
expect(result.current.t('title')).toEqual('')

await waitFor(() => {
// after load of en locale
expect(result.current.t('title')).toEqual(en.title)
})
await waitFor(() => {
// after load of en locale
expect(result.current.t('title')).toEqual(en.title)
})

await act(async () => {
await result.current.switchLocale('fr')
})
await act(async () => {
await result.current.switchLocale('fr')
})

await waitFor(() => {
expect(result.current.t('title')).toEqual(fr.title)
})
await waitFor(() => {
expect(result.current.t('title')).toEqual(fr.title)
})

await act(async () => {
await result.current.switchLocale('es')
})
await act(async () => {
await result.current.switchLocale('es')
})

await waitFor(() => {
expect(result.current.t('title')).toEqual(es.title)
})
})
await waitFor(() => {
expect(result.current.t('title')).toEqual(es.title)
})
},
{},
)

it('should use specific load on useTranslation', async () => {
const { result } = renderHook(
Expand Down Expand Up @@ -262,7 +269,8 @@ describe('i18n hook', () => {

it('should work with a component', async () => {
const { result } = renderHook(
() => useTranslation<{ 'with.identifier': 'Hello {identifier}' }>([]),
() =>
useTranslation<{ 'with.identifier': 'Hello {identifier}' }>(['test']),
{
wrapper: wrapper({ defaultLocale: 'en' }),
},
Expand Down
4 changes: 3 additions & 1 deletion packages/use-i18n/src/usei18n.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ export function useTranslation<
LocaleParam extends BaseLocale = {},
LocalSupportedType extends string = '',
>(
namespaces: string[] = [],
namespaces: [string, ...string[]],
load: LoadTranslationsFn<LocalSupportedType> | undefined = undefined,
): RequiredGenericContext<LocaleParam, LocalSupportedType> & {
isLoaded: boolean
Expand All @@ -162,6 +162,8 @@ export function useTranslation<
}
const { loadTranslations, namespaces: loadedNamespaces } = context

// here we generate a key string from the array of namespace in order to only trigger the use effect
// when the passed keys change and not when the ref of the array change
const key = namespaces.join(',')
useEffect(() => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
Expand Down
Loading