├── .babelrc ├── .gitignore ├── .npmignore ├── .travis.yml ├── LICENSE ├── README.md ├── package.json ├── react-native-logo.jpg └── src ├── LocPresentationalRN.js ├── LocRN.js └── index.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["env", "react"], 3 | "plugins": ["transform-object-rest-spread"] 4 | } 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################################################ 2 | # Local Configuration 3 | ################################################ 4 | 5 | config/local.* 6 | 7 | ################################################ 8 | # Dependencies 9 | ################################################ 10 | 11 | node_modules 12 | bower_components 13 | 14 | ################################################ 15 | # Sails.js / Waterline / Grunt 16 | ################################################ 17 | 18 | .tmp 19 | dump.rdb 20 | 21 | ################################################ 22 | # Node.js / NPM 23 | ################################################ 24 | 25 | lib-cov 26 | *.seed 27 | *.log 28 | *.out 29 | *.pid 30 | npm-debug.log 31 | 32 | ################################################ 33 | # Miscellaneous 34 | ################################################ 35 | 36 | *~ 37 | *# 38 | .DS_STORE 39 | .netbeans 40 | nbproject 41 | .idea 42 | .node_history 43 | .npmrc 44 | lib 45 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .babelrc 2 | .editorconfig 3 | .eslintrc 4 | .gitignore 5 | .idea 6 | .npmignore 7 | .travis.yml 8 | 9 | node_modules/ 10 | 11 | gulpfile.js 12 | test.js 13 | ./index.html 14 | npm-debug.log -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "8" 4 | - "7" 5 | - "6" 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Dmitry Erzunov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # redux-react-native-i18n 2 | 3 | [![Build Status](https://travis-ci.org/derzunov/redux-react-native-i18n.svg?branch=master)](https://travis-ci.org/derzunov/redux-react-native-i18n) 4 | [![npm](https://img.shields.io/npm/dt/redux-react-native-i18n.svg)](https://www.npmjs.com/package/redux-react-native-i18n) 5 | [![npm](https://img.shields.io/npm/v/redux-react-native-i18n.svg)](https://www.npmjs.com/package/redux-react-native-i18n) 6 | [![Package Quality](http://npm.packagequality.com/shield/redux-react-native-i18n.svg)](http://packagequality.com/#?package=redux-react-native-i18n) 7 | 8 | [![Package Quality](http://npm.packagequality.com/badge/redux-react-native-i18n.png)](http://packagequality.com/#?package=redux-react-native-i18n) 9 | 10 | An **i18n** solution with **plural forms** support for **React Native** apps on Redux. 11 | 12 | This package provides functionality of [redux-react-i18n](https://github.com/derzunov/redux-react-i18n) to React Native. 13 | The difference between this package and [redux-react-i18n](https://github.com/derzunov/redux-react-i18n) is in presentational component and its container. `````` from this package uses ``` ``` from ```'react-native'``` instead of ``````. 14 | 15 | React Native Logo 16 | 17 | This package provides functionality of [redux-react-i18n](https://github.com/derzunov/redux-react-i18n) to React Native. 18 | 19 | The difference between this package and [redux-react-i18n](https://github.com/derzunov/redux-react-i18n) is in presentational component. It uses ``` ``` from 'react-native' instead of `````` 20 | 21 | ## Workers of all countries, unite! 22 | 23 | redux-react-i18n 24 | 25 | ### Supported languages list with expected codes for pluralize mechanics switching 26 | - Russian ( ru, ru-RU ) 27 | - English ( en, en-US, en-UK ) 28 | - French ( fr ) 29 | - German ( de ) 30 | - Polish ( pl ) 31 | - Czech ( cs ) 32 | - Portuguese ( pt ) 33 | - Brazilian Portuguese ( pt-BR, br ) 34 | - Arabic ( ar-AR, ar ) 35 | - Turkish ( tr ) 36 | - Occitan ( oc ) 37 | - Belarusian ( be ) 38 | - Bosnian ( bs ) 39 | - Croatian ( hr ) 40 | - Serbian ( sr ) 41 | - Ukrainian ( uk ) 42 | - ... 43 | 44 | ## Example Web Demo 45 | 46 | [derzunov.github.io/redux-react-i18n](https://derzunov.github.io/redux-react-i18n/) 47 | 48 | 49 | ## Short code demo 50 | 51 | #### Write ( jsx ): 52 | ```jsx 53 | 54 | 55 | 56 | 57 | ``` 58 | #### Result ( html ): 59 | ```html 60 | Перевод вашего первого ключа из словаря для текущего языка 61 | Пришла 1 кошечка 62 | Пришли 2 кошечки 63 | Пришло 5 кошечек 64 | ``` 65 | 66 | ### What am I using: 67 | redux-react-i18n: ( [github](https://github.com/derzunov/redux-react-i18n) or [npm](https://www.npmjs.com/package/redux-react-i18n) ) 68 | 69 | ## Install: 70 | ***You need react-native to be installed!*** 71 | 72 | Terminal: 73 | ``` 74 | npm i redux-react-native-i18n 75 | ``` 76 | 77 | ## What's in the box 78 | 79 | ### Components: 80 | - **Loc ( Container Component )** 81 | - LocPresentational ( Presentational Component ) 82 | 83 | ### Actions 84 | - setCurrent( languageCode ) 85 | - setLanguages( languageCode ) 86 | - addDictionary( languageCode, dictionary ) 87 | - setDictionaries( dictionaries ) 88 | 89 | ### Reducer 90 | - i18n 91 | 92 | 93 | ## Full code demo ( complete solution ): 94 | ```jsx 95 | import { i18nReducer, i18nActions, Loc } from 'redux-react-native-i18n' 96 | 97 | ... 98 | // "reducers" contains your reducers 99 | reducers.i18n = i18nReducer 100 | ... 101 | 102 | const store = createStore( combineReducers( reducers ) ) 103 | 104 | ... 105 | // Set dictionaries (simpliest exapmple) ----------------------------------------------------------------------------------------------- 106 | 107 | // This dictionaries can be supported by Localization team without need to know somth about interface or project, 108 | // and you just can fetch it to your project 109 | const dictionaries = { 110 | 'ru-RU': { 111 | 'key_1': 'Первый дефолтный ключ', 112 | 'key_2': [ '$Count', ' ', ['штучка','штучки','штучек']], // 1 штучка, 3 штучки, пять штучек 113 | 'key_3': { 114 | 'nested_1': 'Первый вложенный ключ', 115 | 'nested_2': 'Второй вложенный ключ', 116 | }, 117 | /* ... */ 118 | /* Other keys */ 119 | }, 120 | 'en-US': { 121 | 'key_1': 'First default key', 122 | 'key_2': [ '$Count', ' ', ['thing','things']], // 1 thing, 2 things, 153 things 123 | 'key_3': { 124 | 'nested_1': 'First nested key', 125 | 'nested_2': 'Second nested key', 126 | }, 127 | } 128 | /* ... */ 129 | /* Other dictionaries */ 130 | } 131 | store.dispatch( i18nActions.setDictionaries( dictionaries ) ) 132 | // / Set dictionaries (simpliest exapmple) --------------------------------------------------------------------------------------------- 133 | 134 | // Set languages (simpliest exapmple) -------------------------------------------------------------------------------------------------- 135 | const languages = [ 136 | { 137 | code: 'ru-RU', 138 | name: 'Русский' 139 | }, 140 | { 141 | code: 'en-US', 142 | name: 'English (USA)' 143 | } 144 | /* ... */ 145 | /* Other languages */ 146 | ] 147 | 148 | store.dispatch( i18nActions.setLanguages( languages ) ) 149 | // / Set languages (simpliest exapmple) ------------------------------------------------------------------------------------------------ 150 | 151 | // Set current language code (you can map this action to select component or somth like this) 152 | store.dispatch( i18nActions.setCurrentLanguage( 'ru-RU' ) ) 153 | ``` 154 | 155 | #### And now you can use "Loc" container component 156 | 157 | ```jsx 158 | import { Loc } from 'redux-react-native-i18n' 159 | ... 160 | 161 | 162 | // => Первый дефолтный ключ 163 | // => 7 штучек 164 | // => Первый вложенный ключ 165 | // => Второй вложенный ключ 166 | 167 | 168 | ``` 169 | 170 | ## If you don't want to use a complete solution: 171 | 172 | #### Just use a dumb component and you can design store/actions/reducers by yourself like you want 173 | 174 | ```jsx 175 | // Just import presentational component LocPresentational 176 | import { LocPresentational } from 'redux-react-native-i18n' 177 | ... 178 | ... 179 | ... 180 | // Then map data to props => currentLanguage, dictionary (See more in src/Loc.js): 181 | const mapStateToProps = ( { /*getting data from the state*/ }, ownProps ) => ({ 182 | currentLanguage: yourCurrentLanguageFromState, 183 | dictionary: yourDictionaryFromState 184 | }); 185 | Loc = connect( mapStateToProps )( LocPresentational ) 186 | ... 187 | ... 188 | ... 189 | 190 | 191 | 192 | ``` 193 | See more in src/\*.js 194 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "redux-react-native-i18n", 3 | "version": "1.2.0", 4 | "description": "An i18n solution with plural forms support for React Native apps on Redux", 5 | "main": "lib/index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\"", 8 | "compile": "babel src -d lib", 9 | "prepublish": "npm run compile", 10 | "build": "npm run compile" 11 | }, 12 | "devDependencies": { 13 | "babel-cli": "^6.26.0", 14 | "babel-core": "^6.26.0", 15 | "babel-plugin-transform-object-rest-spread": "^6.26.0", 16 | "babel-preset-env": "^1.6.1", 17 | "babel-preset-react": "^6.24.1" 18 | }, 19 | "repository": { 20 | "type": "git", 21 | "url": "git+https://github.com/derzunov/redux-react-native-i18n.git" 22 | }, 23 | "keywords": [ 24 | "redux", 25 | "i18n", 26 | "localization", 27 | "internationalization", 28 | "react", 29 | "l10n", 30 | "react native", 31 | "native" 32 | ], 33 | "author": "derzunov ", 34 | "license": "MIT", 35 | "bugs": { 36 | "url": "https://github.com/derzunov/redux-react-native-i18n/issues" 37 | }, 38 | "homepage": "https://github.com/derzunov/redux-react-native-i18n#readme", 39 | "dependencies": { 40 | "redux-react-i18n": "^1.3.0", 41 | "translatr": ">=2.1.0" 42 | }, 43 | "peerDependencies": { 44 | "react-dom": ">=16.0.0", 45 | "react-redux": ">=5.0.0", 46 | "redux": ">=3.0.0", 47 | "react": ">=16.0.0" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /react-native-logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derzunov/redux-react-native-i18n/aec8aef7e2a606cf189afacc77bd1ec90e085176/react-native-logo.jpg -------------------------------------------------------------------------------- /src/LocPresentationalRN.js: -------------------------------------------------------------------------------- 1 | import translate from 'translatr' 2 | import React from 'react' 3 | import { Text } from 'react-native' 4 | 5 | const Loc = ({ currentLanguage, locKey, number, dictionary, dispatch, ...rest }) => { 6 | return 7 | { translate( dictionary, currentLanguage, locKey, number ) } 8 | 9 | } 10 | 11 | export default Loc -------------------------------------------------------------------------------- /src/LocRN.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { connect } from 'react-redux' 3 | 4 | // Import presentational component 5 | import Loc from './LocPresentationalRN' 6 | 7 | // The component expects that reducer will be named as i18n 8 | const mapStateToProps = ( { i18n: { currentLanguage, dictionaries } }, ownProps ) => ({ 9 | currentLanguage, 10 | dictionary: dictionaries[ currentLanguage ] 11 | }) 12 | 13 | export default connect( mapStateToProps )( Loc ) 14 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import { i18nActions } from 'redux-react-i18n' 2 | export { i18nActions } 3 | 4 | import { i18nReducer } from 'redux-react-i18n' 5 | export { i18nReducer } 6 | 7 | // You can use the complete scheme of store/reducers/actions proposed by author 8 | export { default as Loc } from './LocRN' 9 | 10 | // Or you can just take a presentational container and map state to props by yourself 11 | export { default as LocPresentational } from './LocPresentationalRN' --------------------------------------------------------------------------------