Git Product home page Git Product logo

react-localize-redux's People

Contributors

anigenero avatar bartekczyz avatar bobafatale avatar daenamkim avatar darksmile92 avatar fredericruaudel avatar marc-ed-raffalli avatar mikicaivosevic avatar ompel avatar pmilla1606 avatar ramyma avatar ryandrewjohnson avatar spadgeaki avatar thchia avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-localize-redux's Issues

Persist active language?

Hello Ryan, we have the react-localize-redux working in our project but currently we encounter an issue. If the user switch the language from English to French, he/she can view the French version of the website all the way util when they refresh the website.

Every time they refresh the website, the router will initialize the language again with the defaultLanguage (in our case it's English).
We saw that when action @@localize/SET_ACTIVE_LANGUAGE was called, the payload {languageCode:"fr"} was sent, but it's not in the redux store.

Is there a way to persist the chosen language? We have redux-persist set up already, if the languageCode is saved anywhere, we can pick it up again and use it as the defaultLanguage when next time we initialize the localication.

Allow inserting react elements as arguments to translate

It would be amazing if I could inject components into a string.

Let's suppose I have this translation

{
  "greeting": "<div>Welcome ${user}!</div>"
}

I'd like to be able to do this:

translate('greeting', { user: (
 <strong>Jon Doe</strong>
)});

The result would be:

<div>Welcome <strong>Jon Doe</strong>!</div>

This is just a simple sample which can actually already be accomplished. However, I'm interested in being able to attach click listeners to components and then inject them into the translation.

localize type definition is not consistent with the example

If I try the following example in TypeScript from Medium:

import { localize } from 'react-localize-redux';

const App = (props) => (
  ...
);

// if you use localize make sure to pass the name of the slice
// that localeReducer was attached to.
export default localize(App, 'locale');

I get the following typescript error:

error TS2345: Argument of type '(props: any) => Element' is not assignable to parameter of type 'ReactElement'.
Property 'type' is missing in type '(props: any) => Element'.

I think localize typescript definition is not matching with this example.

'Reselect' cannot be resolved

ERROR in ./~/react-localize-redux/lib/modules/locale.js
Module not found: Error: Can't resolve 'reselect' in '[...]/node_modules/react-localize-redux/lib/modules'

I have temporarily solved it by installing 'reselect' manually.

Nevertheless, thanks for this library.

Missing Localized key in Containers

Dear Ryan,

First of all congrats for the package, it is what I was looking for. After installation I made a trial with an example translation right in my store configuration and it worked pretty well:

configureStore.js

  const configureStore = () => {
  const persistedState = loadState();
  const store = createStore(
    rootReducer,
    persistedState);

  store.subscribe(throttle(() => {
    saveState({
    });
  }, 1000));

  store.dispatch(setLanguages(['en', 'es', 'fr'], 'en'))

  const locales = {
    "welcome": {
      "greeting": [
        "Hello ${ name }!",
        "Bonjour ${ name }!",
        "Hola ${ name }!"
      ]
    },
  }
  store.dispatch(addTranslation(locales))

  return store;

This was translating the words in my SignupContainer. However, once I want to modularize this and move store.dispatch(addTranslation(locales)) somewhere else... the error Missing Localize key appears. For example, I would like to translate each module text in the same module file like follows:

SignupContainer.js

import React, { Component } from 'react';
import { connect } from 'react-redux'
import { Link } from 'react-router-dom';
import { getTranslate, getActiveLanguage } from 'react-localize-redux'
import configureStore from '../../store/configureStore'
import { addTranslation } from 'react-localize-redux'

const store = configureStore()

const signup = {
  "welcome": {
    "greeting": [
      "Hello ${ name }!",
      "Bonjour ${ name }!",
      "Hola ${ name }!"
    ]
  },
  "info": {
    "greeting": [
      "Hello",
      "Bonjour",
      "Hola"
    ]
  }
}
store.dispatch(addTranslation(signup))


class SignupContainer extends Component {
  render(translate, currentLanguage) {
    return (
      <div>
        <h1>{ this.props.translate('welcome.greeting') }</h1>
        <p>This is a Signup Form</p>
        <li><Link to="/login">Go to Login Page</Link></li>
      </div>
    )
  }
}

const mapStateToProps = state => ({
  translate: getTranslate(state.locale),
  currentLanguage: getActiveLanguage(state.locale).code
})

export default connect(mapStateToProps)(SignupContainer);

However in this case I'm getting Missing localized key: welcome.greeting. I'm new to Redux so maybe it is not something related to your package but for me it looks like the same thing though...

Thanks in advance!

error handling for null active language.

In https://github.com/ryandrewjohnson/react-localize-redux/blob/master/src/Localize.js#L17 where state is mapped to props you are retrieving the active language and immediately accessing the code property.

I'm encountering a race condition in which the locale has not finished initializing before Localize.js maps it's state. This is because I'm loading about 30 translation files and doing some extra processing to support falling back to the closest matching locale. Therefore, the active language is undefined and the maptStateToProps throws an error Cannot read property 'code' of undefined.

Example:

// Parent component
class Main extends React.Component {
  componentWillMount() {
    this.props.loadLocalization() // this is a thunk
  }
  render() {
    return <Child/> // thunk above has not finished by the time this renders.
  }
}

// child component
class Child extends React.Component {

}
Child = localize(Child, 'locale')

Solution

I resolved this by connecting getActiveLangauge on the parent class and rendering a loading screen while the active language was null. However, I think the documentation/logging for this could be clearer.

One solution would be to simply provide some placeholder values in https://github.com/ryandrewjohnson/react-localize-redux/blob/master/src/Localize.js#L17 if the active language was null. This probably isn't the best solution because it encourages developers to be lazy.

The other option would be to intentionally throw an error with a message indicating that they probably didn't finish initializing the locale. Then add a small section to the documentation regarding these asynchronous situations.

[feature request] accept mulitple language JSON file

Right now we have to give one JSON file with multiple language strings as an array.
"title": [
"Hello from Info Page!",
"Bonjour de la Page d’accueil !",
"Hola desde la página de bienvenida!"
]

But as I have to share this file to multiple people for translations, I would be lot easier if I can create JSON file for different languages.
eg:
locale_en.json
"title": "Hello from Info Page!"

locale_fr.json
"title": "Bonjour de la Page d’accueil !"

locale_es.json
"title": "Hola desde la página de bienvenida!"

Unable to resolve module `react-dom/server` from `/...[path to your user folder]/...[project]/node_modules/react-localize-redux/lib/Translate.js

When using this library in a React Native app its not able to compile due to the fact that React-Dom is not available for a React Native App.

Commenting out these lines in:
lib/Translate.js

14 // var _server = require('react-dom/server');
15
16 // var _server2 = _interopRequireDefault(_server);
.
.
.
118 // var translation = _server2.default.renderToStaticMarkup(children);
119 // var defaultLanguage = locale.options.defaultLanguage || locale.languages[0].code;
120 // store.dispatch((0, _locale.addTranslationForLanguage)(_defineProperty({}, id, translation), defaultLanguage));

Allows you to compile and use it properly

getTranslation to return string Type

Hi,
getTranslation is define to return LocalizedElement type
returns (key | key[], data) => LocalizedElement | { [key: string]: LocalizedElement }

Is there a way to return string type only?
Thanks

How do I translate smth like list of services?

So, traditionally I would create an object smth like this

const obj = [
  {
    id: 1,
    title: 'Massage',
    description:
      'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut tincidunt non sem vel lacinia. Duis suscipit, nibh ut malesuada aliquet, velit est consectetur leo, quis consectetur ante mauris rutrum orci.',
  },
  {
    id: 2,
    title: 'Massage',
    description:
      'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut tincidunt non sem vel lacinia. Duis suscipit, nibh ut malesuada aliquet, velit est consectetur leo, quis consectetur ante mauris rutrum orci.',
  },
  {
    id: 3,
    title: 'Massage',
    description:
      'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut tincidunt non sem vel lacinia. Duis suscipit, nibh ut malesuada aliquet, velit est consectetur leo, quis consectetur ante mauris rutrum orci.',
  },
];

and then run my loop

const ServicesList = ({ className }) =>
  obj.map(({ title, description, id }) => (
    <div className={className} key={id}>
      <ContentHeader>{title}</ContentHeader>
      <Content>{description}</Content>
    </div>
  ));

Problem, however, with translations is that I have no idea how with default methods (without resorting to creating custom data) to pass multiple translations without manually adding them as props

<Services {...translate(['ServicesList.Massage.title ...... '])} />

The bigger the list, the more manual work I have to do, plus I have to keep in mind if I delete smth to remove it from here as well, which is far from ideal.

Is there any way to do smth like this

<Services {...translate(['ServicesList'])} />

And then run my .map function on the object to properly loop through translations, without restoring to custom data implementation?

Translate class import issue with TypeScript

import { Translate } from 'react-localize-redux';
Throws:
Module '".../node_modules/react-localize-redux/lib/index"' has no exported member 'Translate'.

import Translate from 'react-localize-redux';
Throws:
"export 'default' (imported as 'Translate') was not found in 'react-localize-redux'

import * as Translate from 'react-localize-redux';
Throws:
JSX element type 'Translate' does not have any construct or call signatures.

Modifying
export default class Translate extends ReactComponent<TranslateProps> {}
to
export class Translate extends ReactComponent<TranslateProps> {}
in index.ts.d fixes the issue for me, I can use the following syntax to import Translate without any errors:
import { Translate } from 'react-localize-redux';

wrap getTranslate with reselect

My component which mapstatetoprops getTranslate keep rerendering when ever there is action dispatch.
Could getTranslate wrapped with reselect?

I workaround it by wrapping it before mapping it myself.

'.code' is undefined

So, from time to time something breaks and my web app crashes cause of ".code' is undefined exception.
I noticed that redux at this point is not even launching the "@@localize/INITIALIZE" but still adds languages and launches the "@@localize/ADD_TRANSLATION_FOR_LANGUAGE"

I tried to put the locale into localstorage to maybe perhaps avoid the undefined '.code' which occurs at "es/locale.js" => var activeLanguageCode = activeLanguage.code; and read the stored locale with store.subscribe but it did not helped at all, '.code' error is still happening.

I just followed the documentation, so I'm not sure what is going on
This is how I'm dispatching it

store.dispatch(initialize([
    { name: 'English', code: 'en-US' },
    { name: 'German', code: 'de-DE' }
]))

store.dispatch(addTranslationForLanguage(settings.en_US, 'en-US'))
store.dispatch(addTranslationForLanguage(settings.de_DE, 'de-DE'))

akzqlhruticqsbq9couo6w
5_krby9qsfu2y6tj-yfaha
m1dmpg7gr7sbpygyvjqitq

How can I use translate in TypeScript project?

I am just wondering how can I use translate:getTranslation(state.locale) in TypeScript *.tsx component?
Looks like TypeScript definition of getTranslation requires at least 2 parameters:

export type Translate = (value: TranslateValue, data: TranslatePlaceholderData, options?: Options) => LocalizedElement|LocalizedElementMap;

So what is data: TranslatePlaceholderData for? I am just expecting to only call this.props.translate('foo') somewhere in my TSX markup.

Thanks in advance and sorry if my questions are too noob.

Problems in <= IE10

Hello!

I am facing one weird problem in IE10 and below. Here is log from console:

[object Error]{description: "Unable to g..." ...}

Unhandled promise rejection TypeError: Unable to get property 'translate' of undefined or null reference

I have no idea where to look for a solution. I am using:

....
"react": "^16.2.0",

"react-localize-redux": "^2.13.7",

"react-redux": "^5.0.6",

"react-router-redux": "^4.0.8",

"redux": "^3.7.2",

"redux-devise-axios": "0.0.4",

"redux-mock-store": "^1.3.0",

"redux-persist": "^4.10.2",

"redux-thunk": "^2.2.0"
....

Mispelling

@ryandrewjohnson one of our devs noticed a misspelling in one of the action types which is a fairly visible part of the app (all logger output would quote it). Are you happy if I open a PR with a fix or do you think it's something you need to support now?

Let me know your pref, I'm happy to contribute or to fork and PR if it's something you'd be likely to merge.

Cheers,
Adam

export type AddTranslationForLanguageAction = BaseAction<'@@localize/ADD_TRANSLATION_FOR_LANGUGE', AddTranslationForLanguagePayload>;

How to use redux-localize-redux with shared validation library

I am writing validation library for redux-form using redux-localize-redux.

The followings are snippets from my project.

loginform.js

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Field, reduxForm } from 'redux-form';
import compose from 'recompose/compose';
import { getTranslate, getActiveLanguage, addTranslation } from 'react-localize-redux';
import {
  Checkbox,
  RadioButtonGroup,
  SelectField,
  TextField,
  Toggle,
  DatePicker
} from 'redux-form-material-ui';
import IconButton from 'material-ui/IconButton';
import Input, { InputLabel, InputAdornment } from 'material-ui/Input';
import Visibility from 'material-ui-icons/Visibility';
import VisibilityOff from 'material-ui-icons/VisibilityOff';
import { withStyles } from 'material-ui/styles'
import { FormControl, FormHelperText } from 'material-ui/Form';
import MailOutline from 'material-ui-icons/MailOutline';

import NinesqTextField from './NinesqTextField';
import NinesqEmailField from './NinesqEmailField';
import NinesqPasswordField from './NinesqPasswordField';
import NineSqValidatorObj from './NineSqValidatorObj';

const styles = theme => ({
  flash_on: {
    display: 'block',
  },
  flash_off: {
    display: 'none',
  },
  fieldOutline: {
    fontWeight: 300,
    borderRadius: 2,
    border: '1px solid red',
    boxSizing: 'border-box',
  },
});

const messages = {
  "LocalLoginForm": {
    "email_placeholder": [
      "이메일 주소",
      "Email Address",
      "JP-Email Address",
      "ZH-Email Address",
      "FR-Email Address",
      "ES-Email Address"
    ],
    "email_label": [
      "이메일",
      "Email",
      "JP-Email",
      "ZH-Email",
      "FR-Email",
      "ES-Email"
    ],
    "password_label": [
      "패스워드",
      "Password",
      "JP-Password",
      "ZH-Password",
      "FR-Password",
      "ES-Password"
    ],
    "password_placeholder": [
      "패스워드",
      "Password",
      "JP-Password",
      "ZH-Password",
      "FR-Password",
      "ES-Password"
    ],
    "submit_label": [
      "로그인",
      "Log in",
      "JP-Log in",
      "ZH-Log in",
      "FR-Log in",
      "ES-Log in"
    ]
  }
};

export class LocalLoginForm extends Component {
  static propTypes = {
    classes: PropTypes.object.isRequired,
  }
  state = {
    showPassword: true,
    nsvalidator: new NineSqValidatorObj(this.props.dispatch, this.props.translate)
  }

  componentWillMount = () => {
    console.log("componentWillMount");
    this.props.dispatch(addTranslation(messages));
  }

  render() {
    const { handleSubmit, pristine, reset, submitting, translate, auth, classes } = this.props;

    return (
      <form onSubmit={handleSubmit}>
        <div className={classes.fieldOutline}>
          <Field name="myField"
            fullWidth
            validate={[this.state.nsvalidator.required]}
            component={NinesqEmailField}
            label={translate('LocalLoginForm.email_placeholder')}
            placeholder={translate('LocalLoginForm.email_placeholder')}
          />
        </div>
        <div className={classes.fieldOutline}>
          <Field name="mypassword"
            fullWidth
            validate={[this.state.nsvalidator.required]}
            component={NinesqPasswordField}
            placeholder={translate('LocalLoginForm.password_placeholder')}
            label={translate('LocalLoginForm.password_placeholder')}
          />
        </div>
        <div className={auth.error ? classes.flash_on: classes.flash_off}>{`error: ${auth.error}`}</div>

        <div><button type="submit">{translate('LocalLoginForm.submit_label')}</button></div>
      </form>
    )
  }
}

const mapStateToProps = (state, props) => ({
  auth: state.auth.auth,
  translate: getTranslate(state.locale),
  currentLanguage: getActiveLanguage(state.locale).code
});

const mapDispatchToProps = {

}

export default compose(reduxForm({form: 'localLogin'}), connect(mapStateToProps, mapDispatchToProps), withStyles(styles))(LocalLoginForm);

NineSqValidatorObj.js

import { getTranslate, getActiveLanguage, addTranslation } from 'react-localize-redux';

const messages = {
  "validate": {
    "required": [
      "필수항목",
      "Required",
      "JP-Required",
      "ZH-Required",
      "FR-Required",
      "ES-Required"
    ],
  }
};

class NineSqValidatorObj {
  constructor(dispatch, translate) {
    dispatch(addTranslation(messages));
    this.translate = translate;
    this.required = this.required.bind(this);
  }

  required(value){
    return (value ? undefined : this.translate('validate.required'));
  }

  maxLength(max) {
    return value => value && value.length > max ? `Must be ${max} characters or less` : undefined;
  }

  maxLengthEmail = this.maxLength(15);

  minLength(min) {
    return value =>
      value && value.length < min ? `Must be ${min} characters or more` : undefined;
  }

  minLength2 = this.minLength(2);

  number(value) {
    return value && isNaN(Number(value)) ? 'Must be a number' : undefined;
  }

  minValue(min) {
    return value => value && value < min ? `Must be at least ${min}` : undefined;
  }

  minValue18 = this.minValue(18);

  email(value) {
    return value && !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(value)
      ? 'Invalid email address'
      : undefined;
  }

  alphaNumeric(value) {
    return value && /[^a-zA-Z0-9 ]/i.test(value)
    ? 'Only alphanumeric characters'
    : undefined;
  }

  phoneNumber(value) {
    return value && !/^(0|[1-9][0-9]{9})$/i.test(value)
      ? 'Invalid phone number, must be 10 digits'
      : undefined;
  }
}

export default NineSqValidatorObj;

I could try to implement it as HOC, however I thought it's wired to have render() in validator functions. So simply use it as a class. The current symptom is it won't find validate.required key.

If anyone can suggest how to implement this way, could you let me know?

Localize component doesn't work with redux-immutable

Hi there, thanks for a great project, we are using this in our app.

The higher order component Localize does not work when using redux-immutable, this is because the mapStateToProps function expects to find the slice at state[slice], whereas when using the redux-immutable combineReducers it saves the state as a Map.

This can be worked around, for example in our app we have used the normal combineReducers so that our state itself is a normal object, but our slices are immutable Maps. However this is not ideal because it breaks some conventions across our code base. Also it could put people off when trying to implement what is otherwise a great translation solution.

I suggest that a check is made and if the state object is a Map then state.get(slice) is called, I have tested this in my app and it works fine.

Missing translations callback&fallback

If some translation is missing, I can not setup returned value. There is showMissingTranslationMsg and missingTranslationCallback, but i really want have some power to make my own output string.
As possible solution you could return missingTranslationCallback result value if callback exists (utils.js, line 9).
And fallback part. It will be really usefully, if translation for some language is missing then return (or try to find) it from default language.
What do you think?

Translations get cut off after 1 character.

Using the following I get a strange quirk...

Screen_Shot_2017_09_18_at_9_43_08_PM

interface HomePageState {
    translate: any;
}

type HomePageProps = HomePageState

class Home extends React.Component<HomePageProps, HomePageState> {   
    /// the below will only render "I"
    public render(): any {
        return <label>{ this.props.translate("home.slogan") }</label>;
   }
}

const addTranslateToProps = state => {
    console.log('state.locale', state.locale);
    // this will log out "translations: { home.slogan: "I'm the correct translation" }
    return {
        translate: getTranslate(state.locale)
    }
};

export default connect(
    addTranslateToProps
)(Home) as typeof Home;

To be clear:
The translations state seems to contain the correct translation / localization, but the translate function exposed via props, does not work as expected.

I do believe it might be a dependent lib (reselect??) thats causing the problem, but not too sure... if anyone has encountered this before, any advice would be appreciated. I'm happy to supply any other information thats needed.

Other info:
Stack is on top of dotnetcore, React + Redux + SSR (with webpack for bundling front end stuff)

Can't setActiveLanguage

I have the locale reducer set :

import { localeReducer as locale } from 'react-localize-redux';
combineReducers({ locale, otherReducers});

The languages initialized:

const languageToUse = 'en';
const languages = ['en', 'fr'];
store.dispatch(initialize(languages));
const json = require('../static/texts/global.locale.json');
store.dispatch(addTranslation(json));
store.dispatch(setActiveLanguage(languageToUse));

And the function mapped to the props:

import { getTranslate, getActiveLanguage, setActiveLanguage } from 'react-localize-redux';

function mapStateToProps(state) {
    return {
      restOfState: state.restOfState,
      translate: getTranslate(state.locale),
      currentLanguage: getActiveLanguage(state.locale).code,
      setActiveLanguage: setActiveLanguage,
    };
  }

  export default mapStateToProps;

However calling this.props.setActiveLanguage('fr') in a connected component does not change anything (logging this.props.currentLanguage ). Is this an issue or am I missing something?

TypeError: Object doesn't support property or method 'find'

Hello,

Looks like getActiveLanguage is expecting Array.find to exist. In IE11 this is causing an error. I created the app with create-react-app and have not ejected or customized anything. Here are some screenshots of the stacktrace and my code that sets up the store. Any ideas what I could do to fix this.. ? Thanks

react1 error

react2 error

The code that sets up the store:

import {applyMiddleware, createStore, combineReducers} from "redux";
import {localeReducer} from 'react-localize-redux';
import {createLogger} from "redux-logger";
import thunk from "redux-thunk"

const middleware = applyMiddleware(thunk, createLogger());

const reducers = combineReducers({
	locale: localeReducer
});

export default createStore(reducers, middleware);

webpack 4 e.search error

I recently migrated to web pack 4 and found this error:

[Error] TypeError: value.search is not a function. (In 'value.search(pattern)', 'value.search' is undefined)
	hasHtmlTags (utils.js:31)
	getLocalizedElement (utils.js:26)
	render (index.jsx:151)
	finishClassComponent (react-dom.development.js:7873)
	performUnitOfWork (react-dom.development.js:10224)
	workLoop (react-dom.development.js:10288)
	callCallback (react-dom.development.js:542)
	dispatchEvent
	invokeGuardedCallbackDev (react-dom.development.js:581)
	invokeGuardedCallback (react-dom.development.js:438)
	renderRoot (react-dom.development.js:10366)
	performWorkOnRoot (react-dom.development.js:11014)
	performWork (react-dom.development.js:10967)
	requestWork (react-dom.development.js:10878)
	scheduleWorkImpl (react-dom.development.js:10732)
	enqueueSetState (react-dom.development.js:6212)
	setState (react.development.js:237)
	onStateChange (connectAdvanced.js:215)
	onStateChange
	dispatch (createStore.js:178)
	(función anónima) (App.js:128)
	promiseReactionJob

This is the only library that presents this error its something bad or could be a web pack bug?

Translate Utility func

Hello there,

First of all, wonderful work here. After reviewing the docs I began implementing this into a project and everything has been very smooth! The Translate component is my mvp; prevents me from having to hook up simpler components to the store.

One issue I've run into is translating attributes on components.
Let's take the placeholder attribute on the input element for example.

import { Translate } from 'react-localize-redux';
...
render() {
  return (
    <input htmlSize="32" label="" name="email" type="email" placeholder={<Translate id="placeholder1" options={{renderInnerHtml: false}}>Email Address</Translate>}/>
  );
}

translations.json

{
"placeholder1": [
		null,
		"Adresse e-mail",
		"Dirección de correo electrónico"
	]
}

This will cause the input placeholder to read out as [object Object], as its not a string but an object.

Now I do understand that I can solve the issue in this particular example by wrapping the entire input markup in a Translate component and adding the markup to the translation data. But doing so can really muck up the translations, and and make performing updates quickly more time consuming than it should be. Perhaps more importantly, I think there's an opportunity here to improve support for React Components.

What I propose is exposing a utility function that will allow developers to translate a given string into the current active language. Something like this:

import { Translate, Translator } from 'react-localize-redux';
...
render() {
  return (
    <input htmlSize="32" label="" name="email" type="email" placeholder={Translator.translate("placeholder1", "Email Address")}/>
  );
}

where translate's signature could be something like:

translate(id, defaultValue, lang=currentActiveLang);

Having the ability to translate strings in this manner would allow them to be passed as props, thereby solving some of the other issues with React Component support by enabling more flexible patterns.

Thoughts? Is this even feasible?

Help me! support TypeScript definition

This library uses flow for typings so it's easy enough for me to test that flow types are working as expected during development.

I have also done my best to support TypeScript as well by including a type definition with this library, but supporting this has become problematic. Since I'm not using TS for development I feel I don't get the proper test coverage before releasing.

What I'm hoping is that someone who is currently using react-localize-redux in their TypeScript project would be willing to help out with keeping the TS type defs up to date.

Translate returning invalid value

After updating to the latest version and switching to <Translate> from localize(), the following error logs to the console and the app doesn't render at all:
Invariant Violation: Translate.render(): A valid React element (or null) must be returned.
It happens when using <Translate> with the id property, but if I supply it a render prop function, everything works well. The code is pretty simple:

const Introduction = () => {
  return (
    <section className={style.Introduction}>
      <article className={style.About}>
        <Translate id="introduction" />
      </article>
    </section>
  );
};

export default Introduction;

Moving to version 3.0

The next major release is in active development with the biggest update being the removal of the dependency on redux. By leveraging React's new Context API the library will now work without redux, while still providing the option to use redux for those users using it in their app.


Release plan:

release-candidate - READY!!!
✅ release v3.0.0


Todo for release:

✅ should work without redux by default
✅ should work with redux if store provided to LocalizeProvider
option to show default language on missing translation
✅ correct spelling for add language action #71
update documentation
✅ battle test new TypeScript definition #69
✅ update examples
document breaking changes
✅ provide migration guide


What's changed?

See official change log.

Scanning the whole react app to generate a file containing all keys found

I would like to use this package for my project, but there is a feature missing that I'd like to have with it though.

A way to generate a file, containing all keys to translate, by scanning the whole react project and looking wherever I use the translate function.

To give you some context:

I’d like to be able to give a default translation, that would be in English, directly in the code, scan it, generate a file, and use this file to build my own translation portal where the translators will have the list of keys to translate with their default value (the English version). Save the whole into a DB and use this to generate the languages.json file that would then be used in the react app for react-localize-redux.

Does that make sense ?

`getTranslate` not working well with PureComponent

Here is my code:

class MyComponent extend PureComponent {
    ...
}

function mapStateToProps(state) {
  return {
    _: getTranslate(state.locale),
  };
}

export default connect(mapStateToProps)(MyComponent));

MyComponent will re-render every time when getTranslate was called.

Translate function in action creator

Most of the time we use the translate function from components. A component gets the translate function as a property from connect.
My problem is that sometimes we must use the translate from an action creator. I wonder if is there better way to access the translate function in an action creator than pass it to each action creator call?
For example:

export function downloadConfig(config: ConfigState, translate: Translate) {
  return function(dispatch: Function): Promise<void> {
    return ConfigApi.downloadConfig(config).then(resp  => {
      fileDownload(JSON.stringify(<ConfigState> resp.data, null, 2), "config.json");
    }).catch( error => {
      dispatch(showErrorDialog(
        translate("modal.error.connecting") as string,
        error.message,
        ConfigApi.BASE_URL + JSON_URL));
    });
  };
}

TypeError with selector getActiveLanguage

I'm getting an error when using the selector getActiveLanguage: Uncaught TypeError: (0 , _reactLocalizeRedux.getActiveLanguage) is not a function.

Not sure but have you forgotten to export getActiveLanguage at index.js? It's only working after importing from lib/modules/locale or after adding following to index.js:

Object.defineProperty(exports, 'getActiveLanguage', {
  enumerable: true,
  get: function get() {
    return _locale.getActiveLanguage;
  }
});

Feature Request: initialize() with array of objects

Hi @ryandrewjohnson,

I'm opening this issue about the topic, which I started in #21.

The problem in current solution is that, you can only initialize locales with language codes.

import { initialize } from 'react-localize-redux';

const languages = ['en', 'fr', 'es'];
store.dispatch(initialize(languages));

And with this scenario, it is bit hard to get the current language name.

I had to implement my own util functions to display "English" in a <LocaleSwitcher /> component, which is simple dropdown with select tag.

Something like this:

const locales = [
  {
    code: 'en',
    name: 'English',
  },
  {
    code: 'fr',
    name: 'French',
  },
  {
    code: 'es',
    name: 'Spanish',
  },
];

// localeByCode('es') => { code: 'es', name: 'Spanish' }
// this util function is used then <LocaleSwticher /> component
// to display the current language name.
const localeByCode = (code, locales) => {
  const locale = locales.filter(l => l.code === code)[0];
  return locale ? locale : locales[0];
};

// => ['en', 'fr', 'es']
const localeCodes = locales.map(l => l.code);
store.dispatch(initialize(localeCodes));

What i'm proposing is, that to have an ability to pass an array of objects in initialize action creator.

And the API would look something like this:

import { initialize } from 'react-localize-redux';

const languages = [{
    code: 'en',
    name: 'English',
  },
  {
    code: 'fr',
    name: 'French',
  },
];

store.dispatch(initialize(languages));

Also, in this case, getLanguages() and getActiveLanguage() should return different values:

// getActiveLanguage() => { code: 'en', name: 'English', active: true } 
// Instead of: 
// getActiveLanguage() => { code: 'en', active: true }

// getLanguages() => 
[{ code: 'en', name: 'English', active: true }, { code: 'fr', name: 'French', active: false }]
// Instead of: 
// getLanguages() => [{ code: 'en', active: true }, { code: 'fr', active: false }]

Other actions should not be changed, as long as, they don't need to know about that name key.

localizing <Link> (react-router-dom)

Hi,

I'd like to provide links in the translation but they shouldn't reload the page.

Ways I have tried so far:

  1. "goto.homepage": "Go to <Link to='/home'>home page</Link>..."

Translates but it's not clickable.

  1. "goto.homepage": "Go to ${link}..."

Inside component:

<p>
  {translate('goto.homepage', {
    link: <Link to='/home'>home page</Link>
  })}
</p>

Returns [object Object]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.