@shopify/react-i18n
Advanced tools
Comparing version 0.0.4 to 0.1.0
@@ -13,11 +13,16 @@ /// <reference types="react" /> | ||
translations: TranslationDictionary[]; | ||
locale: string; | ||
defaultCurrency?: string; | ||
defaultTimezone?: string; | ||
readonly locale: string; | ||
readonly pseudolocalize: boolean | string; | ||
readonly defaultCurrency?: string; | ||
readonly defaultTimezone?: string; | ||
readonly language: string; | ||
readonly region: string | undefined; | ||
/** | ||
* @deprecated Use I18n#region instead. | ||
*/ | ||
readonly countryCode: string | undefined; | ||
readonly languageDirection: LanguageDirection; | ||
readonly isRtlLanguage: boolean; | ||
readonly isLtrLanguage: boolean; | ||
readonly countryCode: string | undefined; | ||
constructor(translations: TranslationDictionary[], { locale, currency, timezone }: I18nDetails); | ||
constructor(translations: TranslationDictionary[], { locale, currency, timezone, pseudolocalize }: I18nDetails); | ||
translate(id: string, options: TranslateOptions, replacements?: PrimitiveReplacementDictionary): string; | ||
@@ -24,0 +29,0 @@ translate(id: string, options: TranslateOptions, replacements?: ComplexReplacementDictionary): React.ReactElement<any>; |
@@ -23,2 +23,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var i18n_1 = require("@shopify/i18n"); | ||
var types_1 = require("./types"); | ||
@@ -53,11 +54,12 @@ var errors_1 = require("./errors"); | ||
function I18n(translations, _a) { | ||
var locale = _a.locale, currency = _a.currency, timezone = _a.timezone; | ||
var locale = _a.locale, currency = _a.currency, timezone = _a.timezone, _b = _a.pseudolocalize, pseudolocalize = _b === void 0 ? false : _b; | ||
this.translations = translations; | ||
this.locale = locale.toLowerCase(); | ||
this.locale = locale; | ||
this.defaultCurrency = currency; | ||
this.defaultTimezone = timezone; | ||
this.pseudolocalize = pseudolocalize; | ||
} | ||
Object.defineProperty(I18n.prototype, "language", { | ||
get: function () { | ||
return this.locale.split('-')[0]; | ||
return i18n_1.languageFromLocale(this.locale); | ||
}, | ||
@@ -67,2 +69,19 @@ enumerable: true, | ||
}); | ||
Object.defineProperty(I18n.prototype, "region", { | ||
get: function () { | ||
return i18n_1.regionFromLocale(this.locale); | ||
}, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
Object.defineProperty(I18n.prototype, "countryCode", { | ||
/** | ||
* @deprecated Use I18n#region instead. | ||
*/ | ||
get: function () { | ||
return i18n_1.regionFromLocale(this.locale); | ||
}, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
Object.defineProperty(I18n.prototype, "languageDirection", { | ||
@@ -91,19 +110,16 @@ get: function () { | ||
}); | ||
Object.defineProperty(I18n.prototype, "countryCode", { | ||
get: function () { | ||
return this.locale.split('-')[1]; | ||
}, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
I18n.prototype.translate = function (id, optionsOrReplacements, replacements) { | ||
var pseudolocalize = this.pseudolocalize; | ||
var normalizedOptions; | ||
if (optionsOrReplacements == null) { | ||
normalizedOptions = {}; | ||
normalizedOptions = { pseudotranslate: pseudolocalize }; | ||
} | ||
else if (isTranslateOptions(optionsOrReplacements)) { | ||
normalizedOptions = __assign({}, optionsOrReplacements, { replacements: replacements }); | ||
normalizedOptions = __assign({}, optionsOrReplacements, { replacements: replacements, pseudotranslate: pseudolocalize }); | ||
} | ||
else { | ||
normalizedOptions = { replacements: optionsOrReplacements }; | ||
normalizedOptions = { | ||
replacements: optionsOrReplacements, | ||
pseudotranslate: pseudolocalize, | ||
}; | ||
} | ||
@@ -110,0 +126,0 @@ return utilities_1.translate(id, normalizedOptions, this.translations, this.locale); |
@@ -10,2 +10,3 @@ /// <reference types="react" /> | ||
timezone?: string; | ||
pseudolocalize?: boolean; | ||
} | ||
@@ -12,0 +13,0 @@ export interface TranslationDictionary { |
import * as React from 'react'; | ||
import { PseudotranslateOptions } from '@shopify/i18n'; | ||
import { TranslationDictionary, ComplexReplacementDictionary, PrimitiveReplacementDictionary } from './types'; | ||
export interface TranslateOptions<Replacements extends PrimitiveReplacementDictionary | ComplexReplacementDictionary> { | ||
export declare const PSEUDOTRANSLATE_OPTIONS: PseudotranslateOptions; | ||
export interface TranslateOptions<Replacements extends PrimitiveReplacementDictionary | ComplexReplacementDictionary = {}> { | ||
scope?: string | string[]; | ||
replacements?: Replacements; | ||
pseudotranslate?: boolean | string; | ||
} | ||
@@ -7,0 +10,0 @@ export declare function translate(id: string, options: TranslateOptions<PrimitiveReplacementDictionary>, translations: TranslationDictionary | TranslationDictionary[], locale: string): string; |
"use strict"; | ||
var __assign = (this && this.__assign) || function () { | ||
__assign = Object.assign || function(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) | ||
t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
var __values = (this && this.__values) || function (o) { | ||
@@ -21,2 +32,3 @@ var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; | ||
var React = __importStar(require("react")); | ||
var i18n_1 = require("@shopify/i18n"); | ||
var errors_1 = require("./errors"); | ||
@@ -27,5 +39,11 @@ var REPLACE_REGEX = /{([^}]*)}/g; | ||
var SEPARATOR = '.'; | ||
exports.PSEUDOTRANSLATE_OPTIONS = { | ||
startDelimiter: '{', | ||
endDelimiter: '}', | ||
prepend: '[!!', | ||
append: '!!]', | ||
}; | ||
function translate(id, options, translations, locale) { | ||
var e_1, _a; | ||
var scope = options.scope, replacements = options.replacements; | ||
var scope = options.scope, replacements = options.replacements, pseudotranslate = options.pseudotranslate; | ||
var normalizedTranslations = Array.isArray(translations) | ||
@@ -38,3 +56,3 @@ ? translations | ||
var translationDictionary = normalizedTranslations_1_1.value; | ||
var result = translateWithDictionary(normalizedId, translationDictionary, locale, replacements); | ||
var result = translateWithDictionary(normalizedId, translationDictionary, locale, replacements, { pseudotranslate: pseudotranslate }); | ||
if (result !== MISSING_TRANSLATION) { | ||
@@ -55,8 +73,9 @@ return result; | ||
exports.translate = translate; | ||
function translateWithDictionary(id, translations, locale, replacements) { | ||
var e_2, _a; | ||
function translateWithDictionary(id, translations, locale, replacements, _a) { | ||
var _b = (_a === void 0 ? {} : _a).pseudotranslate, pseudotranslate = _b === void 0 ? false : _b; | ||
var e_2, _c; | ||
var result = translations; | ||
try { | ||
for (var _b = __values(id.split(SEPARATOR)), _c = _b.next(); !_c.done; _c = _b.next()) { | ||
var part = _c.value; | ||
for (var _d = __values(id.split(SEPARATOR)), _e = _d.next(); !_e.done; _e = _d.next()) { | ||
var part = _e.value; | ||
if (result == null || typeof result !== 'object') { | ||
@@ -71,3 +90,3 @@ return MISSING_TRANSLATION; | ||
try { | ||
if (_c && !_c.done && (_a = _b.return)) _a.call(_b); | ||
if (_e && !_e.done && (_c = _d.return)) _c.call(_d); | ||
} | ||
@@ -85,4 +104,7 @@ finally { if (e_2) throw e_2.error; } | ||
} | ||
if (typeof result === 'string') { | ||
return updateStringWithReplacements(result, replacements); | ||
var processedString = typeof result === 'string' && pseudotranslate | ||
? i18n_1.pseudotranslate(result, __assign({}, exports.PSEUDOTRANSLATE_OPTIONS, { toLocale: typeof pseudotranslate === 'boolean' ? undefined : pseudotranslate })) | ||
: result; | ||
if (typeof processedString === 'string') { | ||
return updateStringWithReplacements(processedString, replacements); | ||
} | ||
@@ -89,0 +111,0 @@ else { |
{ | ||
"name": "@shopify/react-i18n", | ||
"version": "0.0.4", | ||
"version": "0.1.0", | ||
"license": "MIT", | ||
@@ -31,7 +31,12 @@ "description": "i18n utilities for React handling translations, formatting, and more.", | ||
"dependencies": { | ||
"@shopify/i18n": "^0.1.0", | ||
"@types/hoist-non-react-statics": "^3.0.1", | ||
"hoist-non-react-statics": "^3.0.1", | ||
"prop-types": "^15.6.2", | ||
"react-tree-walker": "^4.3.0" | ||
}, | ||
"sideEffects": false | ||
"sideEffects": false, | ||
"peerDependencies": { | ||
"react": "^16.0.0" | ||
} | ||
} |
@@ -0,1 +1,2 @@ | ||
import {languageFromLocale, regionFromLocale} from '@shopify/i18n'; | ||
import { | ||
@@ -46,10 +47,22 @@ I18nDetails, | ||
export default class I18n { | ||
locale: string; | ||
defaultCurrency?: string; | ||
defaultTimezone?: string; | ||
readonly locale: string; | ||
readonly pseudolocalize: boolean | string; | ||
readonly defaultCurrency?: string; | ||
readonly defaultTimezone?: string; | ||
get language(): string { | ||
return this.locale.split('-')[0]; | ||
get language() { | ||
return languageFromLocale(this.locale); | ||
} | ||
get region() { | ||
return regionFromLocale(this.locale); | ||
} | ||
/** | ||
* @deprecated Use I18n#region instead. | ||
*/ | ||
get countryCode() { | ||
return regionFromLocale(this.locale); | ||
} | ||
get languageDirection() { | ||
@@ -69,13 +82,10 @@ return RTL_LANGUAGES.includes(this.language) | ||
get countryCode(): string | undefined { | ||
return this.locale.split('-')[1]; | ||
} | ||
constructor( | ||
public translations: TranslationDictionary[], | ||
{locale, currency, timezone}: I18nDetails, | ||
{locale, currency, timezone, pseudolocalize = false}: I18nDetails, | ||
) { | ||
this.locale = locale.toLowerCase(); | ||
this.locale = locale; | ||
this.defaultCurrency = currency; | ||
this.defaultTimezone = timezone; | ||
this.pseudolocalize = pseudolocalize; | ||
} | ||
@@ -108,2 +118,3 @@ | ||
): any { | ||
const {pseudolocalize} = this; | ||
let normalizedOptions: RootTranslateOptions< | ||
@@ -114,7 +125,14 @@ PrimitiveReplacementDictionary | ComplexReplacementDictionary | ||
if (optionsOrReplacements == null) { | ||
normalizedOptions = {}; | ||
normalizedOptions = {pseudotranslate: pseudolocalize}; | ||
} else if (isTranslateOptions(optionsOrReplacements)) { | ||
normalizedOptions = {...optionsOrReplacements, replacements}; | ||
normalizedOptions = { | ||
...optionsOrReplacements, | ||
replacements, | ||
pseudotranslate: pseudolocalize, | ||
}; | ||
} else { | ||
normalizedOptions = {replacements: optionsOrReplacements}; | ||
normalizedOptions = { | ||
replacements: optionsOrReplacements, | ||
pseudotranslate: pseudolocalize, | ||
}; | ||
} | ||
@@ -121,0 +139,0 @@ |
@@ -26,8 +26,2 @@ import './matchers'; | ||
}); | ||
it('is normalized', () => { | ||
const locale = 'fr-CA'; | ||
const i18n = new I18n(defaultTranslations, {locale}); | ||
expect(i18n).toHaveProperty('locale', locale.toLowerCase()); | ||
}); | ||
}); | ||
@@ -91,2 +85,17 @@ | ||
describe('#region', () => { | ||
it('is determined from the locale', () => { | ||
const locale = 'fr-ca'; | ||
const i18n = new I18n(defaultTranslations, {locale}); | ||
expect(i18n).toHaveProperty('region', 'CA'); | ||
}); | ||
it('is undefined when the locale does not have a country code', () => { | ||
const locale = 'fr'; | ||
const i18n = new I18n(defaultTranslations, {locale}); | ||
// eslint-disable-next-line no-undefined | ||
expect(i18n).toHaveProperty('region', undefined); | ||
}); | ||
}); | ||
describe('#countryCode', () => { | ||
@@ -96,3 +105,3 @@ it('is determined from the locale', () => { | ||
const i18n = new I18n(defaultTranslations, {locale}); | ||
expect(i18n).toHaveProperty('countryCode', 'ca'); | ||
expect(i18n).toHaveProperty('countryCode', 'CA'); | ||
}); | ||
@@ -131,3 +140,3 @@ | ||
describe('#translate()', () => { | ||
it('calls the translate() utility with translations, key, locale, scope, and replacements', () => { | ||
it('calls the translate() utility with translations, key, locale, scope, pseudotranslate, and replacements', () => { | ||
const mockResult = 'translated string'; | ||
@@ -144,3 +153,3 @@ const replacements = {name: 'Chris'}; | ||
'hello', | ||
{...scope, replacements}, | ||
{...scope, replacements, pseudotranslate: false}, | ||
defaultTranslations, | ||
@@ -162,3 +171,3 @@ i18n.locale, | ||
'hello', | ||
{replacements}, | ||
{replacements, pseudotranslate: false}, | ||
defaultTranslations, | ||
@@ -180,3 +189,3 @@ i18n.locale, | ||
'hello', | ||
{...scope}, | ||
{...scope, pseudotranslate: false}, | ||
defaultTranslations, | ||
@@ -197,3 +206,3 @@ i18n.locale, | ||
'hello', | ||
{}, | ||
{pseudotranslate: false}, | ||
defaultTranslations, | ||
@@ -203,2 +212,21 @@ i18n.locale, | ||
}); | ||
it('calls the translate utility with pseudotranslation', () => { | ||
const mockResult = 'translated string'; | ||
translate.mockReturnValue(mockResult); | ||
const i18n = new I18n(defaultTranslations, { | ||
...defaultDetails, | ||
pseudolocalize: true, | ||
}); | ||
const result = i18n.translate('hello'); | ||
expect(result).toBe(mockResult); | ||
expect(translate).toHaveBeenCalledWith( | ||
'hello', | ||
{pseudotranslate: true}, | ||
defaultTranslations, | ||
i18n.locale, | ||
); | ||
}); | ||
}); | ||
@@ -205,0 +233,0 @@ |
@@ -10,2 +10,3 @@ export enum LanguageDirection { | ||
timezone?: string; | ||
pseudolocalize?: boolean; | ||
} | ||
@@ -12,0 +13,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
122591
3012
6
+ Added@shopify/i18n@^0.1.0
+ Addedprop-types@^15.6.2
+ Added@shopify/i18n@0.1.12(transitive)
+ Addedtslib@1.14.1(transitive)