feat: add built-in translations (#200)
* feat: add built-in translations * docs: fix docs * docs: fix docs
This commit is contained in:
parent
9f124f808e
commit
96d0d1d171
|
@ -131,3 +131,4 @@ dist
|
|||
/bundle.js
|
||||
/test/benchmark/node_modules
|
||||
/test/benchmark/data.json
|
||||
/i18n
|
49
README.md
49
README.md
|
@ -33,7 +33,8 @@ A lightweight emoji picker, distributed as a web component.
|
|||
+ [Custom styling](#custom-styling)
|
||||
* [JavaScript API](#javascript-api)
|
||||
+ [Picker](#picker)
|
||||
- [i18n structure](#i18n-structure)
|
||||
- [Internationalization](#internationalization)
|
||||
* [Built-in translations](#built-in-translations)
|
||||
- [Custom category order](#custom-category-order)
|
||||
+ [Database](#database)
|
||||
- [Constructors](#constructors)
|
||||
|
@ -287,9 +288,9 @@ Some values can also be set as declarative attributes:
|
|||
Note that complex properties like `i18n` or `customEmoji` are not supported as attributes, because the DOM only
|
||||
supports string attributes, not complex objects.
|
||||
|
||||
#### i18n structure
|
||||
#### Internationalization
|
||||
|
||||
Here is the default English `i18n` object (`"en"` locale):
|
||||
The `i18n` parameter specifies translations for the picker interface. Here is the default English `i18n` object:
|
||||
|
||||
<!-- i18n options start -->
|
||||
|
||||
|
@ -332,8 +333,36 @@ Here is the default English `i18n` object (`"en"` locale):
|
|||
|
||||
<!-- i18n options end -->
|
||||
|
||||
Note that some of these strings are only visible to users of screen readers.
|
||||
But you should still support them if you internationalize your app!
|
||||
Note that some of these strings are only visible to users of screen readers. They are still important for accessibility!
|
||||
|
||||
##### Built-in translations
|
||||
|
||||
Community-provided translations for some languages [are available](https://github.com/nolanlawson/emoji-picker-element/tree/master/src/i18n). You can use them like so:
|
||||
|
||||
```js
|
||||
import fr from 'emoji-picker-element/i18n/fr';
|
||||
import de from 'emoji-picker-element/i18n/de';
|
||||
|
||||
// French
|
||||
picker.i18n = fr;
|
||||
|
||||
// German
|
||||
picker.i18n = de;
|
||||
```
|
||||
|
||||
Note that translations for the interface (`i18n`) are not the same as translations for the emoji data (`dataSource` and `locale`). To support both, you should do something like:
|
||||
|
||||
```js
|
||||
import fr from 'emoji-picker-element/i18n/fr';
|
||||
|
||||
const picker = new Picker({
|
||||
i18n: fr,
|
||||
locale: 'fr',
|
||||
dataSource: 'https://cdn.jsdelivr.net/npm/emoji-picker-element-data@^1/fr/emojibase/data.json',
|
||||
});
|
||||
```
|
||||
|
||||
If a built-in translation for your target language is not available, you can also write your own translation and pass it in as `i18n`. Please feel free to contribute your translation [here](https://github.com/nolanlawson/emoji-picker-element/tree/master/src/i18n).
|
||||
|
||||
#### Custom category order
|
||||
|
||||
|
@ -740,12 +769,20 @@ While this option can reduce your bundle size, note that it only works if your S
|
|||
|
||||
### Data source and JSON format
|
||||
|
||||
If you'd like to host the emoji JSON yourself, you can do:
|
||||
If you'd like to host the emoji data (`dataSource`) yourself, you can do:
|
||||
|
||||
npm install emoji-picker-element-data@^1
|
||||
|
||||
Then host `node_modules/emoji-picker-element-data/en/emojibase/data.json` (or other JSON files) on your web server.
|
||||
|
||||
```js
|
||||
const picker = new Picker({
|
||||
dataSource: '/path/to/my/webserver/data.json'
|
||||
});
|
||||
```
|
||||
|
||||
See [`emoji-picker-element-data`](https://www.npmjs.com/package/emoji-picker-element-data) for details.
|
||||
|
||||
### Shortcodes
|
||||
|
||||
There is no standard for shortcodes, so unlike other emoji data, there is some disagreement as to what a "shortcode" actually is.
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
import path from 'path'
|
||||
import { copyFile, readdir, writeFile } from './fs.js'
|
||||
import mkdirp from 'mkdirp'
|
||||
import rimraf from 'rimraf'
|
||||
import { promisify } from 'util'
|
||||
|
||||
const __dirname = path.dirname(new URL(import.meta.url).pathname)
|
||||
|
||||
async function main () {
|
||||
const targetDir = path.join(__dirname, '../i18n')
|
||||
|
||||
await promisify(rimraf)(targetDir)
|
||||
await mkdirp(targetDir)
|
||||
|
||||
const sourceDir = path.join(__dirname, '../src/picker/i18n')
|
||||
|
||||
const sourceFiles = await readdir(sourceDir)
|
||||
|
||||
await Promise.all(sourceFiles.map(async sourceFile => {
|
||||
await Promise.all([
|
||||
copyFile(path.join(sourceDir, sourceFile), path.join(targetDir, sourceFile)),
|
||||
writeFile(path.join(targetDir, sourceFile.replace('.js', '.d.ts')), `
|
||||
import { I18n } from "../shared";
|
||||
declare const _default: I18n;
|
||||
export default _default;
|
||||
`.trim())
|
||||
])
|
||||
}))
|
||||
}
|
||||
|
||||
main().catch(err => {
|
||||
console.error(err)
|
||||
process.exit(1)
|
||||
})
|
|
@ -18,11 +18,12 @@
|
|||
],
|
||||
"scripts": {
|
||||
"prepare": "run-s build",
|
||||
"build": "run-s build:rollup build:css-docs build:i18n-docs build:toc",
|
||||
"build": "run-s build:rollup build:i18n build:css-docs build:i18n-docs build:toc",
|
||||
"build:rollup": "cross-env NODE_ENV=production rollup -c",
|
||||
"build:css-docs": "node ./bin/generateCssDocs",
|
||||
"build:i18n-docs": "node ./bin/generateI18nDocs",
|
||||
"build:toc": "node ./bin/generateTOC",
|
||||
"build:i18n": "node ./bin/buildI18n",
|
||||
"benchmark:runtime": "cross-env PERF=1 run-s build:rollup && ./bin/run-benchmark.sh",
|
||||
"benchmark:bundlesize": "run-s build:rollup benchmark:bundle benchmark:run-bundlesize",
|
||||
"benchmark:bundle": "rollup -c ./test/bundlesize/rollup.config.js",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import SveltePicker from './components/Picker/Picker.svelte'
|
||||
import { DEFAULT_DATA_SOURCE, DEFAULT_LOCALE } from '../database/constants'
|
||||
import { DEFAULT_CATEGORY_SORTING, DEFAULT_SKIN_TONE_EMOJI } from './constants'
|
||||
import enI18n from '../picker/i18n/en.js'
|
||||
import enI18n from './i18n/en.js'
|
||||
import styles from 'emoji-picker-element-styles'
|
||||
import Database from './ImportedDatabase'
|
||||
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
export default {
|
||||
categoriesLabel: 'Kategorien',
|
||||
emojiUnsupportedMessage: 'Dein Browser unterstützt keine farbigen Emojis.',
|
||||
favoritesLabel: 'Favoriten',
|
||||
loadingMessage: 'Wird geladen…',
|
||||
networkErrorMessage: 'Konnte Emoji nicht laden. Versuche, die Seite neu zu laden.',
|
||||
regionLabel: 'Emoji auswählen',
|
||||
searchDescription: 'Wenn Suchergebnisse verfügbar sind, wähle sie mit Pfeil rauf und runter, dann Eingabetaste, aus.',
|
||||
searchLabel: 'Suchen',
|
||||
searchResultsLabel: 'Suchergebnisse',
|
||||
skinToneDescription: 'Wenn angezeigt, nutze Pfeiltasten rauf und runter zum Auswählen, Eingabe zum Akzeptieren.',
|
||||
skinToneLabel: 'Wähle einen Hautton (aktuell {skinTone})',
|
||||
skinTonesLabel: 'Hauttöne',
|
||||
skinTones: [
|
||||
'Standard',
|
||||
'Hell',
|
||||
'Mittel-hell',
|
||||
'Mittel',
|
||||
'Mittel-dunkel',
|
||||
'Dunkel'
|
||||
],
|
||||
categories: {
|
||||
custom: 'Benutzerdefiniert',
|
||||
'smileys-emotion': 'Smileys und Emoticons',
|
||||
'people-body': 'Menschen und Körper',
|
||||
'animals-nature': 'Tiere und Natur',
|
||||
'food-drink': 'Essen und Trinken',
|
||||
'travel-places': 'Reisen und Orte',
|
||||
activities: 'Aktivitäten',
|
||||
objects: 'Objekte',
|
||||
symbols: 'Symbole',
|
||||
flags: 'Flaggen'
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
export default {
|
||||
categoriesLabel: 'Catégories',
|
||||
emojiUnsupportedMessage: 'Votre navigateur ne soutient pas les emojis en couleur.',
|
||||
favoritesLabel: 'Favoris',
|
||||
loadingMessage: 'Chargement en cours…',
|
||||
networkErrorMessage: 'Impossible de charger les emojis. Veuillez essayer de recharger.',
|
||||
regionLabel: 'Choisir un emoji',
|
||||
searchDescription: 'Quand les résultats sont disponisbles, appuyez la fleche vers le haut ou le bas et la touche entrée pour choisir.',
|
||||
searchLabel: 'Rechercher',
|
||||
searchResultsLabel: 'Résultats',
|
||||
skinToneDescription: 'Quand disponible, appuyez la fleche vers le haut ou le bas et la touch entrée pour choisir.',
|
||||
skinToneLabel: 'Choisir une couleur de peau (actuellement {skinTone})',
|
||||
skinTonesLabel: 'Couleurs de peau',
|
||||
skinTones: [
|
||||
'Défaut',
|
||||
'Clair',
|
||||
'Moyennement clair',
|
||||
'Moyen',
|
||||
'Moyennement sombre',
|
||||
'Sombre'
|
||||
],
|
||||
categories: {
|
||||
custom: 'Customisé',
|
||||
'smileys-emotion': 'Les smileyes et les émoticônes',
|
||||
'people-body': 'Les gens et le corps',
|
||||
'animals-nature': 'Les animaux et la nature',
|
||||
'food-drink': 'La nourriture et les boissons',
|
||||
'travel-places': 'Les voyages et les endroits',
|
||||
activities: 'Les activités',
|
||||
objects: 'Les objets',
|
||||
symbols: 'Les symbols',
|
||||
flags: 'Les drapeaux'
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue