Skip to content

Instantly share code, notes, and snippets.

@Gerhut
Last active August 25, 2021 07:02
Show Gist options
  • Save Gerhut/07d4edfba836171710e15721df299293 to your computer and use it in GitHub Desktop.
Save Gerhut/07d4edfba836171710e15721df299293 to your computer and use it in GitHub Desktop.
Simple React I18n
import { useCallback } from 'react'
import { createGlobalState } from 'react-use'
/** @typedef {{ [language: string] : { [text: string]: string} }} Translations */
/**
* @param {Translations} translations
* @param {string} defaultLanguage
*/
export function createI18n(translations, defaultLanguage) {
const useI18nLanguage = createGlobalState(defaultLanguage)
function useI18n() {
const [language] = useI18nLanguage()
return useCallback(
function i18n(text) {
return translations?.[language]?.[text] ?? text
},
[language]
)
}
/**
* @param {object} props
* @param {string} props.children
*/
function I18n({ children }) {
const t = useI18n()
return t(children)
}
return { useI18nLanguage, useI18n, I18n }
}
import { createContext, createElement, useContext, useState, useCallback } from 'react'
/** @typedef {{ [language: string] : { [text: string]: string} }} Translations */
const I18nContext = createContext({
/** @type {string} */
language: '',
/** @param {string} language */
setLanguage(language) {},
/** @type {Translations} */
translations: {},
/** @param {string} text */
i18n(text) {
return text
}
})
/**
* @param {object} props
* @param {Translations} props.translations
* @param {string} props.defaultLanguage
* @param {import('react').ReactNode} props.children
*/
export function I18nProvier({ translations, defaultLanguage, children }) {
const [language, setLanguage] = useState(defaultLanguage)
const i18n = useCallback(
/** @param {string} text */
function (text) {
return translations?.[language]?.[text] ?? text
},
[translations, language]
)
return createElement(I18nContext.Provider, { value: { language, setLanguage, translations, i18n } }, children)
}
/**
* @param {object} props
* @param {string} props.children
*/
export function I18n({ children }) {
const { i18n } = useContext(I18nContext)
return i18n(children)
}
export function useI18n() {
const { i18n } = useContext(I18nContext)
return i18n
}
/**
* @returns {[string, (language: string) => void]}
*/
export function useI18nLanguage() {
const { language, setLanguage } = useContext(I18nContext)
return [language, setLanguage]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment