chore: add translation
This commit is contained in:
parent
6dae766f77
commit
5483adf926
32
README.md
32
README.md
|
@ -62,6 +62,37 @@ TODO
|
||||||
| activeCategoryColor | string | "#005b96" | no | Change active category item color |
|
| activeCategoryColor | string | "#005b96" | no | Change active category item color |
|
||||||
| categoryContainerColor | string | "#e3dbcd" | no | Change category container color |
|
| categoryContainerColor | string | "#e3dbcd" | no | Change category container color |
|
||||||
| onCategoryChangeFailed | function | warn(info) | no | Callback on category change failed (info: {index, highestMeasuredFrameIndex, averageItemLength}) |
|
| onCategoryChangeFailed | function | warn(info) | no | Callback on category change failed (info: {index, highestMeasuredFrameIndex, averageItemLength}) |
|
||||||
|
| translation | CategoryTranslation | en | no | Translation object *see translation section* |
|
||||||
|
## Internationalization
|
||||||
|
### Pre-defined
|
||||||
|
Due to the limited translation possibilities, we only provide a few pre-defined translations into the following languages:
|
||||||
|
* `en` - English
|
||||||
|
* `pl` - Polish
|
||||||
|
|
||||||
|
First import lang and use it as `translation` prop.
|
||||||
|
```ts
|
||||||
|
import { pl } from '{package-name}';
|
||||||
|
|
||||||
|
// ...
|
||||||
|
|
||||||
|
translation={pl}
|
||||||
|
```
|
||||||
|
### Own
|
||||||
|
There is possibility to pass own translation to library with the prop called `translation` like this
|
||||||
|
```ts
|
||||||
|
translation={{
|
||||||
|
smileys_emotion: 'Smileys & Emotion',
|
||||||
|
people_body: 'People & Body',
|
||||||
|
animals_nature: 'Animals & Nature',
|
||||||
|
food_drink: 'Food & Drink',
|
||||||
|
travel_places: 'Travel & Places',
|
||||||
|
activities: 'Activities',
|
||||||
|
objects: 'Objects',
|
||||||
|
symbols: 'Symbols',
|
||||||
|
flags: 'Flags',
|
||||||
|
}}
|
||||||
|
```
|
||||||
|
*If you have written a translation into your language, we strongly encourage you to create a Pull Request and add your language to the package, following the example of other langs.*
|
||||||
## License
|
## License
|
||||||
**MIT**
|
**MIT**
|
||||||
|
|
||||||
|
@ -69,4 +100,3 @@ TODO
|
||||||
## TODO
|
## TODO
|
||||||
categories => Specify displayed categories
|
categories => Specify displayed categories
|
||||||
|
|
||||||
language => Use translation
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
import { StyleSheet, Text, SafeAreaView, TouchableOpacity } from 'react-native';
|
import { StyleSheet, Text, SafeAreaView, TouchableOpacity } from 'react-native';
|
||||||
import EmojiPicker from 'react-native-emoji-keyboard';
|
import EmojiPicker, { pl } from 'react-native-emoji-keyboard';
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
const [result, setResult] = React.useState<string>();
|
const [result, setResult] = React.useState<string>();
|
||||||
|
@ -26,6 +26,7 @@ export default function App() {
|
||||||
onEmojiSelected={handlePick}
|
onEmojiSelected={handlePick}
|
||||||
open={isModalOpen}
|
open={isModalOpen}
|
||||||
onClose={() => setIsModalOpen(false)}
|
onClose={() => setIsModalOpen(false)}
|
||||||
|
translation={pl}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* //////////////////////////////////////////// */}
|
{/* //////////////////////////////////////////// */}
|
||||||
|
|
|
@ -8,7 +8,10 @@ for (const [key, value] of Object.entries(json)) {
|
||||||
name: emoji.name,
|
name: emoji.name,
|
||||||
slug: emoji.slug,
|
slug: emoji.slug,
|
||||||
}));
|
}));
|
||||||
newArray.push({ title: key, data: newData });
|
newArray.push({
|
||||||
|
title: key.replace(' & ', '_').replace(' ', '_').toLocaleLowerCase(),
|
||||||
|
data: newData,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.writeFile(
|
fs.writeFile(
|
||||||
|
|
|
@ -4,7 +4,7 @@ import {
|
||||||
defaultKeyboardContext,
|
defaultKeyboardContext,
|
||||||
defaultKeyboardValues,
|
defaultKeyboardValues,
|
||||||
} from './KeyboardProvider';
|
} from './KeyboardProvider';
|
||||||
import type { EmojiType } from './types';
|
import type { CategoryTranslation, EmojiType } from './types';
|
||||||
|
|
||||||
export type KeyboardProps = {
|
export type KeyboardProps = {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
|
@ -27,6 +27,7 @@ export type KeyboardProps = {
|
||||||
highestMeasuredFrameIndex: number;
|
highestMeasuredFrameIndex: number;
|
||||||
averageItemLength: number;
|
averageItemLength: number;
|
||||||
}) => void;
|
}) => void;
|
||||||
|
translation?: CategoryTranslation;
|
||||||
};
|
};
|
||||||
export type ContextValues = {
|
export type ContextValues = {
|
||||||
activeCategoryIndex: number;
|
activeCategoryIndex: number;
|
||||||
|
|
|
@ -5,6 +5,7 @@ import {
|
||||||
ContextValues,
|
ContextValues,
|
||||||
KeyboardContext,
|
KeyboardContext,
|
||||||
} from './KeyboardContext';
|
} from './KeyboardContext';
|
||||||
|
import en from './translation/en';
|
||||||
import type { EmojiType } from './types';
|
import type { EmojiType } from './types';
|
||||||
|
|
||||||
type ProviderProps = KeyboardProps & {
|
type ProviderProps = KeyboardProps & {
|
||||||
|
@ -30,6 +31,7 @@ export const defaultKeyboardContext: Required<KeyboardProps> = {
|
||||||
onCategoryChangeFailed: (info) => {
|
onCategoryChangeFailed: (info) => {
|
||||||
console.warn(info);
|
console.warn(info);
|
||||||
},
|
},
|
||||||
|
translation: en,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defaultKeyboardValues: ContextValues = {
|
export const defaultKeyboardValues: ContextValues = {
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,7 +1,7 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
import { StyleSheet, View, Text, FlatList } from 'react-native';
|
import { StyleSheet, View, Text, FlatList } from 'react-native';
|
||||||
import type { EmojisByCategory, EmojiType } from 'src/types';
|
import type { EmojisByCategory, EmojiType } from '../types';
|
||||||
import { SingleEmoji } from './SingleEmoji';
|
import { SingleEmoji } from './SingleEmoji';
|
||||||
import { KeyboardContext } from '../KeyboardContext';
|
import { KeyboardContext } from '../KeyboardContext';
|
||||||
|
|
||||||
|
@ -19,23 +19,30 @@ export const EmojiCategory = ({
|
||||||
}: {
|
}: {
|
||||||
item: EmojisByCategory;
|
item: EmojisByCategory;
|
||||||
}) => {
|
}) => {
|
||||||
const { onEmojiSelected, emojiSize, ...ctx } =
|
const {
|
||||||
React.useContext(KeyboardContext);
|
onEmojiSelected,
|
||||||
|
emojiSize,
|
||||||
|
numberOfColumns,
|
||||||
|
width,
|
||||||
|
hideHeader,
|
||||||
|
headerStyles,
|
||||||
|
translation,
|
||||||
|
} = React.useContext(KeyboardContext);
|
||||||
|
|
||||||
const [empty, setEmpty] = React.useState<EmojiType[]>([]);
|
const [empty, setEmpty] = React.useState<EmojiType[]>([]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (data.length % ctx.numberOfColumns) {
|
if (data.length % numberOfColumns) {
|
||||||
const fillWithEmpty = new Array(
|
const fillWithEmpty = new Array(
|
||||||
ctx.numberOfColumns - (data.length % ctx.numberOfColumns)
|
numberOfColumns - (data.length % numberOfColumns)
|
||||||
).fill(emptyEmoji);
|
).fill(emptyEmoji);
|
||||||
setEmpty(fillWithEmpty);
|
setEmpty(fillWithEmpty);
|
||||||
}
|
}
|
||||||
}, [ctx.numberOfColumns, data]);
|
}, [numberOfColumns, data]);
|
||||||
|
|
||||||
const getItemLayout = (_: EmojiType[] | null | undefined, index: number) => ({
|
const getItemLayout = (_: EmojiType[] | null | undefined, index: number) => ({
|
||||||
length: emojiSize ? emojiSize : 0,
|
length: emojiSize ? emojiSize : 0,
|
||||||
offset: emojiSize * Math.ceil(index / ctx.numberOfColumns),
|
offset: emojiSize * Math.ceil(index / numberOfColumns),
|
||||||
index,
|
index,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -51,14 +58,16 @@ export const EmojiCategory = ({
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={[styles.container, { width: ctx.width }]}>
|
<View style={[styles.container, { width: width }]}>
|
||||||
{!ctx.hideHeader && (
|
{!hideHeader && (
|
||||||
<Text style={[styles.sectionTitle, ctx.headerStyles]}>{title}</Text>
|
<Text style={[styles.sectionTitle, headerStyles]}>
|
||||||
|
{translation[title]}
|
||||||
|
</Text>
|
||||||
)}
|
)}
|
||||||
<FlatList
|
<FlatList
|
||||||
data={[...data, ...empty]}
|
data={[...data, ...empty]}
|
||||||
keyExtractor={(emoji) => emoji.name}
|
keyExtractor={(emoji) => emoji.name}
|
||||||
numColumns={ctx.numberOfColumns}
|
numColumns={numberOfColumns}
|
||||||
renderItem={renderItem}
|
renderItem={renderItem}
|
||||||
removeClippedSubviews={true}
|
removeClippedSubviews={true}
|
||||||
getItemLayout={getItemLayout}
|
getItemLayout={getItemLayout}
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
import { EmojiKeyboard } from './EmojiKeyboard';
|
import { EmojiKeyboard } from './EmojiKeyboard';
|
||||||
import { EmojiPicker } from './EmojiPicker';
|
import { EmojiPicker } from './EmojiPicker';
|
||||||
import { KeyboardProvider } from './KeyboardProvider';
|
import { KeyboardProvider } from './KeyboardProvider';
|
||||||
|
import en from './translation/en';
|
||||||
|
import pl from './translation/pl';
|
||||||
|
|
||||||
export { EmojiKeyboard, KeyboardProvider };
|
export { EmojiKeyboard, KeyboardProvider };
|
||||||
|
export { en, pl };
|
||||||
|
|
||||||
export default EmojiPicker;
|
export default EmojiPicker;
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
import type { CategoryTranslation } from '../types';
|
||||||
|
|
||||||
|
export const en: CategoryTranslation = {
|
||||||
|
smileys_emotion: 'Smileys & Emotion',
|
||||||
|
people_body: 'People & Body',
|
||||||
|
animals_nature: 'Animals & Nature',
|
||||||
|
food_drink: 'Food & Drink',
|
||||||
|
travel_places: 'Travel & Places',
|
||||||
|
activities: 'Activities',
|
||||||
|
objects: 'Objects',
|
||||||
|
symbols: 'Symbols',
|
||||||
|
flags: 'Flags',
|
||||||
|
};
|
||||||
|
export default en;
|
|
@ -0,0 +1,14 @@
|
||||||
|
import type { CategoryTranslation } from '../types';
|
||||||
|
|
||||||
|
const pl: CategoryTranslation = {
|
||||||
|
smileys_emotion: 'Buźki i Emocje',
|
||||||
|
people_body: 'Ludzie',
|
||||||
|
animals_nature: 'Zwierzęta i przyroda',
|
||||||
|
food_drink: 'Jedzenie i napoje',
|
||||||
|
travel_places: 'Podróże i miejsca',
|
||||||
|
activities: 'Aktywność',
|
||||||
|
objects: 'Przedmioty',
|
||||||
|
symbols: 'Symbole',
|
||||||
|
flags: 'Flagi',
|
||||||
|
};
|
||||||
|
export default pl;
|
58
src/types.ts
58
src/types.ts
|
@ -5,26 +5,26 @@ export type EmojiType = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export type CategoryTypes =
|
export type CategoryTypes =
|
||||||
| 'Smileys & Emotion'
|
| 'smileys_emotion'
|
||||||
| 'People & Body'
|
| 'people_body'
|
||||||
| 'Animals & Nature'
|
| 'animals_nature'
|
||||||
| 'Food & Drink'
|
| 'food_drink'
|
||||||
| 'Travel & Places'
|
| 'travel_places'
|
||||||
| 'Activities'
|
| 'activities'
|
||||||
| 'Objects'
|
| 'objects'
|
||||||
| 'Symbols'
|
| 'symbols'
|
||||||
| 'Flags';
|
| 'flags';
|
||||||
|
|
||||||
export const CATEGORIES: CategoryTypes[] = [
|
export const CATEGORIES: CategoryTypes[] = [
|
||||||
'Smileys & Emotion',
|
'smileys_emotion',
|
||||||
'People & Body',
|
'people_body',
|
||||||
'Animals & Nature',
|
'animals_nature',
|
||||||
'Food & Drink',
|
'food_drink',
|
||||||
'Travel & Places',
|
'travel_places',
|
||||||
'Activities',
|
'activities',
|
||||||
'Objects',
|
'objects',
|
||||||
'Symbols',
|
'symbols',
|
||||||
'Flags',
|
'flags',
|
||||||
];
|
];
|
||||||
|
|
||||||
export type CategoryNavigationItem = {
|
export type CategoryNavigationItem = {
|
||||||
|
@ -32,16 +32,20 @@ export type CategoryNavigationItem = {
|
||||||
category: CategoryTypes;
|
category: CategoryTypes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type CategoryTranslation = {
|
||||||
|
[key in CategoryTypes]: string;
|
||||||
|
};
|
||||||
|
|
||||||
export const CATEGORIES_NAVIGATION: CategoryNavigationItem[] = [
|
export const CATEGORIES_NAVIGATION: CategoryNavigationItem[] = [
|
||||||
{ icon: 'Smile', category: 'Smileys & Emotion' },
|
{ icon: 'Smile', category: 'smileys_emotion' },
|
||||||
{ icon: 'Users', category: 'People & Body' },
|
{ icon: 'Users', category: 'people_body' },
|
||||||
{ icon: 'Trees', category: 'Animals & Nature' },
|
{ icon: 'Trees', category: 'animals_nature' },
|
||||||
{ icon: 'Pizza', category: 'Food & Drink' },
|
{ icon: 'Pizza', category: 'food_drink' },
|
||||||
{ icon: 'Plane', category: 'Travel & Places' },
|
{ icon: 'Plane', category: 'travel_places' },
|
||||||
{ icon: 'Football', category: 'Activities' },
|
{ icon: 'Football', category: 'activities' },
|
||||||
{ icon: 'Lightbulb', category: 'Objects' },
|
{ icon: 'Lightbulb', category: 'objects' },
|
||||||
{ icon: 'Ban', category: 'Symbols' },
|
{ icon: 'Ban', category: 'symbols' },
|
||||||
{ icon: 'Flag', category: 'Flags' },
|
{ icon: 'Flag', category: 'flags' },
|
||||||
];
|
];
|
||||||
|
|
||||||
export type EmojisByCategory = {
|
export type EmojisByCategory = {
|
||||||
|
|
Loading…
Reference in New Issue