@shopify/react-i18n
Advanced tools
Comparing version 1.0.0 to 1.1.0
@@ -11,2 +11,12 @@ # Changelog | ||
## [1.1.0] - 2019-04-09 | ||
### Added | ||
- Added a `useSimpleI18n` hook for performantly sharing an i18n instance within a React subtree ([#639](https://github.com/Shopify/quilt/pull/639)) | ||
### Fixed | ||
- Improved the typing of `withI18n` to no longer mark the `i18n` prop as required ([#639](https://github.com/Shopify/quilt/pull/639)) | ||
## [1.0.0] - 2019-04-08 | ||
@@ -18,3 +28,3 @@ | ||
- Added a `useI18n` decorator as the new first-class API ([#547](https://github.com/Shopify/quilt/pull/547)) | ||
- Added a `useI18n` hook as the new first-class API ([#547](https://github.com/Shopify/quilt/pull/547)) | ||
@@ -21,0 +31,0 @@ ### Changed |
import * as React from 'react'; | ||
import { I18nManager } from './manager'; | ||
import { I18n } from './i18n'; | ||
export declare const I18nContext: React.Context<I18nManager | null>; | ||
export declare const I18nParentsContext: React.Context<string[]>; | ||
export declare const I18nParentsContext: React.Context<I18n | null>; |
@@ -6,2 +6,2 @@ "use strict"; | ||
exports.I18nContext = React.createContext(null); | ||
exports.I18nParentsContext = React.createContext([]); | ||
exports.I18nParentsContext = React.createContext(null); |
@@ -7,2 +7,2 @@ import React from 'react'; | ||
} | ||
export declare function withI18n(i18nOptions?: RegisterOptions): <P extends WithI18nProps>(WrappedComponent: React.ComponentType<P>) => React.ComponentType<P>; | ||
export declare function withI18n(i18nOptions?: RegisterOptions): <OwnProps, C>(WrappedComponent: (React.ComponentClass<OwnProps & WithI18nProps, any> & C) | (React.FunctionComponent<OwnProps & WithI18nProps> & C)) => (React.ComponentClass<OwnProps, any> & C) | (React.FunctionComponent<OwnProps> & C); |
@@ -11,5 +11,4 @@ "use strict"; | ||
var _a = tslib_1.__read(hooks_1.useI18n(i18nOptions), 2), i18n = _a[0], ShareTranslations = _a[1]; | ||
var children = props.children; | ||
return (react_1.default.createElement(ShareTranslations, null, | ||
react_1.default.createElement(WrappedComponent, tslib_1.__assign({}, props, { i18n: i18n }), children))); | ||
react_1.default.createElement(WrappedComponent, tslib_1.__assign({}, props, { i18n: i18n })))); | ||
} | ||
@@ -16,0 +15,0 @@ return hoist_non_react_statics_1.default(WithTranslations, WrappedComponent); |
@@ -7,1 +7,2 @@ import * as React from 'react'; | ||
}>]; | ||
export declare function useSimpleI18n(): I18n; |
@@ -11,5 +11,6 @@ "use strict"; | ||
if (manager == null) { | ||
throw new Error('Missing manager'); | ||
throw new Error('Missing i18n manager. Make sure to use an <I18nContext.Provider /> somewhere in your React tree.'); | ||
} | ||
var parentIds = React.useContext(context_1.I18nParentsContext); | ||
var parentI18n = React.useContext(context_1.I18nParentsContext); | ||
var parentIds = parentI18n ? parentI18n.ids || [] : []; | ||
var ids = React.useMemo(function () { return (id ? tslib_1.__spread([id], parentIds) : parentIds); }, tslib_1.__spread([ | ||
@@ -23,3 +24,3 @@ id | ||
var translations = manager.state(ids).translations; | ||
return new i18n_1.I18n(translations, manager.details); | ||
return new i18n_1.I18n(translations, manager.details, ids); | ||
}), 2), i18n = _c[0], setI18n = _c[1]; | ||
@@ -29,3 +30,3 @@ React.useEffect(function () { | ||
var translations = _a.translations; | ||
setI18n(new i18n_1.I18n(translations, details)); | ||
setI18n(new i18n_1.I18n(translations, details, ids)); | ||
}); | ||
@@ -36,3 +37,3 @@ }, [manager]); | ||
var children = _a.children; | ||
return (React.createElement(context_1.I18nParentsContext.Provider, { value: ids }, children)); | ||
return (React.createElement(context_1.I18nParentsContext.Provider, { value: i18n }, children)); | ||
}; | ||
@@ -43,1 +44,10 @@ }, [i18n]); | ||
exports.useI18n = useI18n; | ||
function useSimpleI18n() { | ||
var manager = React.useContext(context_1.I18nContext); | ||
if (manager == null) { | ||
throw new Error('Missing i18n manager. Make sure to use an <I18nContext.Provider /> somewhere in your React tree.'); | ||
} | ||
var i18n = React.useContext(context_1.I18nParentsContext) || new i18n_1.I18n([], manager.details); | ||
return i18n; | ||
} | ||
exports.useSimpleI18n = useSimpleI18n; |
@@ -13,3 +13,4 @@ /// <reference types="react" /> | ||
export declare class I18n { | ||
translations: TranslationDictionary[]; | ||
readonly translations: TranslationDictionary[]; | ||
readonly ids?: string[] | undefined; | ||
readonly locale: string; | ||
@@ -30,3 +31,3 @@ readonly pseudolocalize: boolean | string; | ||
readonly isLtrLanguage: boolean; | ||
constructor(translations: TranslationDictionary[], { locale, currency, timezone, country, pseudolocalize, onError, }: I18nDetails); | ||
constructor(translations: TranslationDictionary[], { locale, currency, timezone, country, pseudolocalize, onError, }: I18nDetails, ids?: string[] | undefined); | ||
translate(id: string, options: TranslateOptions, replacements?: PrimitiveReplacementDictionary): string; | ||
@@ -33,0 +34,0 @@ translate(id: string, options: TranslateOptions, replacements?: ComplexReplacementDictionary): React.ReactElement<any>; |
@@ -24,6 +24,7 @@ "use strict"; | ||
var I18n = /** @class */ (function () { | ||
function I18n(translations, _a) { | ||
function I18n(translations, _a, ids) { | ||
var locale = _a.locale, currency = _a.currency, timezone = _a.timezone, country = _a.country, _b = _a.pseudolocalize, pseudolocalize = _b === void 0 ? false : _b, onError = _a.onError; | ||
var _this = this; | ||
this.translations = translations; | ||
this.ids = ids; | ||
this.getCurrencySymbol = function (currencyCode) { | ||
@@ -30,0 +31,0 @@ var currency = currencyCode || _this.defaultCurrency; |
export { I18nManager, ExtractedTranslations } from './manager'; | ||
export { I18nContext } from './context'; | ||
export { I18n } from './i18n'; | ||
export { useI18n } from './hooks'; | ||
export { useI18n, useSimpleI18n } from './hooks'; | ||
export { withI18n, WithI18nProps } from './decorator'; | ||
@@ -6,0 +6,0 @@ export { translate } from './utilities'; |
@@ -11,2 +11,3 @@ "use strict"; | ||
exports.useI18n = hooks_1.useI18n; | ||
exports.useSimpleI18n = hooks_1.useSimpleI18n; | ||
var decorator_1 = require("./decorator"); | ||
@@ -13,0 +14,0 @@ exports.withI18n = decorator_1.withI18n; |
{ | ||
"name": "@shopify/react-i18n", | ||
"version": "1.0.0", | ||
"version": "1.1.0", | ||
"license": "MIT", | ||
@@ -5,0 +5,0 @@ "description": "i18n utilities for React handling translations, formatting, and more.", |
@@ -105,3 +105,3 @@ # `@shopify/react-i18n` | ||
class NorFound extends React.Component<ComposedProps> { | ||
class NotFound extends React.Component<ComposedProps> { | ||
render() { | ||
@@ -124,2 +124,22 @@ const {i18n} = this.props; | ||
If you only need access to parent translations and/ or the various formatting utilities found on the `I18n` object, you can instead use the `useSimpleI18n` hook. This hook does not support providing any internationalization details for the component itself, but is a very performant way to access i18n utilities that are tied to the global locale. | ||
```tsx | ||
import * as React from 'react'; | ||
import {EmptyState} from '@shopify/polaris'; | ||
import {useSimpleI18n} from '@shopify/react-i18n'; | ||
export default function NotFound() { | ||
const i18n = useSimpleI18n(); | ||
return ( | ||
<EmptyState | ||
heading={i18n.translate('NotFound.heading')} | ||
action={{content: i18n.translate('Common.back'), url: '/'}} | ||
> | ||
<p>{i18n.translate('NotFound.content')}</p> | ||
</EmptyState> | ||
); | ||
} | ||
``` | ||
#### `i18n` | ||
@@ -126,0 +146,0 @@ |
90766
1858
395