Skip to content

Commit 6fcceb4

Browse files
authored
Merge pull request marmelab#10615 from marmelab/fix/Translate
Improve implementation of the `Translate` component
2 parents 878323f + 223c74e commit 6fcceb4

6 files changed

Lines changed: 70 additions & 80 deletions

File tree

docs/Translate.md

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,42 @@ const MarkAsUnreadButton = () => {
3737
| Prop | Required | Type | Default | Description |
3838
| ---------- | -------- | ----------- | ------- | --------------------------------------------------------------- |
3939
| `i18nKey` | Required | `string` | - | The translation key. |
40-
| `args` | Optional | `Object` | - | The options used for pluralization and interpolation. |
4140
| `children` | Optional | `ReactNode` | - | The default content to display if the translation is not found. |
41+
| `options` | Optional | `Object` | - | The options used for pluralization and interpolation. |
4242

43-
## `args`
43+
## `children`
44+
45+
`<Translate>` renders its child node if `translate` doesn't find a translation for the `i18nKey`.
46+
47+
```tsx
48+
const messages = {};
49+
50+
<Translate i18nKey="ra.page.loading">Loading</Translate>
51+
// Loading
52+
```
53+
54+
## `i18nKey`
55+
56+
The translation key, used to look up the translation message.
57+
58+
```tsx
59+
const messages = {
60+
resources: {
61+
reviews: {
62+
action: {
63+
reject: 'Reject review',
64+
},
65+
},
66+
},
67+
};
68+
69+
<Translate i18nKey="resources.reviews.action.reject" />
70+
// Reject review
71+
```
72+
73+
## `options`
4474

45-
Use the `args` props to pass additional options to the `translate` function, e.g. for [pluralization or interpolation](./TranslationTranslating.md#interpolation-pluralization-and-default-translation).
75+
Use the `options` props to pass additional options to the `translate` function, e.g. for [pluralization or interpolation](./TranslationTranslating.md#interpolation-pluralization-and-default-translation).
4676

4777
{% raw %}
4878

@@ -53,7 +83,7 @@ const messages = {
5383
},
5484
};
5585

56-
<Translate i18nKey="custom.hello_world" args={{ name: 'John' }} />
86+
<Translate i18nKey="custom.hello_world" options={{ name: 'John' }} />
5787
// Hello, John!
5888
```
5989

@@ -72,38 +102,8 @@ const messages = {
72102
},
73103
};
74104

75-
<Translate i18nKey="ra.notification.deleted" args={{ smart_count: 2 }} />
105+
<Translate i18nKey="ra.notification.deleted" options={{ smart_count: 2 }} />
76106
// 2 items deleted
77107
```
78108

79109
{% endraw %}
80-
81-
## `children`
82-
83-
`<Translate>` renders its child node if `translate` doesn't find a translation for the `i18nKey`.
84-
85-
```tsx
86-
const messages = {};
87-
88-
<Translate i18nKey="ra.page.loading">Loading</Translate>
89-
// Loading
90-
```
91-
92-
## `i18nKey`
93-
94-
The translation key, used to look up the translation message.
95-
96-
```tsx
97-
const messages = {
98-
resources: {
99-
reviews: {
100-
action: {
101-
reject: 'Reject review',
102-
},
103-
},
104-
},
105-
};
106-
107-
<Translate i18nKey="resources.reviews.action.reject" />
108-
// Reject review
109-
```

packages/ra-core/src/i18n/Translate.spec.tsx

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,12 @@ import React from 'react';
22
import { render } from '@testing-library/react';
33

44
import {
5-
Args,
5+
Options,
66
Basic,
77
NoTranslation,
8-
NoTranslationWithChildren,
8+
NoTranslationWithChildrenAsNode,
9+
NoTranslationWithChildrenAsString,
910
} from './Translate.stories';
10-
import { TestTranslationProvider } from './TestTranslationProvider';
11-
import { Translate } from './Translate';
1211

1312
describe('<Translate />', () => {
1413
it('should render the translation', () => {
@@ -18,15 +17,9 @@ describe('<Translate />', () => {
1817

1918
it('should render the translation event if children is set', () => {
2019
const { container } = render(
21-
<TestTranslationProvider
22-
messages={{
23-
custom: {
24-
myKey: 'My Translated Key',
25-
},
26-
}}
27-
>
28-
<Translate i18nKey="custom.myKey">Lorem Ipsum</Translate>
29-
</TestTranslationProvider>
20+
<NoTranslationWithChildrenAsString
21+
messages={{ custom: { myKey: 'My Translated Key' } }}
22+
/>
3023
);
3124
expect(container.innerHTML).toBe('My Translated Key');
3225
});
@@ -37,21 +30,19 @@ describe('<Translate />', () => {
3730
});
3831

3932
it('should render the children (string) if no translation available', () => {
40-
const { container } = render(<NoTranslationWithChildren />);
33+
const { container } = render(<NoTranslationWithChildrenAsString />);
4134
expect(container.innerHTML).toBe('My Default Translation');
4235
});
4336

4437
it('should render the children (ReactNode) if no translation available', () => {
45-
const { container } = render(
46-
<NoTranslationWithChildren isChildrenANode />
47-
);
38+
const { container } = render(<NoTranslationWithChildrenAsNode />);
4839
expect(container.innerHTML).toBe(
4940
'<div style="color: red;"><i>My Default Translation</i></div>'
5041
);
5142
});
5243

53-
it('should render the translation with args', () => {
54-
const { container } = render(<Args />);
44+
it('should render the translation with options', () => {
45+
const { container } = render(<Options />);
5546
expect(container.innerHTML).toBe('It cost 6.00 $');
5647
});
5748
});

packages/ra-core/src/i18n/Translate.stories.tsx

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,37 +24,30 @@ export const NoTranslation = () => (
2424
</TestTranslationProvider>
2525
);
2626

27-
export const NoTranslationWithChildren = ({
28-
isChildrenANode = false,
29-
}: {
30-
isChildrenANode?: boolean;
31-
}) => (
27+
export const NoTranslationWithChildrenAsString = ({ messages = {} }) => (
28+
<TestTranslationProvider messages={messages}>
29+
<Translate i18nKey="custom.myKey">My Default Translation</Translate>
30+
</TestTranslationProvider>
31+
);
32+
33+
export const NoTranslationWithChildrenAsNode = () => (
3234
<TestTranslationProvider messages={{}}>
3335
<Translate i18nKey="custom.myKey">
34-
{isChildrenANode ? (
35-
<div style={{ color: 'red' }}>
36-
<i>My Default Translation</i>
37-
</div>
38-
) : (
39-
'My Default Translation'
40-
)}
36+
<div style={{ color: 'red' }}>
37+
<i>My Default Translation</i>
38+
</div>
4139
</Translate>
4240
</TestTranslationProvider>
4341
);
4442

45-
NoTranslationWithChildren.args = { isChildrenANode: false };
46-
NoTranslationWithChildren.argTypes = {
47-
isChildrenANode: { control: 'boolean' },
48-
};
49-
50-
export const Args = () => (
43+
export const Options = () => (
5144
<TestTranslationProvider
5245
messages={{
5346
custom: {
5447
myKey: ({ price }) => `It cost ${price}.00 $`,
5548
},
5649
}}
5750
>
58-
<Translate i18nKey="custom.myKey" args={{ price: '6' }} />
51+
<Translate i18nKey="custom.myKey" options={{ price: '6' }} />
5952
</TestTranslationProvider>
6053
);

packages/ra-core/src/i18n/Translate.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import React, { ReactNode } from 'react';
22
import { useTranslate } from './useTranslate';
33

4-
export const Translate = ({ i18nKey, args, children }: TranslateProps) => {
4+
export const Translate = ({ i18nKey, options, children }: TranslateProps) => {
55
const translate = useTranslate();
66
const translatedMessage = translate(
77
i18nKey,
8-
typeof children === 'string' ? { _: children, ...args } : args
8+
typeof children === 'string' ? { _: children, ...options } : options
99
);
1010

1111
if (translatedMessage) {
@@ -17,5 +17,5 @@ export const Translate = ({ i18nKey, args, children }: TranslateProps) => {
1717
export interface TranslateProps {
1818
i18nKey: string;
1919
children?: ReactNode;
20-
args?: Object;
20+
options?: Object;
2121
}

packages/ra-i18n-i18next/src/index.stories.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,10 +201,13 @@ export const TranslateComponent = () => {
201201
<br />
202202
<Translate
203203
i18nKey="custom.helloWorld"
204-
args={{ myWorld: 'world' }}
204+
options={{ myWorld: 'world' }}
205205
/>
206206
<br />
207-
<Translate i18nKey="custom.countBeer" args={{ smart_count: 2 }} />
207+
<Translate
208+
i18nKey="custom.countBeer"
209+
options={{ smart_count: 2 }}
210+
/>
208211
</I18nContextProvider>
209212
);
210213
};

packages/ra-i18n-polyglot/src/index.stories.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,13 @@ export const TranslateComponent = () => {
118118
<br />
119119
<Translate
120120
i18nKey="custom.helloWorld"
121-
args={{ myWorld: 'world' }}
121+
options={{ myWorld: 'world' }}
122122
/>
123123
<br />
124-
<Translate i18nKey="custom.countBeer" args={{ smart_count: 2 }} />
124+
<Translate
125+
i18nKey="custom.countBeer"
126+
options={{ smart_count: 2 }}
127+
/>
125128
</I18nContextProvider>
126129
);
127130
};

0 commit comments

Comments
 (0)