Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-localize

Package Overview
Dependencies
Maintainers
3
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-localize - npm Package Compare versions

Comparing version 1.0.0 to 1.1.0

.babelrc

14

build/index.js

@@ -6,3 +6,3 @@ 'use strict';

});
exports.Text = undefined;
exports.LocalizationConnector = exports.LocalizationWrapper = exports.Text = undefined;

@@ -17,5 +17,15 @@ var _Localization = require('./Localization');

var _LocalizationWrapper = require('./LocalizationWrapper');
var _LocalizationWrapper2 = _interopRequireDefault(_LocalizationWrapper);
var _LocalizationConnector = require('./LocalizationConnector');
var _LocalizationConnector2 = _interopRequireDefault(_LocalizationConnector);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
exports.default = _Localization2.default;
exports.Text = _Text2.default;
exports.Text = _Text2.default;
exports.LocalizationWrapper = _LocalizationWrapper2.default;
exports.LocalizationConnector = _LocalizationConnector2.default;

49

build/Localization.js

@@ -7,6 +7,10 @@ 'use strict';

var _get = require('lodash/get');
var _localizeFormatter = require('./util/localize-formatter');
var _get2 = _interopRequireDefault(_get);
var _localizeFormatter2 = _interopRequireDefault(_localizeFormatter);
var _lodash = require('lodash.get');
var _lodash2 = _interopRequireDefault(_lodash);
var _react = require('react');

@@ -16,8 +20,5 @@

var _util = require('util');
var _util2 = _interopRequireDefault(_util);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var bool = _react.PropTypes.bool;
var func = _react.PropTypes.func;

@@ -32,3 +33,6 @@ var objectOf = _react.PropTypes.objectOf;

propTypes: {
messages: objectOf(string).isRequired
messages: objectOf(string).isRequired,
localize: func,
_localizeDebug: bool,
xLocale: bool
},

@@ -38,3 +42,6 @@

return {
messages: {}
messages: {},
localize: _localizeFormatter2.default,
_localizeDebug: false,
xLocale: false
};

@@ -45,3 +52,4 @@ },

childContextTypes: {
localize: func
localize: func,
_localizeDebug: bool
},

@@ -51,19 +59,19 @@

return {
localize: this.localize
localize: this.localize,
_localizeDebug: this.props.debug
};
},
localize: function localize(key) {
var messages = this.props.messages;
var values = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];
var _props = this.props;
var messages = _props.messages;
var xLocale = _props.xLocale;
var string = (0, _get2.default)(messages, key, key);
for (var _len = arguments.length, values = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
values[_key - 1] = arguments[_key];
if (xLocale) {
return 'XXXXXX';
}
if (values && string) {
string = _util2.default.format.apply(_util2.default, [string].concat(values));
}
return string;
var message = (0, _lodash2.default)(messages, key, null);
return this.props.localize(message, key, values);
},

