@solid-hooks/i18n
v0.2.3
Published
i18n for solid-js
Downloads
4
Readme
@solid-hooks/i18n
I18n for solid.js
Install
npm i @solid-hooks/i18n
yarn add @solid-hooks/i18n
pnpm add @solid-hooks/i18n
Usage
Static Message
import { defineI18n, useStaticMessage } from '@solid-hooks/i18n'
import { For } from 'solid-js'
// use `as const` to make parameters typesafe
const en = { t: '2', deep: { data: 'Hello, {name}' }, plural: '{day}(0=zero|1=one)' } as const
const zh = { t: '1', deep: { data: '你好{name}' }, plural: '{day}日' } as const
export const { useI18n, I18nProvider } = defineI18n({
message: useStaticMessage({ 'en': en, 'zh-CN': zh }),
defaultLocale: 'en',
datetimeFormats: {
'en': {
short: { dateStyle: 'short' },
long: { dateStyle: 'long' },
custom: d => d.getTime().toString(),
},
'zh-CN': {
short: { dateStyle: 'short' },
long: { dateStyle: 'full' },
custom: d => d.getTime().toString(),
},
},
numberFormats: {
'en': {
currency: { style: 'currency', currency: 'USD' },
},
'zh-CN': {
currency: { style: 'currency', currency: 'CNY' },
},
},
})
// usage
const { t, scopeT, d, n, availiableLocales, locale, setLocale } = useI18n(/* optional typesafe scope */)
const scopeT = scopeT('deep')
return (
<I18nProvider>
<select onChange={e => setLocale(e.target.value)}>
<For each={availiableLocales}>
{l => <option selected={l === locale()}>{l}</option>}
</For>
</select>
<div>{t('t')}</div>
<br />
{/* typesafe parameters */}
<div>{t('t')}</div>
<div>{t('deep.data', { name: 'test' })}</div>
<div>{t('plural', { day: 1 })}</div>
<div>{scopeT('data', { name: 'test' })}</div>
<div>{d(new Date())}</div>
<div>{d(new Date(), 'long')}</div>
<div>{d(new Date(), 'long', 'en')}</div>
<div>{n(100, 'currency')}</div>
</I18nProvider>
)
Dynamic Message
Use import.meta.glob
to dynamically load message
import { defineI18n, useDynamicMessage } from '@solid-hooks/i18n'
import { MSG } from './type'
export const { useI18n, I18nProvider } = defineI18n({
message: useDynamicMessage(
import.meta.glob('./locales/*.yml') as MSG,
path => path.slice(10, -4)
),
// other options...
})
return (
<I18nProvider useSuspense={<div>loading...</div>}>
{/* ... */}
</I18nProvider>
)
Vite Plugin
To convert yml
or other formats of message, setup built-in vite plugin
From v0.2.1, you can get variable type check support by withTypeSupport
. It will generate compact types to output
file
vite.config.ts
import { I18nPlugin, withTypeSupport } from '@solid-hooks/i18n/vite'
import { defineConfig } from 'vite'
import { parse } from 'yaml'
export default defineConfig({
plugins: [
I18nPlugin({
include: './src/i18n/locales/*.yml',
transformMessage: withTypeSupport({
baseTranslationFilePath: './i18n/locales/en.yml',
transform: content => parse(content),
output: './i18n/type.ts',
}),
}),
],
})
Syntax
Variable
{variable}
e.g.
const en = { var: 'show {variable}' } as const
t('var', { variable: 'text' }) // show text
Plural
{variable}(case=text|case=text)
- case: support number (seprated by
,
) / range (seprated by-
) /*
(fallback cases) - text: plural text, use
@
to show matched variable
e.g.
const en = { plural: 'at {var}(1=one day|2-3,5=a few days|*=@ days) ago' } as const
t('plural', { var: 1 }) // at one day ago
t('plural', { var: 2 }) // at a few days ago
t('plural', { var: 4 }) // at 4 days ago
t('plural', { var: 5 }) // at a few days ago
I18n-Ally VSCode plugin
add in .vscode/i18n-ally-custom-framework.yml
# more config: https://github.com/lokalise/i18n-ally/wiki/Custom-Framework
languageIds:
- javascript
- typescript
- javascriptreact
- typescriptreact
usageMatchRegex:
- '[^\w\d]t\([''"`]({key})[''"`]'
monopoly: true
RTL
Credit to react-spectrum
import { getReadingDirection, isRTL } from '@solid-hooks/i18n'
console.log(isRTL('ae')) // true
console.log(getReadingDirection('Mend')) // 'rtl'
License
MIT