0.3.0 • Published 4 years ago

react-i18n-chain v0.3.0

Weekly downloads
1
License
MIT
Repository
github
Last release
4 years ago

English | 中文

Are you always copy and paste duplicate i18n code like t('home:submit') t('common:something:success'). It take working slowly, and you are very easy to make typo if you don't recheck words carefully.

I don't like that way, I prefer to write code as a chain like i18n.common.something.success with typescript checking. So, why not try this package?

Installation

# Npm
npm install react-i18n-chain

#Yarn
yarn add react-i18n-chain

Demo

Here is demo

Define locales

// ./src/i18n/locales/en.ts

const en = {
  button: {
    submit: 'Submit',
    cancel: 'Go back',
  },
  user: {
    profile: 'Tom',
  },
};

export default en;
export type Locale = typeof en;
// ./src/i18n/locales/zh.ts

import { Locale } from './en';

const zh: Locale = {
  button: {
    submit: '提交',
    cancel: '返回',
  },
  user: {
    profile: '原罪',
  },
};

export default zh;

Create i18n instance

// ./src/i18n/index.ts

import { createI18n } from 'react-i18n-chain';
import en from './locales/en';

const i18n = createI18n({
  defaultLocale: {
    key: 'en',
    values: en,
  },
});

export default i18n;

Use i18n with React-Hooks

// ./src/components/App.ts

import React, { FC } from 'react';
import { useI18n } from 'react-i18n-chain';
import i18n from '../i18n';

const App: FC = () => {
  // For re-render when i18n switch locale
  useI18n(i18n);

  return <button>{i18n.button.submit}</button>;
};

export default App;

Use i18n with React-Component

// ./src/components/App.ts

import React, { FC } from 'react';
import { I18nProvider } from 'react-i18n-chain';
import i18n from '../i18n';

const App: FC = () => {
  return <button>{i18n.button.submit}</button>;
};

// For re-render when i18n switch locale
export default I18nProvider(i18n)(App);

Import locales

First way, define immediately.

import { createI18n } from 'react-i18n-chain';
import zh from './locales/zh';

const i18n = createI18n({
  defaultLocale: { ... },
});

i18n._.define('zh', zh);

export default i18n;

Second way, async import. loader will be invoked when locales doesn't defined.

const i18n = createI18n({
  defaultLanguage: { ... },
  loader: (name) => import('./locales/' + name),
});

export default i18n;

Switch locale

i18n._.locale('zh');

String literal

Feel free to try i18n['button.submit'] and i18n.button.submit, they have the same effect. Unfortunately, you can't enjoy type checking by using chain['xx.yy.zz'].

Template with parameters

You are required to use array to define template when parameters exist.

const en = {
  property: ['{{property1}}template{{property2}}', { property1: value2, property2: value2 }],
};

The second element in array is an object that is default value of template.

const en = {
  user: {
    profile: [
      'My name is {{name}}, I born in {{country}}, I am {{age}} old now, my birthday is {{birthday}}',
      {
        country: undefined,
        name: 'Tom',
        age: (value: number = 20) => {
          if (value <= 1) {
            return `${value} year`;
          } else {
            return `${value} years`;
          }
        },
        birthday: (value: Date) => {
          return value.toString();
        },
      },
    ],
  },
};

////////////////////////////////////
// The above code equivalent to definition below: (automatically)
interface User {
  Profile {
    country: string | number;
    name?: string;
    birthday: Date;
    age?: number;
  }
}
/////////////////////////////////////

// Minium configuration
i18n.user.profile({
  age: 20,
  country: 'China',
});

// Append optional property `name`
i18n.user.profile({
  age: 30,
  country: 'Usa',
  name: 'Lucy',
});

The primary difference between method age and birthday is: age has default parameter (value: number = 20) => {...} but birthday doesn't have. It's optional to input value to property who has default parameter value on function.


Set undefined to property if you want to force input value when invoking method.

const en = {
  template: ['Hello, {{world}}', { world: undefined }]
};
0.3.0

4 years ago

0.1.0

4 years ago

0.0.15

4 years ago

0.0.16

4 years ago

0.0.17

4 years ago

0.0.13

4 years ago

0.0.12

4 years ago

0.0.11

4 years ago

0.0.10

4 years ago

0.0.9

4 years ago

0.0.8

4 years ago

0.0.7

4 years ago

0.0.6

4 years ago

0.0.5

4 years ago

0.0.4

4 years ago

0.0.3

4 years ago

0.0.2

4 years ago

0.0.1

4 years ago