[I18n] Add HOC injecting i18n provider (#23683) (#23804)

* add injectI18nProvider HOC

* Fix propTypes typo

* Typescriptify wrapper

* Add tests

* Fix tests

* Resolve comments
This commit is contained in:
Leanid Shutau 2018-10-04 13:43:00 +03:00 committed by GitHub
parent 6e6dd48409
commit 5bf648f039
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 231 additions and 0 deletions

View file

@ -0,0 +1,145 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`injectI18nProvider provides with context 1`] = `
Object {
"defaultFormats": Object {
"date": Object {
"full": Object {
"day": "numeric",
"month": "long",
"weekday": "long",
"year": "numeric",
},
"long": Object {
"day": "numeric",
"month": "long",
"year": "numeric",
},
"medium": Object {
"day": "numeric",
"month": "short",
"year": "numeric",
},
"short": Object {
"day": "numeric",
"month": "numeric",
"year": "2-digit",
},
},
"number": Object {
"currency": Object {
"style": "currency",
},
"percent": Object {
"style": "percent",
},
},
"time": Object {
"full": Object {
"hour": "numeric",
"minute": "numeric",
"second": "numeric",
"timeZoneName": "short",
},
"long": Object {
"hour": "numeric",
"minute": "numeric",
"second": "numeric",
"timeZoneName": "short",
},
"medium": Object {
"hour": "numeric",
"minute": "numeric",
"second": "numeric",
},
"short": Object {
"hour": "numeric",
"minute": "numeric",
},
},
},
"defaultLocale": "en",
"formatDate": [Function],
"formatHTMLMessage": [Function],
"formatMessage": [Function],
"formatNumber": [Function],
"formatPlural": [Function],
"formatRelative": [Function],
"formatTime": [Function],
"formats": Object {
"date": Object {
"full": Object {
"day": "numeric",
"month": "long",
"weekday": "long",
"year": "numeric",
},
"long": Object {
"day": "numeric",
"month": "long",
"year": "numeric",
},
"medium": Object {
"day": "numeric",
"month": "short",
"year": "numeric",
},
"short": Object {
"day": "numeric",
"month": "numeric",
"year": "2-digit",
},
},
"number": Object {
"currency": Object {
"style": "currency",
},
"percent": Object {
"style": "percent",
},
},
"time": Object {
"full": Object {
"hour": "numeric",
"minute": "numeric",
"second": "numeric",
"timeZoneName": "short",
},
"long": Object {
"hour": "numeric",
"minute": "numeric",
"second": "numeric",
"timeZoneName": "short",
},
"medium": Object {
"hour": "numeric",
"minute": "numeric",
"second": "numeric",
},
"short": Object {
"hour": "numeric",
"minute": "numeric",
},
},
},
"formatters": Object {
"getDateTimeFormat": [Function],
"getMessageFormat": [Function],
"getNumberFormat": [Function],
"getPluralFormat": [Function],
"getRelativeFormat": [Function],
},
"locale": "en",
"messages": Object {},
"now": [Function],
"onError": [Function],
"textComponent": "span",
"timeZone": null,
}
`;
exports[`injectI18nProvider renders children 1`] = `
<I18nProvider>
<ChildrenMock />
</I18nProvider>
`;

View file

@ -30,4 +30,5 @@ export {
} from 'react-intl';
export { I18nProvider } from './provider';
export { injectI18nProvider } from './inject_i18n_provider';
export { injectI18n } from './inject';

View file

@ -0,0 +1,47 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { mount, shallow } from 'enzyme';
import * as React from 'react';
import { intlShape } from 'react-intl';
import { injectI18n } from './inject';
import { injectI18nProvider } from './inject_i18n_provider';
describe('injectI18nProvider', () => {
test('renders children', () => {
const ChildrenMock = () => null;
const Injected = injectI18nProvider(ChildrenMock);
expect(shallow(<Injected />)).toMatchSnapshot();
});
test('provides with context', () => {
const ChildrenMock = () => <div />;
const WithIntl = injectI18n(ChildrenMock);
const Injected = injectI18nProvider(WithIntl);
const wrapper = mount(<Injected />, {
childContextTypes: {
intl: intlShape,
},
});
expect(wrapper.find(ChildrenMock).prop('intl')).toMatchSnapshot();
});
});

View file

@ -0,0 +1,38 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React from 'react';
import { I18nProvider } from './provider';
export function injectI18nProvider<P>(WrappedComponent: React.ComponentType<P>) {
const I18nProviderWrapper: React.SFC<P> = props => {
return (
<I18nProvider>
<WrappedComponent {...props} />
</I18nProvider>
);
};
// Original propTypes from the wrapped component should be re-exposed
// since it will be used by reactDirective Angular service
// that will rely on propTypes to watch attributes with these names
I18nProviderWrapper.propTypes = WrappedComponent.propTypes;
return I18nProviderWrapper;
}