feat: Add public useI18n hook - #4854
Conversation
| * Public hook for third-party component libraries to resolve translations | ||
| * through I18nProvider under their own namespace. | ||
| */ | ||
| export function useI18n(namespace: string, component: string): I18nFormatFunction { |
There was a problem hiding this comment.
It looks like the only difference between the public-facing hook and internal hook is the type-safety, which would be a shame to lose when making the API public. Internally, we auto-generate an argument mapping alongside the strings, so this comes for "free" for us, but types can still be maintained by builders making custom components and namespaces.
useInternalI18n essentially hardcodes a dependency on I18nFormatArgTypes, but we can make this a generic; something like (I didn't test this out, but it looks reasonable):
export const namespace = 'cloudscape-design-components';
export interface ComponentFormatFunction<
NamespaceTypes,
ComponentName extends StringKeyOf<NamespaceTypes>,
> {
// ...
}
/** The publicly exposed custom i18n function */
export function useCustomI18n<
NamespaceTypes,
ComponentName extends StringKeyOf<NamespaceTypes>
>(
namespace: string,
componentName: ComponentName
): ComponentFormatFunction<NamespaceTypes, ComponentName> {
// ...
}
/** The internal convenience version hardcoded for Cloudscape's namespace and types */
export function useInternalI18n<ComponentName extends StringKeyOf<I18nFormatArgTypes>>(
componentName: ComponentName
): ComponentFormatFunction<I18nFormatArgTypes, ComponentName> {
return useCustomI18n<I18nFormatArgTypes, ComponentName>(namespace, componentName);
}This way, there's no "internal" and "external" version of the hook, the internal is just the external one with a frequently duplicated argument pre-provided.
| @@ -0,0 +1,180 @@ | |||
| // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | |||
There was a problem hiding this comment.
These mostly seem to test the same things the existing unit tests test for, except with a different string value? If you can mostly remove these without Codecov yelling at you, I would be fine with it.
But the specific tests concerning interactions between multiple namespaces, either in a single I18nProvider or in nested providers, are worth keeping.
| * Public hook for third-party component libraries to resolve translations | ||
| * through I18nProvider under their own namespace. | ||
| */ | ||
| export function useI18n(namespace: string, component: string): I18nFormatFunction { |
There was a problem hiding this comment.
(To discuss) useCustomI18n might be a better name; we still want to indicate the hook is meant for custom components, not to replace application-wide internationalization support.
Will discuss with the team tomorrow about the naming.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4854 +/- ##
=======================================
Coverage 97.63% 97.63%
=======================================
Files 957 957
Lines 31097 31100 +3
Branches 11435 11436 +1
=======================================
+ Hits 30361 30364 +3
Misses 689 689
Partials 47 47 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Summary
Add a public namespace-aware
useI18n(namespace, component)hook from@cloudscape-design/components/i18n.This lets component libraries built on top of Cloudscape resolve their own translated strings through the existing
I18nProvidermessage context, without exposingInternalI18nContextor changing Cloudscape's internaluseInternalI18nhook.Changes
useI18n(namespace, component)as a thin public wrapper around the existing formatter.useI18nandI18nFormatFunctionfrom@cloudscape-design/components/i18n.Non-goals
I18nProviderbehavior changes.useInternalI18nor Cloudscape component typing.Testing
npm run quick-buildnode_modules/.bin/eslint src/i18n/context.ts src/i18n/index.ts src/i18n/__tests__/use-i18n.test.tsxTZ=UTC node_modules/.bin/jest -c jest.unit.config.js src/i18n/__tests__/use-i18n.test.tsx src/i18n/__tests__/i18n.test.tsxTZ=UTC node_modules/.bin/jest -c jest.unit.config.js src/__tests__/functional-tests/public-exports.test.tsgit diff --check