mobx-i18n
v0.6.0
Published
Responsive Translation utility based on TypeScript & MobX
Downloads
92
Maintainers
Readme
MobX i18n
Responsive Translation utility based on TypeScript & MobX
Features
- [x] Type hinting of Text keys
- [x] Lambda Expression values
- [x] Space utility for CJK & other characters
- [x] Responsive re-rendering
- [x] Async loading of Language packages
- [x] support HTTP protocol for Server-side rendering
- [x] support BOM/DOM language API for Client-side rendering
- [x] Speech Synthesis API for Text-to-Speech (TTS)
Versions
| SemVer | branch | status | ES decorator | MobX |
| :-------: | :------: | :----------: | :----------: | :---------: |
| >=0.5.0
| main
| ✅developing | stage-3 | >=6.11
|
| <0.5.0
| master
| ❌deprecated | stage-2 | >=4 <6.11
|
Text internationalization (React/Next.js example)
Original from https://github.com/kaiyuanshe/kaiyuanshe.github.io
Installation
npm i mobx mobx-react mobx-i18n next-ssr-middleware
Configuration
tsconfig.json
{
"compilerOptions": {
"target": "ES6",
"useDefineForClassFields": true,
"experimentalDecorators": false
}
}
Translation
translation/zh-CN.ts
import { textJoin } from 'mobx-i18n';
export default {
open_source: '开源',
project: '项目',
love: ({ a, b }: Record<'a' | 'b', string>) => textJoin(a, '爱', b)
} as const;
translation/en-US.ts
import { textJoin } from 'mobx-i18n';
export default {
open_source: 'Open Source',
project: 'project',
love: ({ a, b }: Record<'a' | 'b', string>) => textJoin(a, 'love', b)
} as const;
Initialization
model/Translation.ts
export const i18n = new TranslationModel({
'zh-CN': zhCN,
'en-US': () => import('../translation/en-US')
});
export const LanguageName: Record<(typeof i18n)['currentLanguage'], string> = {
'zh-CN': '简体中文',
'en-US': 'English'
};
pages/index.tsx
import { textJoin } from 'mobx-i18n';
import { compose, translator } from 'next-ssr-middleware';
import { Component } from 'react';
import { i18n, LanguageName } from '../model/Translation';
export const getServerSideProps = compose(translator(i18n));
@observer
export default class HomePage extends Component {
render() {
const { currentLanguage, t } = i18n;
return (
<>
<select
value={currentLanguage}
onChange={({ currentTarget: { value } }) =>
i18n.changeLanguage(value as typeof currentLanguage)
}
>
{Object.entries(LanguageName).map(([code, name]) => (
<option key={code} value={code}>
{name}
</option>
))}
</select>
<p>
{t('love', {
a: '我',
b: textJoin(t('open_source'), t('project'))
})}
</p>
</>
);
}
}
Text to Speech (WebCell example)
pages/article.tsx
import { component, observer } from 'web-cell';
import { SpeechSynthesisModel, SpeechSynthesisState } from 'mobx-i18n';
@component({ tagName: 'article-page' })
@observer
export class ArticlePage extends HTMLElement {
storeTTS = new SpeechSynthesisModel();
toggleSpeaking = () => {
const { storeTTS } = this;
if (storeTTS.state !== SpeechSynthesisState.Clear)
return storeTTS.toggle();
const text = SpeechSynthesisModel.getReadableText(
this.querySelector('article')
);
storeTTS.speak(text);
};
render() {
const speaking = this.storeTTS.state === SpeechSynthesisState.Speaking;
return (
<>
<button
style={{ background: speaking ? 'red' : 'blue' }}
onClick={this.toggleSpeaking}
>
{speaking ? '🔇' : '📢'}
</button>
<article>
<h1>The Four Freedoms</h1>
<ol>
<li>Freedom of speech and expression</li>
<li>Freedom of worship</li>
<li>Freedom from want</li>
<li>Freedom from fear</li>
</ol>
</article>
</>
);
}
}
Inspired by
- https://github.com/infinum/react-mobx-translatable
- https://github.com/jverhoelen/react-mobx-i18n
- https://github.com/QuiiBz/next-international