@vocab/react
Advanced tools
Comparing version 1.1.0 to 1.1.1
# @vocab/react | ||
## 1.1.1 | ||
### Patch Changes | ||
- [`e9c7067`](https://github.com/seek-oss/vocab/commit/e9c7067b31215a176e70ac1e73f2c878107f328f) [#83](https://github.com/seek-oss/vocab/pull/83) Thanks [@michaeltaranto](https://github.com/michaeltaranto)! - Add React 18 support | ||
## 1.1.0 | ||
@@ -4,0 +10,0 @@ |
import { TranslationFile, LanguageName, ParsedFormatFnByKey, ParsedFormatFn } from '@vocab/types'; | ||
import { FunctionComponent, ReactNode } from 'react'; | ||
import { ReactNode } from 'react'; | ||
declare type Locale = string; | ||
@@ -8,3 +8,6 @@ interface TranslationsValue { | ||
} | ||
export declare const VocabProvider: FunctionComponent<TranslationsValue>; | ||
interface VocabProviderProps extends TranslationsValue { | ||
children: ReactNode; | ||
} | ||
export declare const VocabProvider: ({ children, language, locale, }: VocabProviderProps) => JSX.Element; | ||
export declare const useLanguage: () => TranslationsValue; | ||
@@ -11,0 +14,0 @@ declare type FormatXMLElementReactNodeFn = (parts: ReactNode[]) => ReactNode; |
@@ -75,3 +75,3 @@ 'use strict'; | ||
if (typeof item === 'object' && item && !item.key && /*#__PURE__*/React.isValidElement(item)) { | ||
result[i] = /*#__PURE__*/React.cloneElement(result[i], { | ||
result[i] = /*#__PURE__*/React.cloneElement(item, { | ||
key: `_vocab-${i}` | ||
@@ -78,0 +78,0 @@ }); |
@@ -75,3 +75,3 @@ 'use strict'; | ||
if (typeof item === 'object' && item && !item.key && /*#__PURE__*/React.isValidElement(item)) { | ||
result[i] = /*#__PURE__*/React.cloneElement(result[i], { | ||
result[i] = /*#__PURE__*/React.cloneElement(item, { | ||
key: `_vocab-${i}` | ||
@@ -78,0 +78,0 @@ }); |
@@ -67,3 +67,3 @@ import React, { useMemo, useContext, useReducer, isValidElement, cloneElement } from 'react'; | ||
if (typeof item === 'object' && item && !item.key && /*#__PURE__*/isValidElement(item)) { | ||
result[i] = /*#__PURE__*/cloneElement(result[i], { | ||
result[i] = /*#__PURE__*/cloneElement(item, { | ||
key: `_vocab-${i}` | ||
@@ -70,0 +70,0 @@ }); |
{ | ||
"name": "@vocab/react", | ||
"version": "1.1.0", | ||
"version": "1.1.1", | ||
"main": "dist/vocab-react.cjs.js", | ||
@@ -16,5 +16,5 @@ "module": "dist/vocab-react.esm.js", | ||
"devDependencies": { | ||
"@types/react": "^17.0.0", | ||
"react": "^17.0.1" | ||
"@types/react": "^18.0.9", | ||
"react": "^18.1.0" | ||
} | ||
} |
149
README.md
@@ -187,2 +187,10 @@ # Vocab | ||
```js | ||
function capitalize(element) { | ||
return element.toUpperCase(); | ||
} | ||
function pad(message) { | ||
return '[' + message + ']'; | ||
} | ||
module.exports = { | ||
@@ -197,6 +205,20 @@ devLanguage: 'en', | ||
/** | ||
* An array of languages to generate based off translations for existing languages | ||
* Default: [] | ||
*/ | ||
generatedLanguages: [ | ||
{ | ||
name: 'generatedLangauge', | ||
extends: 'en', | ||
generator: { | ||
transformElement: capitalize, | ||
transformMessage: pad | ||
} | ||
} | ||
], | ||
/** | ||
* The root directory to compile and validate translations | ||
* Default: Current working directory | ||
*/ | ||
projectRoot: './example/'; | ||
projectRoot: './example/', | ||
/** | ||
@@ -214,2 +236,127 @@ * A custom suffix to name vocab translation directories | ||
## Generated languages | ||
Vocab supports the creation of generated languages via the `generatedLanguages` config. | ||
Generated languages are created by running a message `generator` over every translation message in an existing translation. | ||
A `generator` may contain a `transformElement` function, a `transformMessage` function, or both. | ||
Both of these functions accept a single string parameter and return a string. | ||
`transformElement` is applied to string literal values contained within `MessageFormatElement`s. | ||
A `MessageFormatElement` is an object representing a node in the AST of a compiled translation message. | ||
Simply put, any text that would end up being translated by a translator, i.e. anything that is not part of the [ICU Message syntax], will be passed to `transformElement`. | ||
An example of a use case for this function would be adding [diacritics] to every letter in order to stress your UI from a vertical line-height perspective. | ||
`transformMessage` receives the entire translation message _after_ `transformElement` has been applied to its individual elements. | ||
An example of a use case for this function would be adding padding text to the start/end of your messages in order to easily identify which text in your app has not been extracted into a `translations.json` file. | ||
By default, a generated language's messages will be based off the `devLanguage`'s messages, but this can be overridden by providing an `extends` value that references another language. | ||
**vocab.config.js** | ||
```js | ||
function capitalize(message) { | ||
return message.toUpperCase(); | ||
} | ||
function pad(message) { | ||
return '[' + message + ']'; | ||
} | ||
module.exports = { | ||
devLanguage: 'en', | ||
languages: [{ name: 'en' }, { name: 'fr' }], | ||
generatedLanguages: [ | ||
{ | ||
name: 'generatedLanguage', | ||
extends: 'en', | ||
generator: { | ||
transformElement: capitalize, | ||
transformMessage: pad | ||
} | ||
} | ||
] | ||
}; | ||
``` | ||
Generated languages are consumed the same way as regular languages. | ||
Any Vocab API that accepts a `language` parameter will work with a generated language as well as a regular language. | ||
**App.tsx** | ||
```tsx | ||
const App = () => ( | ||
<VocabProvider language="generatedLanguage"> | ||
... | ||
</VocabProvider> | ||
); | ||
``` | ||
[icu message syntax]: https://formatjs.io/docs/intl-messageformat/#message-syntax | ||
[diacritics]: https://en.wikipedia.org/wiki/Diacritic | ||
## Pseudo-localization | ||
The `@vocab/pseudo-localize` package exports low-level functions that can be used for pseudo-localization of translation messages. | ||
```ts | ||
import { | ||
extendVowels, | ||
padString, | ||
pseudoLocalize, | ||
substituteCharacters | ||
} from '@vocab/pseudo-localize'; | ||
const message = 'Hello'; | ||
// [Hello] | ||
const paddedMessage = padString(message); | ||
// Ḩẽƚƚö | ||
const substitutedMessage = substituteCharacters(message); | ||
// Heelloo | ||
const extendedMessage = extendVowels(message); | ||
// Extend the message and then substitute characters | ||
// Ḩẽẽƚƚöö | ||
const pseudoLocalizedMessage = pseudoLocalize(message); | ||
``` | ||
Pseudo-localization is a transformation that can be applied to a translation message. | ||
Vocab's implementation of this transformation contains the following elements: | ||
- _Start and end markers (`padString`):_ All strings are encapsulated in `[` and `]`. If a developer doesn’t see these characters they know the string has been clipped by an inflexible UI element. | ||
- _Transformation of ASCII characters to extended character equivalents (`substituteCharacters`):_ Stresses the UI from a vertical line-height perspective, tests font and encoding support, and weeds out strings that haven’t been externalized correctly (they will not have the pseudo-localization applied to them). | ||
- _Padding text (`extendVowels`):_ Simulates translation-induced expansion. Vocab's implementation of this involves repeating vowels (and `y`) to simulate a 40% expansion in the message's length. | ||
This Netflix technology [blog post][blog post] inspired Vocab's implementation of this | ||
functionality. | ||
### Generating a pseudo-localized language using Vocab | ||
Vocab can generate a pseudo-localized language via the [`generatedLanguages` config][generated languages config], either via the webpack plugin or your `vocab.config.js` file. | ||
`@vocab/pseudo-localize` exports a `generator` that can be used directly in your config. | ||
**vocab.config.js** | ||
```js | ||
const { generator } = require('@vocab/pseudo-localize'); | ||
module.exports = { | ||
devLanguage: 'en', | ||
languages: [{ name: 'en' }, { name: 'fr' }], | ||
generatedLanguages: [ | ||
{ | ||
name: 'pseudo', | ||
extends: 'en', | ||
generator | ||
} | ||
] | ||
}; | ||
``` | ||
[blog post]: https://netflixtechblog.com/pseudo-localization-netflix-12fff76fbcbe | ||
[generated languages config]: #generated-languages | ||
## Use without React | ||
@@ -216,0 +363,0 @@ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
36611
392
448