@@ -75,2 +83,3 @@ render: function render() {

exports.default = Localization;
exports.default = Localization;
module.exports = exports['default'];

@@ -13,7 +13,6 @@ 'use strict';

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
var array = _react.PropTypes.array;
var bool = _react.PropTypes.bool;
var func = _react.PropTypes.func;

@@ -25,8 +24,8 @@ var string = _react.PropTypes.string;

var message = props.message;
var children = props.children;
var values = props.values;
var rest = _objectWithoutProperties(props, ['message', 'children', 'values']);
var rest = _objectWithoutProperties(props, ['message', 'values']);
var localize = context.localize;
var _localizeDebug = context._localizeDebug;

@@ -37,14 +36,14 @@

if (typeof localize === 'function') {
localized = localize.apply(undefined, [message].concat(_toConsumableArray(values)));
localized = localize(message, values);
}
if (typeof children === 'function') {
return children.apply(undefined, [localized, message].concat(_toConsumableArray(values)));
} else {
return _react2.default.createElement(
'span',
rest,
localized
);
if (_localizeDebug) {
rest['data-original-message'] = message;
}
return _react2.default.createElement(
'span',
rest,
localized
);
};

@@ -55,3 +54,2 @@

Text.propTypes = {
children: func,
message: string.isRequired,

@@ -66,5 +64,7 @@ values: array

Text.contextTypes = {
localize: func.isRequired
localize: func.isRequired,
_localizeDebug: bool
};
exports.default = Text;
exports.default = Text;
module.exports = exports['default'];

@@ -1,4 +0,6 @@

require('babel/register');
require('babel-register');
const build = require('./tools/build').build;
const test = require('./tools/test').test;
const watchTest = require('./tools/test').watchTest;
const githooks = require('./tools/githooks');

@@ -10,1 +12,3 @@ const gulp = require('gulp');

gulp.task('build', build);
gulp.task('test', test);
gulp.task('watchTest', watchTest);
{
"name": "react-localize",
"version": "1.0.0",
"version": "1.1.0",
"description": "A simple context wrapper and text localization component for localizing strings",
"main": "build/index.js",
"scripts": {
"build": "gulp build",
"githooks": "gulp githooks",
"precommit": "npm run test",
"test": "echo \"Error: no test specified\" && exit 0"
"prepublish": "in-publish && npm t && npm run build || not-in-publish",
"test": "gulp test"
},

@@ -26,20 +28,22 @@ "repository": {

"dependencies": {
"lodash": "4.8.1",
"react": "0.14.8"
"in-publish": "2.0.0",
"lodash.get": "^4.0.0",
"util": "0.10.3"
},
"peerDependencies": {
"react": "^0.14.6 || 15.x"
},
"devDependencies": {
"babel": "5.8.34",
"babel-preset-es2015": "6.6.0",
"babel-preset-react": "6.5.0",
"babel-preset-stage-0": "6.5.0",
"babelify": "6.3.0",
"browserify": "13.0.0",
"envify": "3.4.0",
"gulp": "git://github.com/gulpjs/gulp.git#aaed69d1fd73750227e803035b2a75d0f49e7de0",
"babel-preset-netflix-dea": "1.0.0-alpha.2",
"babel-register": "6.7.2",
"chai": "^3.5.0",
"gulp": "git://github.com/gulpjs/gulp.git#4ed9a4a3275559c73a396eff7e1fde3824951ebb",
"gulp-babel": "6.1.2",
"gulp-mocha": "^2.2.0",
"gulp-symlink": "2.1.4",
"lodash": "4.7.0",
"vinyl-source-stream": "1.1.0",
"watchify": "3.7.0"
"gulp-util": "^3.0.7",
"mocha": "^2.5.3",
"react": "^0.14.6 || 15.x",
"react-dom": "^0.14.6 || 15.x"
}
}
# react-localize
A simple context wrapper and text localization component for localizing strings.
## You know this part:
[![Travis build status](http://img.shields.io/travis/sprjr/react-localize.svg?style=flat)](https://travis-ci.org/sprjr/react-localize/)
## Getting Started, Quickly:
### Install it from [npm, Inc.](http://www.npmjs.org):
`npm i react-localize`
### Use it in your React App (with <Text /> helper):
## You can use it like this:
```
```js
import Localization, { Text } from 'react-localize';
<Localization messages={{
const localizationBundle = {
'app.button.Submit': 'Submit',

@@ -17,34 +20,116 @@ foo: {

}
}}>
<AnyParent>
};
<Localization messages={localizationBundle}>
<AnyParentComponent>
<Text message="prop.Val" style={{ color: 'blue' }} />
<Text message="app.button.Submit" data-magic="pretty neat" />
<Text message="foo.bar" values={['Foophen', 32]} style={{ color: 'red' }} />
</AnyParent>
</AnyParentComponent>
</Localization>
// outputs (respectively):
// <span style="color: blue">prop.Val</span>
// <span data-magic="pretty neat">Submit</span>
// <span style="color: red">Hey Foophen, you must be 32 old?</span>
```
## You can expect the above to output: (respectively)
### Use it in your React App (with context.localize() method):
```js
// app.js
<Localization messages={myBundle}>
<YourComponent />
</Localization>
// YourComponent.jsx
import TabsMaybe from 'react-bootstrap-tabs-i-guess';
export default YourComponent = (props, context) => {
const tabsConfig = props.tabsArray.map((tab) => {
return {
id: tab.id,
message: context.localize(tab.label)
onClick: () => props.onTabClick(tab.id)
};
});
return <TabsMaybe tabs={tabConfig} />
};
```
<span style="color: blue">prop.Val</span>
<span data-magic="pretty neat">Submit</span>
<span style="color: red">Hey Foophen, you must be 32 old?</span>
## More Info & Usage:
`<Localization />` exposes a `localize(key, values)` function that is passed through [ReactJS Context](https://facebook.github.io/react/docs/context.html) to all children in the render tree it wraps. It takes a `messages` property that should be formatted like `{ 'mykey.path.to.Value': 'Value' }` or `{ myKey: { path: { to: { Value: 'Value' } } } }`.
The `<Text />` component is just a wrapper intended to help you out when you don't need or want to wire your component up to `contextTypes` and process things yourself. All it's really doing it helping you call `localize(key, values)`. By default it returns a span with all the other props you pass this component. Because this renders a `<span>` it's not always useful, for example when localizing `<input placeholder='something' />`.
### LocalizationWrapper
If you need to do non-JSX localization and you just want the string back, you must wire your component up to context in order to pick up the formatter function. We provide an HOC wrapper to help with this, like so:
```js
import { LocalizationWrapper } from 'react-localize';
const MyComponent = React.createClass({
// stuff
render() {
return <input placeholder={this.context.localize('foo')} />;
}
});
export default LocalizationWrapper(MyComponent);
```
## Also you can defer rendering for custom output:
This is just a convenience HOC for delcaring `contextTypes` on your component, which you're welcome to do if you don't like this pattern.
### LocalizationConnector
There's also an HOC wrapper to quickly provide childContextTypes for a given component. Let's redo the first example above using this pattern:
```js
// app.js
import { LocalizationWrapper } from 'react-localize';
import MyApp from './app.js';
const localizationBundle = {
'app.button.Submit': 'Submit',
foo: {
bar: 'Hey %s, you must be %d old?'
}
};
export default LocalizationWrapper(MyApp, localizationBundle)
```
<Text message='some.key'>
{(localized, message, ...values) => {
// message & ...values are optional, and are really just whatever you sent in on props
return <input type="text" placholder={localized} />
}}
</Text>
This is just a convenience HOC for declaring `childContextTypes` for your app, the same way `<Localization><MyApp /></Localization>` does.
## Available Props
### xLocale
If you pass `<Localization xLocale={true} />` this short circuits `context.localize()` calls to always return `XXXXXX`. This can be useful for viewing your UI and identifying which parts of the application are not using localization.
### debug
Utilizing `<Localization debug={true} />` expands the `<Text />` helper to include an HTML attribute `data-original-message`, which will be set to the `message` prop given. This can be useful in areas like Chrome DevTools where you want to see what key an element is using to localize things without having to swap back to your code.
### localize
`context.localize(key, values)` simply tries to look `messageBundle[key]` up using `lodash/get`. It then calls `this.props.localize(message, key, values);` so that the string can be formatted, you can utilize the default formatter function we provide, or you can override this to suit your needs. If the key is not found on your bundle, by default you'll receive the key back.
The default `localize()` format function behaves similar to `printf` formatted strings. You can read more about how that works on [util.format](https://nodejs.org/api/util.html#util_util_format_format) as well. Here's some quick examples:
```js
util.format('Why hello, %s!', 'Foophen');
// 'Why hello, Foophen!'
util.format('There are %d things you have to do today', 5)
// There are 5 things you have to do today
```
(that's so you can use something other than span, or put localized text in attributes, mostly)
## Testing
React is in package.json's dev and peer dependencies because React is required for running the tests. You'll need to build before the tests will work as they're run against the built files. We're using Puny to test because tests for react-localize should be simple & fast.
## More Stuff
I think you might need to browserify `build/index.js` because of `util` dependency. I have the `dist/` folder but I'm not sure how I feel about all that or what it should do yet.
`¯\_(ツ)_/¯`
```sh
npm run build
npm t
```
import Localization from './Localization';
import { default as Text } from './Text';
import LocalizationWrapper from './LocalizationWrapper';
import LocalizationConnector from './LocalizationConnector';
export default Localization;
export { Text };
export { Text, LocalizationWrapper, LocalizationConnector };

@@ -1,9 +0,12 @@

import get from 'lodash/get';
import defaultLocalizer from './util/localize-formatter';
import get from 'lodash.get';
import React, { PropTypes } from 'react';
import util from 'util';
const { func, objectOf, string } = PropTypes;
const { bool, func, objectOf, string } = PropTypes;
const Localization = React.createClass({
propTypes: {
messages: objectOf(string).isRequired
messages: objectOf(string).isRequired,
localize: func,
_localizeDebug: bool,
xLocale: bool
},

@@ -13,3 +16,6 @@

return {
messages: {}
messages: {},
localize: defaultLocalizer,
_localizeDebug: false,
xLocale: false
};

@@ -19,3 +25,4 @@ },

childContextTypes: {
localize: func
localize: func,
_localizeDebug: bool
},

@@ -25,15 +32,16 @@

return {
localize: this.localize
localize: this.localize,
_localizeDebug: this.props.debug
};
},
localize(key, ...values) {
const { messages } = this.props;
let string = get(messages, key, key);
localize(key, values=[]) {
const { messages, xLocale } = this.props;
if (values && string) {
string = util.format(string, ...values);
if (xLocale) {
return 'XXXXXX';
}
return string;
const message = get(messages, key, null);
return this.props.localize(message, key, values);
},

@@ -40,0 +48,0 @@

@@ -8,3 +8,3 @@ /*

* <AnyParent>
* <Text key='localized.strings.HelloWord' style={{ color: 'blue' }} />
* <Text message='localized.strings.HelloWord' style={{ color: 'blue' }} />
* </AnyParent>

@@ -17,7 +17,7 @@ * </Localization>

import React, { PropTypes } from 'react';
const { array, func, string } = PropTypes;
const { array, bool, func, string } = PropTypes;
const Text = (props, context) => {
const { message, children, values, ...rest } = props;
const { localize } = context;
const { message, values, ...rest } = props;
const { localize, _localizeDebug } = context;

@@ -27,11 +27,10 @@ let localized = message;

if (typeof localize === 'function') {
localized = localize(message, ...values);
localized = localize(message, values);
}
// allow for optional alternative API using render-prop pattern
if (typeof children === 'function') {
return children(localized, message, ...values);
} else {
return (<span {...rest}>{localized}</span>);
if (_localizeDebug) {
rest['data-original-message'] = message;
}
return (<span {...rest}>{localized}</span>);
};

@@ -42,3 +41,2 @@

Text.propTypes = {
children: func,
message: string.isRequired,

@@ -53,5 +51,6 @@ values: array

Text.contextTypes = {
localize: func.isRequired
localize: func.isRequired,
_localizeDebug: bool
};
export default Text;
# Done is Better than Perfect™
(but we should do these, eventually)
## (but we should do these, eventually)
- Tests. (because then we'll know if we break something)
- better usage documentation
- Fix up lint / style and update githooks
- Add custom retrieval hook for `<Localization />` for folks who want to deviate from the current data model pattern.
- Improve built in `localize()` key lookup functionality

@@ -1,20 +0,7 @@

import assign from 'lodash/assign';
import babelify from 'babelify';
import browserify from 'browserify';
import envify from 'envify/custom';
import gulp from 'gulp';
import babel from 'gulp-babel';
import source from 'vinyl-source-stream';
import gulp from 'gulp';
//------------------------------------------------------------------------------
// Build Client Assets
// Build ES5 Assets
//------------------------------------------------------------------------------
export function dist() {
return browserify('./src/index.js')
.transform(babelify)
.bundle()
.pipe(source('index.js'))
.pipe(gulp.dest('dist'));
};
export function build() {

@@ -24,3 +11,3 @@ return gulp.src('./src/**/*.js*')

comments: false,
presets: ['es2015', 'react', 'stage-0'],
presets: ['netflix-dea'],
sourceMaps: true

@@ -27,0 +14,0 @@ }))

@@ -1,3 +0,2 @@

import gulp from 'gulp';
import symlink from 'gulp-symlink';
import gulp, { symlink } from 'gulp';

@@ -8,6 +7,7 @@ //------------------------------------------------------------------------------

function githooks() {
return gulp.src('./tools/pre-commit')
.pipe(symlink('.git/hooks/pre-commit', { force: true }));
return gulp.src('./tools/hooks/pre-commit')
//`(gulp|vinylFS).symlink` injests folders only
.pipe(symlink('.git/hooks', { overwrite : true }));
}
export default githooks;

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc