diff --git a/src/EmojiKeyboard.tsx b/src/EmojiKeyboard.tsx index ca18567..38bc13b 100644 --- a/src/EmojiKeyboard.tsx +++ b/src/EmojiKeyboard.tsx @@ -15,7 +15,8 @@ import emojisByGroup from './assets/emojis.json'; export const EmojiKeyboard = () => { const { width } = useWindowDimensions(); - const ctx = React.useContext(KeyboardContext); + const { activeCategoryIndex, containerStyles, onCategoryChangeFailed } = + React.useContext(KeyboardContext); const flatListRef = React.useRef(null); @@ -36,22 +37,20 @@ export const EmojiKeyboard = () => { ); React.useEffect(() => { Animated.spring(scrollNav, { - toValue: ctx.activeCategoryIndex * (28 + 9), + toValue: activeCategoryIndex * (28 + 9), useNativeDriver: true, }).start(); - }, [ctx, scrollNav]); + }, [activeCategoryIndex, scrollNav]); return ( - + item.title} renderItem={renderItem} removeClippedSubviews={true} ref={flatListRef} - onScrollToIndexFailed={() => {}} + onScrollToIndexFailed={onCategoryChangeFailed} horizontal showsHorizontalScrollIndicator={false} pagingEnabled diff --git a/src/KeyboardContext.tsx b/src/KeyboardContext.tsx index b375178..9a9abb0 100644 --- a/src/KeyboardContext.tsx +++ b/src/KeyboardContext.tsx @@ -22,6 +22,11 @@ export type KeyboardProps = { categoryColor?: string; activeCategoryColor?: string; categoryContainerColor?: string; + onCategoryChangeFailed?: (info: { + index: number; + highestMeasuredFrameIndex: number; + averageItemLength: number; + }) => void; }; export type ContextValues = { activeCategoryIndex: number; diff --git a/src/KeyboardProvider.tsx b/src/KeyboardProvider.tsx index 7468817..082c42c 100644 --- a/src/KeyboardProvider.tsx +++ b/src/KeyboardProvider.tsx @@ -27,6 +27,9 @@ export const defaultKeyboardContext: Required = { categoryColor: '#000000', activeCategoryColor: '#005b96', categoryContainerColor: '#e3dbcd', + onCategoryChangeFailed: (info) => { + console.warn(info); + }, }; export const defaultKeyboardValues: ContextValues = { diff --git a/src/components/Categories.tsx b/src/components/Categories.tsx index f0bcc24..e6b2ec3 100644 --- a/src/components/Categories.tsx +++ b/src/components/Categories.tsx @@ -1,7 +1,12 @@ import * as React from 'react'; import { View, Animated, StyleSheet, FlatList } from 'react-native'; import { KeyboardContext } from '../KeyboardContext'; -import { CATEGORIES, CATEGORIES_NAVIGATION, CategoryTypes } from '../types'; +import { + CATEGORIES, + CATEGORIES_NAVIGATION, + CategoryNavigationItem, + CategoryTypes, +} from '../types'; import { CategoryItem } from './CategoryItem'; type CategoriesProps = { @@ -10,7 +15,12 @@ type CategoriesProps = { }; export const Categories = ({ flatListRef, scrollNav }: CategoriesProps) => { - const ctx = React.useContext(KeyboardContext); + const { + activeCategoryIndex, + categoryContainerColor, + onCategoryChangeFailed, + } = React.useContext(KeyboardContext); + const handleScrollToCategory = React.useCallback( (category: CategoryTypes) => { flatListRef?.current?.scrollToIndex({ @@ -21,7 +31,7 @@ export const Categories = ({ flatListRef, scrollNav }: CategoriesProps) => { ); const rendarItem = React.useCallback( - ({ item, index }) => ( + ({ item, index }: { item: CategoryNavigationItem; index: number }) => ( { return ( { ItemSeparatorComponent={() => } scrollEnabled={false} horizontal={true} - onScrollToIndexFailed={(e) => console.log(e)} + onScrollToIndexFailed={onCategoryChangeFailed} ListHeaderComponent={activeIndicator} ListHeaderComponentStyle={styles.activeIndicatorContainer} - extraData={ctx?.activeCategoryIndex} + extraData={activeCategoryIndex} /> diff --git a/src/components/CategoryItem.tsx b/src/components/CategoryItem.tsx index 2e89066..e9e8c4d 100644 --- a/src/components/CategoryItem.tsx +++ b/src/components/CategoryItem.tsx @@ -1,11 +1,11 @@ import * as React from 'react'; import { View, StyleSheet, TouchableOpacity } from 'react-native'; import { KeyboardContext } from '../KeyboardContext'; -import type { CategoryTypes } from '../types'; +import type { CategoryNavigationItem, CategoryTypes } from '../types'; import { Icon } from './Icon'; type CategoryItemProps = { - item: any; + item: CategoryNavigationItem; index: number; handleScrollToCategory: (category: CategoryTypes) => void; }; @@ -15,21 +15,26 @@ export const CategoryItem = ({ index, handleScrollToCategory, }: CategoryItemProps) => { - const ctx = React.useContext(KeyboardContext); + const { + activeCategoryIndex, + categoryColor, + activeCategoryColor, + setActiveCategoryIndex, + } = React.useContext(KeyboardContext); + + const handleSelect = () => { + handleScrollToCategory(item.category); + setActiveCategoryIndex(index); + }; return ( - { - handleScrollToCategory(item.category); - ctx?.setActiveCategoryIndex(index); - }} - > + diff --git a/src/components/EmojiCategory.tsx b/src/components/EmojiCategory.tsx index 95fda32..57c1a74 100644 --- a/src/components/EmojiCategory.tsx +++ b/src/components/EmojiCategory.tsx @@ -14,20 +14,24 @@ const emptyEmoji = { emoji_version: '0', }; -export const EmojiCategory = ({ item }: { item: EmojisByCategory }) => { +export const EmojiCategory = ({ + item: { title, data }, +}: { + item: EmojisByCategory; +}) => { const { onEmojiSelected, emojiSize, ...ctx } = React.useContext(KeyboardContext); const [empty, setEmpty] = React.useState([]); React.useEffect(() => { - if (item.data.length % ctx.numberOfColumns) { + if (data.length % ctx.numberOfColumns) { const fillWithEmpty = new Array( - ctx.numberOfColumns - (item.data.length % ctx.numberOfColumns) + ctx.numberOfColumns - (data.length % ctx.numberOfColumns) ).fill(emptyEmoji); setEmpty(fillWithEmpty); } - }, [ctx.numberOfColumns, item]); + }, [ctx.numberOfColumns, data]); const getItemLayout = (_: EmojiType[] | null | undefined, index: number) => ({ length: emojiSize ? emojiSize : 0, @@ -49,12 +53,10 @@ export const EmojiCategory = ({ item }: { item: EmojisByCategory }) => { return ( {!ctx.hideHeader && ( - - {item.title} - + {title} )} emoji.name} numColumns={ctx.numberOfColumns} renderItem={renderItem} diff --git a/src/components/ModalWithBackdrop.tsx b/src/components/ModalWithBackdrop.tsx index d6721d0..1951282 100644 --- a/src/components/ModalWithBackdrop.tsx +++ b/src/components/ModalWithBackdrop.tsx @@ -75,5 +75,6 @@ const styles = StyleSheet.create({ shadowOpacity: 0.15, shadowOffset: { width: 0, height: 0 }, shadowRadius: 5, + elevation: 10, }, }); diff --git a/src/components/SingleEmoji.tsx b/src/components/SingleEmoji.tsx index b081643..1bfa0aa 100644 --- a/src/components/SingleEmoji.tsx +++ b/src/components/SingleEmoji.tsx @@ -11,15 +11,11 @@ export class SingleEmoji extends React.Component<{ return false; } render() { + const { item, emojiSize, onPress } = this.props; return ( - this.props.onPress(this.props.item)} - style={styles.container} - > + onPress(item)} style={styles.container}> - - {this.props.item.emoji} - + {item.emoji} ); diff --git a/src/types.ts b/src/types.ts index 40419d8..a7d4fb3 100644 --- a/src/types.ts +++ b/src/types.ts @@ -30,7 +30,7 @@ export const CATEGORIES: CategoryTypes[] = [ 'Flags', ]; -type CategoryNavigationItem = { +export type CategoryNavigationItem = { icon: string; category: CategoryTypes; }; @@ -47,18 +47,6 @@ export const CATEGORIES_NAVIGATION: CategoryNavigationItem[] = [ { icon: 'Flag', category: 'Flags' }, ]; -// export const CATEGORIES_NAVIGATION: CategoryNavigationItem[] = [ -// { icon: '😀', category: 'Smileys & Emotion' }, -// { icon: '👋', category: 'People & Body' }, -// { icon: '🐵', category: 'Animals & Nature' }, -// { icon: '🍇', category: 'Food & Drink' }, -// { icon: '🌍', category: 'Travel & Places' }, -// { icon: '🎃', category: 'Activities' }, -// { icon: '👓', category: 'Objects' }, -// { icon: '🏧', category: 'Symbols' }, -// { icon: '🏁', category: 'Flags' }, -// ]; - export type EmojisByCategory = { title: CategoryTypes; data: EmojiType[];