import React, { Children, ReactElement, Component } from 'react'; import Polyglot from 'node-polyglot'; import { connect, MapStateToProps } from 'react-redux'; import defaultMessages from 'ra-language-english'; import defaultsDeep from 'lodash/defaultsDeep'; import { ReduxState } from '../types'; import { TranslationContextProps, TranslationContext, } from './TranslationContext'; interface MappedProps { locale: string; messages: object; } interface State { contextValues: TranslationContextProps; } interface Props { children: ReactElement; } interface ViewProps extends MappedProps, Props {} /** * Creates a translation context, available to its children * * Must be called within a Redux app. * * @example * const MyApp = () => ( * * * * * * ); */ class TranslationProviderView extends Component { constructor(props) { super(props); const { locale, messages } = props; const polyglot = new Polyglot({ locale, phrases: defaultsDeep({ '': '' }, messages, defaultMessages), }); this.state = { contextValues: { locale, translate: polyglot.t.bind(polyglot), }, }; } componentDidUpdate(prevProps) { if ( prevProps.locale !== this.props.locale || prevProps.messages !== this.props.messages ) { const { locale, messages } = this.props; const polyglot = new Polyglot({ locale, phrases: defaultsDeep({ '': '' }, messages, defaultMessages), }); this.setState({ contextValues: { locale, translate: polyglot.t.bind(polyglot), }, }); } } render() { const { children } = this.props; const { contextValues } = this.state; return ( {Children.only(children)} ); } } const mapStateToProps: MapStateToProps< MappedProps, any, ReduxState > = state => ({ locale: state.i18n.locale, messages: state.i18n.messages, }); const TranslationProvider = connect(mapStateToProps)(TranslationProviderView); export default TranslationProvider;