-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(Forms): add
Form.useTranslation
hook (#4123)
This PR relies on #4121 as of now. This lets form components consume the internal translations as well as extending the translations with your own strings: ```tsx import { Form } from '@dnb/eufemia/extensions/forms' const myTranslations = { 'en-GB': { Custom: { translation: 'My translation with a {myKey}', }, }, } function MyComponent() { const { Custom, formatMessage } = Form.useTranslation<myTranslations>() // Use it directly const str1 = formatMessage(Custom.translation, { myKey: 'value!', }) // Or use it with a key const str2 = formatMessage('Field.errorRequired', { myKey: 'value!', }) return <>MyComponent</> } <Form.Handler locale="en-GB" translations={myTranslations}> <MyComponent /> </Form.Handler> ``` --------- Co-authored-by: Anders <[email protected]>
- Loading branch information
1 parent
ca15887
commit 6f40922
Showing
12 changed files
with
762 additions
and
181 deletions.
There are no files selected for viewing
23 changes: 23 additions & 0 deletions
23
...nb-design-system-portal/src/docs/uilib/extensions/forms/Form/useTranslation.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
--- | ||
title: 'useTranslation' | ||
description: '`Form.useTranslation` is a hook that returns the translations for the current locale.' | ||
showTabs: true | ||
tabs: | ||
- title: Info | ||
key: '/info' | ||
- title: Demos | ||
key: '/demos' | ||
breadcrumb: | ||
- text: Forms | ||
href: /uilib/extensions/forms/ | ||
- text: Form | ||
href: /uilib/extensions/forms/Form/ | ||
- text: Form.useTranslation | ||
href: /uilib/extensions/forms/Form/useTranslation/ | ||
--- | ||
|
||
import Info from 'Docs/uilib/extensions/forms/Form/useTranslation/info' | ||
import Demos from 'Docs/uilib/extensions/forms/Form/useTranslation/demos' | ||
|
||
<Info /> | ||
<Demos /> |
78 changes: 78 additions & 0 deletions
78
...dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/useTranslation/Examples.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/* eslint-disable @typescript-eslint/ban-ts-comment */ | ||
// @ts-nocheck | ||
import React from 'react' | ||
import ComponentBox from '../../../../../../shared/tags/ComponentBox' | ||
import { Form } from '@dnb/eufemia/src/extensions/forms' | ||
|
||
export const CustomTranslations = () => { | ||
return ( | ||
<ComponentBox> | ||
{() => { | ||
const MyField = () => { | ||
const { Custom, formatMessage } = Form.useTranslation() | ||
|
||
const myTranslation = formatMessage(Custom.translation, { | ||
myKey: 'value!', | ||
}) | ||
console.log('Custom', myTranslation) | ||
|
||
return <>{myTranslation}</> | ||
} | ||
|
||
const MyForm = () => { | ||
return ( | ||
<Form.Handler | ||
locale="en-GB" | ||
translations={{ | ||
'en-GB': { | ||
Custom: { translation: 'My translation with a {myKey}' }, | ||
}, | ||
}} | ||
> | ||
<MyField /> | ||
</Form.Handler> | ||
) | ||
} | ||
|
||
return <MyForm /> | ||
}} | ||
</ComponentBox> | ||
) | ||
} | ||
|
||
export const GetTranslation = () => { | ||
return ( | ||
<ComponentBox> | ||
{() => { | ||
const MyField = () => { | ||
const { formatMessage } = Form.useTranslation() | ||
|
||
const myTranslation = formatMessage('Custom.translation', { | ||
myKey: 'value!', | ||
}) | ||
const errorRequired = formatMessage('Field.errorRequired') | ||
console.log(errorRequired) | ||
|
||
return <>{myTranslation}</> | ||
} | ||
|
||
const MyForm = () => { | ||
return ( | ||
<Form.Handler | ||
locale="en-GB" | ||
translations={{ | ||
'en-GB': { | ||
Custom: { translation: 'My translation with a {myKey}' }, | ||
}, | ||
}} | ||
> | ||
<MyField /> | ||
</Form.Handler> | ||
) | ||
} | ||
|
||
return <MyForm /> | ||
}} | ||
</ComponentBox> | ||
) | ||
} |
15 changes: 15 additions & 0 deletions
15
...ign-system-portal/src/docs/uilib/extensions/forms/Form/useTranslation/demos.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
--- | ||
showTabs: true | ||
--- | ||
|
||
import * as Examples from './Examples' | ||
|
||
## Demos | ||
|
||
### Custom translations example | ||
|
||
<Examples.CustomTranslations /> | ||
|
||
### Get translations with a key | ||
|
||
<Examples.GetTranslation /> |
155 changes: 155 additions & 0 deletions
155
...sign-system-portal/src/docs/uilib/extensions/forms/Form/useTranslation/info.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
--- | ||
showTabs: true | ||
--- | ||
|
||
## Description | ||
|
||
The `Form.useTranslation` is a hook that returns the translations for the current locale. | ||
|
||
```tsx | ||
import { Form } from '@dnb/eufemia/extensions/forms' | ||
|
||
function MyComponent() { | ||
const { Field } = Form.useTranslation() | ||
const { errorRequired } = Field | ||
|
||
return <>MyComponent</> | ||
} | ||
|
||
render( | ||
<Form.Handler locale="en-GB"> | ||
<MyComponent /> | ||
</Form.Handler>, | ||
) | ||
``` | ||
|
||
## Additional utilities | ||
|
||
In addition to all internal translations, you also get; | ||
|
||
- `formatMessage` - a function you can use to get a specific translation based on a key (flattened object with dot-notation). | ||
|
||
```tsx | ||
import { Form } from '@dnb/eufemia/extensions/forms' | ||
|
||
function MyComponent() { | ||
const { formatMessage } = Form.useTranslation() | ||
const errorRequired = formatMessage('Field.errorRequired') | ||
|
||
return <>MyComponent</> | ||
} | ||
|
||
render( | ||
<Form.Handler locale="en-GB"> | ||
<MyComponent /> | ||
</Form.Handler>, | ||
) | ||
``` | ||
|
||
## Custom translations | ||
|
||
You can also extend the translations with your own custom translations. | ||
|
||
```tsx | ||
import { Form } from '@dnb/eufemia/extensions/forms' | ||
|
||
const myTranslations = { | ||
'nb-NO': { myString: 'Min egendefinerte streng' }, | ||
'en-GB': { | ||
// Cascaded translations | ||
Nested: { | ||
stringWithArgs: 'My custom string with an argument: {myKey}', | ||
}, | ||
|
||
// Flat translations | ||
'Nested.stringWithArgs': 'My custom string with an argument: {myKey}', | ||
}, | ||
} | ||
|
||
const MyComponent = () => { | ||
const t = Form.useTranslation<typeof myTranslations>() | ||
|
||
// Internal translations | ||
const existingString = t.Field.errorRequired | ||
|
||
// Your translations | ||
const myString = t.myString | ||
|
||
// Use the "formatMessage" function to handle strings with arguments | ||
const myStringWithArgsA = t.formatMessage(t.Nested.stringWithArgs, { | ||
myKey: 'myValue', | ||
}) | ||
// You can also get the string with a key (dot-notation) | ||
const myStringWithArgsB = t.formatMessage('Nested.stringWithArgs', { | ||
myKey: 'myValue', | ||
}) | ||
|
||
return <>MyComponent</> | ||
} | ||
|
||
render( | ||
<Form.Handler translations={myTranslations}> | ||
<MyComponent /> | ||
</Form.Handler>, | ||
) | ||
``` | ||
|
||
## Using the `<Translation />` | ||
|
||
Instead of using the hook, you can also, use the `<Translation />` component to consume your translations: | ||
|
||
```tsx | ||
import { Form } from '@dnb/eufemia/extensions/forms' | ||
import { Translation, TranslationProps } from '@dnb/eufemia/shared' | ||
|
||
const myTranslations = { | ||
'nb-NO': { 'custom.string': 'Min egendefinerte streng' }, | ||
'en-GB': { 'custom.string': 'My custom string' }, | ||
} | ||
|
||
// For TypeScript support | ||
type Tr<T> = TranslationProps<T[keyof T]> | ||
const Tr = (props: Tr<typeof myTranslations>) => <Translation {...props} /> | ||
|
||
render( | ||
<Form.Handler translations={myTranslations}> | ||
<Form.MainHeading> | ||
<Translation id="custom.string" /> | ||
</Form.MainHeading> | ||
|
||
<Form.SubHeading> | ||
<Tr id={(t) => t.custom.string} /> | ||
</Form.SubHeading> | ||
</Form.Handler>, | ||
) | ||
``` | ||
|
||
## Use the shared Provider to customize translations | ||
|
||
```tsx | ||
import { Form, Field } from '@dnb/eufemia/extensions/forms' | ||
import { Provider, Translation } from '@dnb/eufemia/shared' | ||
|
||
const myTranslations = { | ||
'nb-NO': { | ||
'PhoneNumber.label': 'Egendefinert', | ||
'custom.string': 'Min egendefinerte streng', | ||
}, | ||
'en-GB': { | ||
'PhoneNumber.label': 'Custom', | ||
'custom.string': 'My custom string', | ||
}, | ||
} | ||
|
||
render( | ||
<Provider translations={myTranslations}> | ||
<Heading> | ||
<Translation id="custom.string" /> | ||
</Heading> | ||
|
||
<Form.Handler> | ||
<Field.PhoneNumber /> | ||
</Form.Handler> | ||
</Provider>, | ||
) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.