Skip to content

Commit

Permalink
feat(core): add use translation hook (refinedev#5733)
Browse files Browse the repository at this point in the history
* feat(core): add useTranslation hook

* feat(docs): add useTranslation doc

* feat(examples): update examples

* chore(core): update changeset

* fix(docs): redirections

* feat(docs): update guide and concept
  • Loading branch information
alicanerdurmaz authored Mar 29, 2024
1 parent 4ff40b5 commit 2b5ac6f
Show file tree
Hide file tree
Showing 26 changed files with 285 additions and 208 deletions.
55 changes: 55 additions & 0 deletions .changeset/friendly-kids-hug.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
"@refinedev/core": patch
---

feat: added `useTranslation` hook. It combines `useTranslate`, `useSetLocale` and `useGetLocale` hooks and returns `translate`, `changeLocale` and `getLocale` methods from that hooks for better developer experience.

It returns all [`i18nProvider`](/docs/i18n/i18n-provider) methods in one hook. It can be used to translate texts, change the locale, and get the current locale in your own components.

```tsx
import { useTranslation } from "@refinedev/core";

export const MyComponent = () => {
const { translate, getLocale, changeLocale } = useTranslation();
const currentLocale = getLocale();

return (
<div>
<h1>{translate("languages")}</h1>
<button
onClick={() => changeLocale("en")}
disabled={currentLocale === "en"}
>
English
</button>
<button
onClick={() => changeLocale("de")}
disabled={currentLocale === "de"}
>
German
</button>
</div>
);
};
```

Example of combining `useTranslation` with `useTranslate`, `useSetLocale` and `useGetLocale` hooks.

```diff
import {
- useGetLocale,
- useSetLocale,
- useTranslate,
+ useTranslation,
} from "@refinedev/core";

export const MyComponent = () => {
- const changeLocale = useSetLocale();
- const getLocale = useGetLocale();
- const translate = useTranslate();

+ const { translate, getLocale, changeLocale } = useTranslation();

return <div>{/* ... */}</div>;
};
```
7 changes: 2 additions & 5 deletions documentation/docs/guides-concepts/i18n/i18n-headless.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,10 @@ export default App;

const HomePageTsxCode = /* jsx */ `
import React from "react";
import { useTranslate, useGetLocale, useSetLocale } from "@refinedev/core";
import { useTranslation } from "@refinedev/core";
export const HomePage = () => {
const translate = useTranslate();
const changeLanguage = useSetLocale();
const getLocale = useGetLocale();
const { translate, getLocale, changeLocale } = useTranslation();
return (
<div>
Expand Down
30 changes: 11 additions & 19 deletions documentation/docs/guides-concepts/i18n/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,7 @@ const App: React.FC = () => {
};
```

This will allow us to put translation features to the followings hooks:

- [`useTranslate`][use-translate] shows translation between different languages.
- [`useSetLocale`][use-setlocale] changes locale at runtime.
- [`useGetLocale`][use-getlocale] getting current locale.
This will allow us to put translation features to the [`useTranslation`][use-translation] hook

Let's add multi-language support to our application using the `react-i18next` framework. When we are done, our application will support both German and English.

Expand Down Expand Up @@ -159,7 +155,7 @@ const App: React.FC = () => {
};
```

After we pass the `i18nProvider` to the `<Refine>` component, all three translation hooks ([`useTranslate`][use-translate], [`useSetLocale`][use-setlocale], [`useGetLocale`][use-getlocale]) will be ready for use.
After we pass the `i18nProvider` to the `<Refine />` component, [`useTranslation`][use-translation] hook will be ready for use.

### Adding the Translations Files

Expand Down Expand Up @@ -215,27 +211,25 @@ All of Refine's components support i18n, meaning that if you want to change thei

### Changing The Locale

Next, we will create a `<Header>` component. This component will allow us to change the language.
Next, we will create a `<Header />` component. This component will allow us to change the language.

```tsx title="src/components/header.tsx"
import { DownOutlined } from "@ant-design/icons";
import { useGetLocale, useSetLocale } from "@refinedev/core";
import { useTranslation } from "@refinedev/core";
import { Avatar, Button, Dropdown, Layout, Menu, Space } from "antd";
import { useTranslation } from "react-i18next";

export const Header: React.FC = () => {
const { i18n } = useTranslation();
const locale = useGetLocale();
const changeLanguage = useSetLocale();

const currentLocale = locale();
const { getLocale, changeLocale } = useTranslation();
const currentLocale = getLocale();

const menu = (
<Menu selectedKeys={currentLocale ? [currentLocale] : []}>
{[...(i18n.languages || [])].sort().map((lang: string) => (
<Menu.Item
key={lang}
onClick={() => changeLanguage(lang)}
onClick={() => changeLocale(lang)}
icon={
<span style={{ marginRight: 8 }}>
<Avatar size={16} src={`/images/flags/${lang}.svg`} />
Expand Down Expand Up @@ -315,12 +309,12 @@ const App: React.FC = () => {

<br />

Finally, we will create the `<PostList>` page and then we will translate texts using `useTranslate`.
Finally, we will create the `<PostList>` page and then we will translate texts using [`useTranslation`][use-translation].

```tsx title="src/App.tsx"
import {
// highlight-next-line
useTranslate,
useTranslation,
useMany,
} from "@refinedev/core";
import {
Expand All @@ -336,7 +330,7 @@ import { IPost, ICategory } from "interfaces";

export const PostList: React.FC = () => {
// highlight-next-line
const translate = useTranslate();
const { translate } = useTranslation();
const { tableProps } = useTable<IPost>();

const categoryIds =
Expand Down Expand Up @@ -425,6 +419,4 @@ Here is the list of all translation keys that you can override:
[i18nnextjs]: /examples/i18n/i18n-nextjs.md
[react-i18next]: https://react.i18next.com/
[create-refine-app]: /docs/getting-started/quickstart.md
[use-translate]: /docs/i18n/hooks/use-translate
[use-getlocale]: /docs/i18n/hooks/use-get-locale
[use-setlocale]: /docs/i18n/hooks/use-set-locale
[use-translation]: /docs/i18n/hooks/use-translation
41 changes: 0 additions & 41 deletions documentation/docs/i18n/hooks/use-get-locale/index.md

This file was deleted.

27 changes: 0 additions & 27 deletions documentation/docs/i18n/hooks/use-set-locale/index.md

This file was deleted.

21 changes: 0 additions & 21 deletions documentation/docs/i18n/hooks/use-translate/index.md

This file was deleted.

84 changes: 84 additions & 0 deletions documentation/docs/i18n/hooks/use-translation/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
---
title: useTranslation
---

The `useTranslation` hook, allows you to use call `translate`, `changeLocale`, and `getLocale` methods from the [`i18nProvider`](/docs/i18n/i18n-provider) that you provided. It can be used to translate texts, change the locale, and get the current locale in your own components.

## Usage

> This hook can only be used if [`i18nProvider`](/docs/i18n/i18n-provider) is provided.
```tsx
import { useTranslation } from "@refinedev/core";

export const MyComponent = () => {
const { translate, getLocale, changeLocale } = useTranslation();
const currentLocale = getLocale();

return (
<div>
<h1>{translate("languages")}</h1>
<button
onClick={() => changeLocale("en")}
disabled={currentLocale === "en"}
>
English
</button>
<button
onClick={() => changeLocale("de")}
disabled={currentLocale === "de"}
>
German
</button>
</div>
);
};
```

## translate

If you need to translate the texts in your own components, you can use `translate` method. It calls the `translate` method from [`i18nProvider`](/docs/i18n/i18n-provider) under the hood.

```tsx
import { useTranslate } from "@refinedev/core";

export const MyComponent = () => {
const { translate } = useTranslate();

return <button>{translate("my.translate.text")}</button>;
};
```

## changeLocale

If you need to change the locale at runtime, you can use the `changeLocale` method. It calls the `changeLocale` method from [`i18nProvider`](/docs/i18n/i18n-provider) under the hood.

```tsx
import { useSetLocale } from "@refinedev/core";

export const LanguageSwicher = () => {
const { changeLocale } = useTranslation();

return (
<div>
<span>Languages</span>
<button onClick={() => changeLanguage("en")}>English</button>
<button onClick={() => changeLanguage("es")}>Spanish</button>
</div>
);
};
```

## getLocale

If you need to know the current locale, you can use the `getLocale` method. It calls the `getLocale` method from [`i18nProvider`](/docs/i18n/i18n-provider) under the hood.

```tsx
import { useSetLocale } from "@refinedev/core";

export const LanguageSwicher = () => {
const { getLocale } = useTranslation();

return <h1>Current Locale: {getLocale()}</h1>;
};
```
Loading

0 comments on commit 2b5ac6f

Please sign in to comment.