Skip to content

Commit bca0436

Browse files
committed
[ex-9] i18n
1 parent 64d369c commit bca0436

File tree

6 files changed

+70
-9
lines changed

6 files changed

+70
-9
lines changed

src/App.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,39 @@
11
import React, { useState } from 'react'
2-
import { Row, Col, Normalize, Grid, Typography } from '@smooth-ui/core-sc'
2+
import {
3+
Button,
4+
Row,
5+
Col,
6+
Normalize,
7+
Grid,
8+
Typography,
9+
} from '@smooth-ui/core-sc'
310
import SearchInput from './components/SearchInput'
11+
import { useI18n, T } from './components/I18n'
412
import Catch from './components/Catch'
513
import Card from './components/Card'
614
import { MovieSearch } from './containers/MovieDb'
715

816
export default function App() {
917
const [query, setQuery] = useState('Lord of the Rings')
18+
// Récupération de la locale et de la fonction "setLocale" depuis le contexte
19+
const { setLocale, locale } = useI18n()
20+
// Si on est en français, on voudra passer en anglais et inversement
21+
const otherLocale = locale === 'fr' ? 'en' : 'fr'
1022

1123
return (
1224
<>
1325
{/* Le composant "Grid" centre dans la page, "py" signifie "padding-top" et "padding-bottom" */}
1426
<Grid>
1527
{/* Injection de normalize.css pour avoir un rendu consistant sur tous les navigateurs */}
1628
<Normalize />
29+
{/* Bouton permettant de changer de langue, "my" signifie "margin-top" et "margin-bottom" */}
30+
<Button my={1} onClick={() => setLocale(otherLocale)}>
31+
<T id={otherLocale} />
32+
</Button>
1733
{/* "Typography" est un composant avec des variantes de titres prêtes à l'emploi */}
18-
<Typography variant="display-1">Smooth Movie</Typography>
34+
<Typography variant="display-1">
35+
<T id="title" />
36+
</Typography>
1937
{/* Votre composant "SearchInput" */}
2038
<SearchInput
2139
value={query}

src/components/I18n.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import React, { createContext, useState, useContext, useMemo } from 'react'
2+
3+
const I18nContext = createContext()
4+
5+
export function I18nProvider({ translations, defaultLocale, children }) {
6+
// La locale est stockée dans le state afin de pouvoir être modifiée à la volée
7+
const [locale, setLocale] = useState(defaultLocale)
8+
return (
9+
<I18nContext.Provider value={{ translations, locale, setLocale }}>
10+
{children}
11+
</I18nContext.Provider>
12+
)
13+
}
14+
15+
export function useT(id) {
16+
// Récupérations des "translations" et de la "locale" depuis le contexte
17+
const { translations, locale } = useContext(I18nContext)
18+
// Tant que rien n'a changé, on utilisera la même traduction
19+
// si par la suite notre fonction fait des calculs, ce sera optimisé
20+
return useMemo(() => translations[locale][id], [locale, translations, id])
21+
}
22+
23+
export function T({ id }) {
24+
return useT(id)
25+
}
26+
27+
export function useI18n() {
28+
return useContext(I18nContext)
29+
}

src/components/SearchInput.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
import React from 'react'
22
import { Input } from '@smooth-ui/core-sc'
3+
import { useT } from './I18n'
34

45
export default function SearchInput(props) {
6+
const placeholder = useT('placeholder')
57
return (
6-
<Input
7-
placeholder="Type something..."
8-
width="100%"
9-
type="search"
10-
{...props}
11-
/>
8+
<Input placeholder={placeholder} width="100%" type="search" {...props} />
129
)
1310
}

src/index.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,16 @@ import ReactDOM from 'react-dom'
33
import './index.css'
44
import App from './App'
55
import Catch from './components/Catch'
6+
import { I18nProvider } from './components/I18n'
67
import * as serviceWorker from './serviceWorker'
8+
import en from './locales/en.json'
9+
import fr from './locales/fr.json'
710

811
ReactDOM.render(
912
<Catch>
10-
<App />
13+
<I18nProvider translations={{ en, fr }} defaultLocale="en">
14+
<App />
15+
</I18nProvider>
1116
</Catch>,
1217
document.getElementById('root'),
1318
)

src/locales/en.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"fr": "🇫🇷 French",
3+
"en": "🇬🇧 English",
4+
"title": "Smooth Movies",
5+
"placeholder": "Type something..."
6+
}

src/locales/fr.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"fr": "🇫🇷 Français",
3+
"en": "🇬🇧 Anglais",
4+
"title": "Smooth Films",
5+
"placeholder": "Tapez quelque chose..."
6+
}

0 commit comments

Comments
 (0)