@shopify/react-i18n
Advanced tools
Comparing version 0.0.0-snapshot-20221101233331 to 0.0.0-snapshot-20221110172345
@@ -16,3 +16,4 @@ 'use strict'; | ||
const MISSING_TRANSLATION = Symbol('Missing translation'); | ||
const PLURALIZATION_KEY_NAME = 'count'; | ||
const CARDINAL_PLURALIZATION_KEY_NAME = 'count'; | ||
const ORDINAL_PLURALIZATION_KEY_NAME = 'ordinal'; | ||
const SEPARATOR = '.'; | ||
@@ -113,4 +114,4 @@ | ||
if (typeof result === 'object' && replacements != null && Object.prototype.hasOwnProperty.call(replacements, PLURALIZATION_KEY_NAME)) { | ||
const count = replacements[PLURALIZATION_KEY_NAME]; | ||
if (typeof result === 'object' && replacements != null && Object.prototype.hasOwnProperty.call(replacements, CARDINAL_PLURALIZATION_KEY_NAME)) { | ||
const count = replacements[CARDINAL_PLURALIZATION_KEY_NAME]; | ||
@@ -120,4 +121,14 @@ if (typeof count === 'number') { | ||
result = result[group] || result.other; | ||
additionalReplacements[PLURALIZATION_KEY_NAME] = memoizedNumberFormatter(locale).format(count); | ||
additionalReplacements[CARDINAL_PLURALIZATION_KEY_NAME] = memoizedNumberFormatter(locale).format(count); | ||
} | ||
} else if (typeof result === 'object' && replacements != null && Object.prototype.hasOwnProperty.call(replacements, ORDINAL_PLURALIZATION_KEY_NAME)) { | ||
const count = replacements[ORDINAL_PLURALIZATION_KEY_NAME]; | ||
if (typeof count === 'number') { | ||
const group = memoizedPluralRules(locale, { | ||
type: 'ordinal' | ||
}).select(count); | ||
result = result.ordinal[group] || result.ordinal['other']; | ||
additionalReplacements[ORDINAL_PLURALIZATION_KEY_NAME] = memoizedNumberFormatter(locale).format(count); | ||
} | ||
} | ||
@@ -193,4 +204,4 @@ | ||
function updateTreeWithReplacements(translationTree, locale, replacements) { | ||
if (Object.prototype.hasOwnProperty.call(replacements, PLURALIZATION_KEY_NAME)) { | ||
const count = replacements[PLURALIZATION_KEY_NAME]; | ||
if (Object.prototype.hasOwnProperty.call(replacements, CARDINAL_PLURALIZATION_KEY_NAME)) { | ||
const count = replacements[CARDINAL_PLURALIZATION_KEY_NAME]; | ||
@@ -202,6 +213,20 @@ if (typeof count === 'number') { | ||
return updateStringWithReplacements(translationTree[group], { ...replacements, | ||
PLURALIZATION_KEY_NAME: memoizedNumberFormatter(locale).format(count) | ||
CARDINAL_PLURALIZATION_KEY_NAME: memoizedNumberFormatter(locale).format(count) | ||
}); | ||
} | ||
} | ||
} else if (Object.prototype.hasOwnProperty.call(replacements, ORDINAL_PLURALIZATION_KEY_NAME)) { | ||
const count = replacements[ORDINAL_PLURALIZATION_KEY_NAME]; | ||
if (typeof count === 'number') { | ||
const group = memoizedPluralRules(locale, { | ||
type: 'ordinal' | ||
}).select(count); | ||
if (isString(translationTree[group])) { | ||
return updateStringWithReplacements(translationTree[group], { ...replacements, | ||
ORDINAL_PLURALIZATION_KEY_NAME: memoizedNumberFormatter(locale).format(count) | ||
}); | ||
} | ||
} | ||
} | ||
@@ -208,0 +233,0 @@ |
{ | ||
"name": "@shopify/react-i18n", | ||
"version": "0.0.0-snapshot-20221101233331", | ||
"version": "0.0.0-snapshot-20221110172345", | ||
"license": "MIT", | ||
@@ -49,3 +49,3 @@ "description": "i18n utilities for React handling translations, formatting, and more", | ||
"dependencies": { | ||
"@shopify/dates": "^2.0.1", | ||
"@shopify/dates": "0.0.0-snapshot-20221110172345", | ||
"@shopify/decorators": "^3.0.1", | ||
@@ -52,0 +52,0 @@ "@shopify/function-enhancers": "^3.0.1", |
@@ -135,4 +135,3 @@ # `@shopify/react-i18n` | ||
- if `form: 'explicit'` is given, then the result will be the same as for `short`, but will append the ISO 4217 code if it is not already present | ||
- if `form: 'auto'` is given, then `explicit` will be selected if the `currency` option does not match the `defaultCurrency`, otherwise `short` is selected. If either `currency` or `defaultCurrency` is not defined then `short` is selected. | ||
- if `form:` is not given, then `form: 'auto'` will be used by default. | ||
- if `form` is omitted, or if `form: 'auto'` is given, then `explicit` will be selected if the `currency` option does not match the `defaultCurrency`, otherwise `short` is selected. If either `currency` or `defaultCurrency` is not defined then `short` is selected. | ||
- `unformatCurrency()`: converts a localized currency string to a currency string parseable by JavaScript. Example: `€ 1,25 => 1.25` | ||
@@ -302,4 +301,8 @@ - `formatPercentage()`: formats a number as a percentage according to the locale. Convenience function that simply _auto-assigns_ the `as` option to `percent` and calls `formatNumber()`. | ||
`@shopify/react-i18n` handles pluralization similarly to [Rails’ default i18n utility](https://guides.rubyonrails.org/i18n.html#pluralization) ([with some minor differences](docs/react_i18n_schema.md#pluralization-1)). The key is to provide the plural-dependent value as a `count` variable. `react-i18n` then looks up the plural form using [`Intl.PluralRules`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/PluralRules) and, within the keypath you have specified for the translation, will look up a nested translation matching the plural form: | ||
`@shopify/react-i18n` handles pluralization similarly to [Rails’ default i18n utility](https://guides.rubyonrails.org/i18n.html#pluralization) ([with some minor differences](docs/react_i18n_schema.md#pluralization-1)). `react-i18n` then looks up the plural form using [`Intl.PluralRules`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/PluralRules) and, within the keypath you have specified for the translation, will look up a nested translation matching the plural form. | ||
###### Cardinal Pluralization | ||
Cardinal pluralization lookups use the value of the `count` replacement to choose the correct string: | ||
```ts | ||
@@ -319,5 +322,2 @@ // Assuming a dictionary like: | ||
As noted above, this functionality depends on the `Intl.PluralRules` global. If this does not exist [for your environment](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/PluralRules#Browser_compatibility), we recommend including the [`intl-pluralrules`](https://yarnpkg.com/en/package/intl-pluralrules) polyfill or included `import '@shopify/polyfills/intl';` from [`@shopify/polyfills`](https://github.com/Shopify/quilt/tree/main/packages/polyfills). | ||
We also recommend to have the `{count}` variable in all of your keys as some languages can use the key `"one"` when the count is `zero` for example. See MDN docs on [Localization and Plurals](https://developer.mozilla.org/en-US/docs/Mozilla/Localization/Localization_and_Plurals). | ||
By default, `{count}` will be automatically formatted as a number. If you want to format the variable differently, you can simply pass it in another variable. | ||
@@ -330,4 +330,4 @@ | ||
"searchResult": { | ||
"one": "{formattedCount} widget found", | ||
"other": "{formattedCount} widgets found" | ||
"one": "{unformattedCount} widget found", | ||
"other": "{unformattedCount} widgets found" | ||
} | ||
@@ -339,6 +339,57 @@ } | ||
count: searchResults, | ||
formattedCount: i18n.formatNumber(searchResults), | ||
unformattedCount: searchResults, | ||
}); | ||
``` | ||
We also recommend to have the `{count}` replacement in all of your keys as some languages can use the key `one` when the count is 0, for example. See MDN docs on [Localization and Plurals](https://developer.mozilla.org/en-US/docs/Mozilla/Localization/Localization_and_Plurals). | ||
###### Ordinal Pluralization | ||
Ordinal pluralization lookups rely on the keys being nested under an `ordinal` key (i.e., being in an [ordinal pluralization context](https://github.com/Shopify/quilt/blob/main/packages/react-i18n/docs/react_i18n_schema.md#ordinal-pluralization)), and use the value of the `ordinal` replacement to choose the correct string: | ||
```ts | ||
// Assuming a dictionary like: | ||
{ | ||
"MyComponent": { | ||
"searchResult": { | ||
"ordinal": { | ||
"one": "This is the {ordinal}st widget found", | ||
"two": "This is the {ordinal}nd widget found", | ||
"few": "This is the {ordinal}rd widget found", | ||
"other": "This is the {ordinal}th widget found", | ||
} | ||
} | ||
} | ||
} | ||
i18n.translate('MyComponent.searchResult', {ordinal: searchResultOrdinal}); | ||
``` | ||
By default, `{ordinal}` will be automatically formatted as a number. If you want to format the variable differently, you can simply pass it in another variable. | ||
```ts | ||
// Assuming a dictionary like: | ||
{ | ||
"MyComponent": { | ||
"searchResult": { | ||
"ordinal": { | ||
"one": "This is the {unformattedOrdinal}st widget found", | ||
"two": "This is the {unformattedOrdinal}nd widget found", | ||
"few": "This is the {unformattedOrdinal}rd widget found", | ||
"other": "This is the {unformattedOrdinal}th widget found", | ||
} | ||
} | ||
} | ||
} | ||
i18n.translate('MyComponent.searchResult', { | ||
ordinal: searchResultOrdinal, | ||
unformattedOrdinal: searchResultOrdinal, | ||
}); | ||
``` | ||
###### `Intl.PluralRules` | ||
As noted above, pluralization functionality depends on the `Intl.PluralRules` global. If this does not exist [for your environment](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/PluralRules#Browser_compatibility), we recommend including the [`intl-pluralrules`](https://yarnpkg.com/en/package/intl-pluralrules) polyfill or included `import '@shopify/polyfills/intl';` from [`@shopify/polyfills`](https://github.com/Shopify/quilt/tree/main/packages/polyfills). | ||
##### Translation tree | ||
@@ -345,0 +396,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
276404
4182
489
+ Added@shopify/dates@0.0.0-snapshot-20221110172345(transitive)
- Removed@shopify/dates@2.1.1(transitive)