diff --git a/src/I18nextProvider.js b/src/I18nextProvider.js index 953376ff..049d32b0 100644 --- a/src/I18nextProvider.js +++ b/src/I18nextProvider.js @@ -5,6 +5,7 @@ class I18nextProvider extends Component { constructor(props, context) { super(props, context); this.i18n = props.i18n; + this.defaultNS = props.defaultNS; if (props.initialI18nStore) { this.i18n.services.resourceStore.data = props.initialI18nStore; this.i18n.options.isInitialSSR = true; // if set will be deleted on first render in translate hoc @@ -15,7 +16,10 @@ class I18nextProvider extends Component { } getChildContext() { - return { i18n: this.i18n }; + return { + i18n: this.i18n, + defaultNS: this.defaultNS + }; } componentWillReceiveProps(nextProps) { @@ -32,11 +36,17 @@ class I18nextProvider extends Component { I18nextProvider.propTypes = { i18n: PropTypes.object.isRequired, - children: PropTypes.element.isRequired + children: PropTypes.element.isRequired, + defaultNS: PropTypes.string }; I18nextProvider.childContextTypes = { - i18n: PropTypes.object.isRequired + i18n: PropTypes.object.isRequired, + defaultNS: PropTypes.string +}; + +I18nextProvider.defaultProps = { + defaultNS: undefined }; export default I18nextProvider; diff --git a/src/translate.js b/src/translate.js index 59bc5415..0bbb56ca 100644 --- a/src/translate.js +++ b/src/translate.js @@ -21,7 +21,7 @@ export default function translate(namespaceArg, options = {}) { this.namespaces = typeof namespaceArg === 'function' ? ( namespaceArg(props) ) : ( - namespaceArg || (this.i18n.options && this.i18n.options.defaultNS) + namespaceArg || context.defaultNS || (this.i18n.options && this.i18n.options.defaultNS) ); if (typeof this.namespaces === 'string') this.namespaces = [this.namespaces]; @@ -79,7 +79,8 @@ export default function translate(namespaceArg, options = {}) { Translate.WrappedComponent = WrappedComponent; Translate.contextTypes = { - i18n: PropTypes.object + i18n: PropTypes.object, + defaultNS: PropTypes.string }; Translate.displayName = `Translate(${getDisplayName(WrappedComponent)})`; diff --git a/test/i18nextProvider.spec.js b/test/i18nextProvider.spec.js index 49c4a229..b02ceb12 100644 --- a/test/i18nextProvider.spec.js +++ b/test/i18nextProvider.spec.js @@ -35,10 +35,29 @@ describe('I18nextProvider', () => { const render = wrapper.render(); expect(render).toBe(child); }); + it('should provide defaultNS', () => { + const i18n = { + options: {}, + services: { + resourceStore: { + data: {} + } + }, + changeLanguage: () => {} + }; + const wrapper = new I18nextProvider({ i18n, defaultNS: 'provided-namespace', initialI18nStore: {}, initialLanguage: 'en' }); + expect(wrapper.getChildContext().defaultNS).toBe('provided-namespace'); + expect(I18nextProvider.childContextTypes.defaultNS) + .toBe(PropTypes.string); + }); it('should have i18n proptype required', () => { expect(I18nextProvider.propTypes.i18n) .toBe(PropTypes.object.isRequired); }); + it('should have defaultNS proptype optional string', () => { + expect(I18nextProvider.propTypes.defaultNS) + .toBe(PropTypes.string); + }); it('should have children proptype required', () => { expect(I18nextProvider.propTypes.children) .toBe(PropTypes.element.isRequired); diff --git a/test/translate.spec.js b/test/translate.spec.js index 8c30d9d4..d9bd64e8 100644 --- a/test/translate.spec.js +++ b/test/translate.spec.js @@ -16,6 +16,7 @@ describe('translate', () => { const wrapped = wrap(Elem); expect(wrapped.WrappedComponent).toBe(Elem); expect(wrapped.contextTypes.i18n).toBe(PropTypes.object); + expect(wrapped.contextTypes.defaultNS).toBe(PropTypes.string); expect(wrapped.displayName).toBe('Translate(Elem)'); expect(wrapped.namespaces.length).toBe(2); expect(wrapped.namespaces[0]).toBe('ns1'); @@ -73,5 +74,51 @@ describe('translate', () => { expect(instance.i18n).toBe(i18n); }); - + it('reads defaultNS from context if not provided as an argument', () => { + const context = { + i18n: { + options: { + defaultNS: 'i18nDefaultNS' + } + }, + defaultNS: 'contextDefaultNS' + }; + const props = { initialI18nStore: {}, initialLanguage: 'en' }; + const Elem = React.createFactory('Elem'); + const wrapped = translate()(Elem); + const instance = new wrapped(props, context); + expect(instance.namespaces.length).toBe(1); + expect(instance.namespaces[0]).toBe('contextDefaultNS'); + }); + it('reads namespace from argument when provided', () => { + const context = { + i18n: { + options: { + defaultNS: 'i18nDefaultNS' + } + }, + defaultNS: 'contextDefaultNS' + }; + const props = { initialI18nStore: {}, initialLanguage: 'en' }; + const Elem = React.createFactory('Elem'); + const wrapped = translate('namespaceFromArgument')(Elem); + const instance = new wrapped(props, context); + expect(instance.namespaces.length).toBe(1); + expect(instance.namespaces[0]).toBe('namespaceFromArgument'); + }); + it('reads namespace from i18n default if neither argument nor context have a defaultNS', () => { + const context = { + i18n: { + options: { + defaultNS: 'i18nDefaultNS' + } + } + }; + const props = { initialI18nStore: {}, initialLanguage: 'en' }; + const Elem = React.createFactory('Elem'); + const wrapped = translate()(Elem); + const instance = new wrapped(props, context); + expect(instance.namespaces.length).toBe(1); + expect(instance.namespaces[0]).toBe('i18nDefaultNS'); + }); });