Skip to content

Commit

Permalink
Merge branch 'master' into feat/optional-search-clear-icon
Browse files Browse the repository at this point in the history
  • Loading branch information
DominikDanielewicz authored Mar 25, 2024
2 parents 84f7404 + b4ef98c commit 7e87afe
Show file tree
Hide file tree
Showing 16 changed files with 302 additions and 8 deletions.
Binary file added docs/assets/img/custom-button-preview-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/img/custom-button-preview-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/img/custom-button-preview-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions docs/docs/api/modal.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,18 @@ Reveal the search bar, used to find specific emoji.

<ApiTable typeVal='boolean' defaultVal='false'/>

### `hideSearchBarClearIcon`

Hide the search bar clear icon inside the search input.

<ApiTable typeVal='boolean' defaultVal='false'/>

### `customButtons`

Inject custom buttons into the component.

<ApiTable typeVal='React.ReactNode' defaultVal='null'/>

### `enableCategoryChangeAnimation`

Allow to turn off FlatList scrolling animation when category is changed.
Expand Down
63 changes: 63 additions & 0 deletions docs/docs/documentation/Examples/custom-buttons.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
sidebar_position: 13
title: Custom Buttons
---

import preview1 from '../../../assets/img/custom-button-preview-1.png'
import preview2 from '../../../assets/img/custom-button-preview-2.png'
import preview3 from '../../../assets/img/custom-button-preview-3.png'

:::info
To preview app with this example, clone [**github repo**](https://github.com/TheWidlarzGroup/rn-emoji-keyboard.git) and run `yarn example ios` or `yarn example android`.
:::

### Usage

We've introduced a custom button feature to provide you with the flexibility to add your unique functionality to our interface.

The `customButtons` prop allows you to inject custom buttons into the `EmojiPicker` component, enabling additional functionalities or actions within the emoji picker interface. This flexible prop accepts an array of React elements, allowing for multiple custom buttons to be specified.

To use the `customButtons` prop, pass an array of React components that you wish to render as buttons within the emoji picker. Each component must be assigned a unique key prop to help React identify which items have changed, are being added, or are removed.

If search bar is enabled, custom buttons shows next to it.

The `DeleteButton` is a pre-designed component that can be used within the `EmojiPicker` as part of the customButtons prop array. You can add `onPress` prop with a function that will be called when the DeleteButton is pressed. This allows you to define the specific action that should occur on press, such as deleting an emoji from the input field.
. You can add any pressableProps you need to this custom component.

```jsx
import EmojiPicker from 'rn-emoji-keyboard'

const ExampleComponent = () => {
// ...

return (
<EmojiPicker
onEmojiSelected={handlePick}
open={isModalOpen}
onClose={() => setIsModalOpen(false)}
enableSearchBar
customButtons={[
<DeleteButton
key="deleteButton"
onPress={deleteLastEmoji}
style={({ pressed }) => ({
backgroundColor: pressed ? '#000' : '#e1e1e1',
padding: 10,
borderRadius: 100,
})}
iconNormalColor="#000"
iconActiveColor="#fff"
/>,
]}
allowMultipleSelections
categoryPosition="top"
/>
)
}
```

<div className="gallery">
<img src={preview1} alt="First Image" />
<img src={preview2} alt="Second Image" />
<img src={preview3} alt="Third Image" />
</div>
37 changes: 36 additions & 1 deletion docs/docs/documentation/Examples/dark.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ title: Dark Mode
We do not provide a prop that will directly enable dark mode, but with the ability to adjust theme, you can easily achieve it
using theme prop.

```tsx
```jsx
<EmojiPicker
onEmojiSelected={handlePick}
open={isModalOpen}
Expand All @@ -29,3 +29,38 @@ using theme prop.

The effect of the above code.
![The effect of the above code](../../../assets/img/dark-mode-preview.jpg)

Above, the `theme` property is displayed with the styles required for the basic version of the EmojiPicker. Below, you'll find the `theme` property showcasing all available styles.

```jsx
<EmojiPicker
onEmojiSelected={handlePick}
open={isModalOpen}
onClose={() => setIsModalOpen(false)}
theme={{
backdrop: '#16161888',
knob: '#766dfc',
container: '#282829',
header: '#fff',
skinTonesContainer: '#252427',
category: {
icon: '#766dfc',
iconActive: '#fff',
container: '#252427',
containerActive: '#766dfc',
},
customButton: {
icon: '#766dfc',
iconPressed: '#fff',
background: '#252427',
backgroundPressed: '#766dfc',
},
search: {
text: '#fff',
placeholder: '#ffffff2c',
icon: '#fff',
background: '#00000011',
},
}}
/>
```
2 changes: 2 additions & 0 deletions docs/docs/documentation/Examples/search.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ To preview app with this example, clone [**github repo**](https://github.com/The

If you want to reveal the search bar, used to find specific emoji, just pass `enableSearchBar` to `EmojiPicker`.

You can also choose whether to display the search bar clear icon (which appears when you type something in search input). To hide this icon, pass the `hideSearchBarClearIcon` prop to `EmojiPicker`.

```jsx
import EmojiPicker from 'rn-emoji-keyboard'

Expand Down
31 changes: 31 additions & 0 deletions docs/src/css/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,34 @@
font-weight: 700;
src: local('JetBrainsMono'), url(../../assets/fonts/JetBrainsMono-Bold.woff2) format('woff2');
}

.gallery {
display: flex;
justify-content: space-between;
align-items: center;
flex-direction: row;
}

.gallery img {
width: 32%;
margin-right: 2%;
}

.gallery img:last-child {
margin-right: 0;
}

@media (max-width: 768px) {
.gallery {
flex-direction: column;
}
.gallery img {
width: 100%;
margin-right: 0px;
margin-bottom: 20px;
}

.gallery img:last-child {
margin-right: 0;
}
}
53 changes: 53 additions & 0 deletions example/app/(examples)/custom-buttons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { Button } from 'example/src/components/Button'
import React from 'react'
import { Results } from 'example/src/components/Results'
import EmojiPicker, { type EmojiType } from 'rn-emoji-keyboard'
import { DeleteButton } from '../../../src/components/DeleteButton'

export default function () {
const [result, setResult] = React.useState<string>()
const [isModalOpen, setIsModalOpen] = React.useState<boolean>(false)

const handlePick = (emoji: EmojiType) => {
console.log(emoji)
setResult(emoji.emoji)
setIsModalOpen((prev) => !prev)
}

const deleteLastEmoji = () => {
if (result) {
let arrayFromString = Array.from(result)
arrayFromString.pop()
setResult(arrayFromString.join(''))
}
}

return (
<>
<Results label={result} />
<Button onPress={() => setIsModalOpen(true)} label="Open" />

<EmojiPicker
onEmojiSelected={handlePick}
open={isModalOpen}
onClose={() => setIsModalOpen(false)}
enableSearchBar
customButtons={[
<DeleteButton
key="deleteButton"
onPress={deleteLastEmoji}
style={({ pressed }) => ({
backgroundColor: pressed ? '#000' : '#e1e1e1',
padding: 10,
borderRadius: 100,
})}
iconNormalColor="#000"
iconActiveColor="#fff"
/>,
]}
allowMultipleSelections
categoryPosition="top"
/>
</>
)
}
2 changes: 1 addition & 1 deletion example/app/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as React from 'react'

import { StyleSheet, View } from 'react-native'
import { Link } from 'example/src/components/Link'
import { Stack } from 'expo-router'
Expand All @@ -18,6 +17,7 @@ export const screens = {
'/search': 'Search Bar',
'/selected-emojis': 'Selected Emojis',
'/translated': 'Translated',
'/custom-buttons': 'Custom Button',
} as const

export default function App() {
Expand Down
Binary file added src/assets/icons/backspace.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
66 changes: 66 additions & 0 deletions src/components/DeleteButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React from 'react'
import {
View,
Pressable,
StyleSheet,
type StyleProp,
type ViewStyle,
type PressableProps,
} from 'react-native'
import { KeyboardContext } from '../contexts/KeyboardContext'
import { Icon } from './Icon'

type CustomButtonType = {
containerStyle?: StyleProp<ViewStyle>
iconNormalColor?: string
iconActiveColor?: string
} & PressableProps

export const DeleteButton = ({
containerStyle,
iconNormalColor,
iconActiveColor,
...pressableProps
}: CustomButtonType) => {
const { theme } = React.useContext(KeyboardContext)
return (
<View style={[styles.buttonContainer, containerStyle]}>
<Pressable
style={({ pressed }) => [
{
backgroundColor: pressed
? theme.customButton.backgroundPressed
: theme.customButton.background,
padding: 8,
borderRadius: 100,
},
styles.button,
]}
{...pressableProps}
>
{({ pressed }) => (
<Icon
iconName="Backspace"
isActive={pressed}
normalColor={iconNormalColor || theme.customButton.icon}
activeColor={iconActiveColor || theme.customButton.iconPressed}
/>
)}
</Pressable>
</View>
)
}

const styles = StyleSheet.create({
buttonContainer: {
marginTop: 16,
marginLeft: 8,
flexDirection: 'row',
justifyContent: 'flex-end',
alignItems: 'center',
},
button: {
justifyContent: 'center',
alignItems: 'center',
},
})
22 changes: 18 additions & 4 deletions src/components/EmojiStaticKeyboard.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as React from 'react'

import {
StyleSheet,
View,
Expand Down Expand Up @@ -30,6 +29,7 @@ export const EmojiStaticKeyboard = React.memo(
enableCategoryChangeGesture,
categoryPosition,
enableSearchBar,
customButtons,
searchPhrase,
renderList,
disableSafeArea,
Expand Down Expand Up @@ -139,9 +139,18 @@ export const EmojiStaticKeyboard = React.memo(
)}
>
<>
{enableSearchBar && (
<SearchBar scrollEmojiCategoryListToIndex={scrollEmojiCategoryListToIndex} />
)}
<View
style={
categoryPosition === 'top'
? [styles.searchContainer, { marginBottom: 16 }]
: styles.searchContainer
}
>
{enableSearchBar && (
<SearchBar scrollEmojiCategoryListToIndex={scrollEmojiCategoryListToIndex} />
)}
{customButtons}
</View>
<Animated.FlatList<EmojisByCategory>
extraData={[keyboardState.recentlyUsed.length, searchPhrase]}
data={renderList}
Expand Down Expand Up @@ -181,6 +190,11 @@ const styles = StyleSheet.create({
flex: 1,
borderRadius: 16,
},
searchContainer: {
paddingHorizontal: 16,
flexDirection: 'row',
justifyContent: 'flex-end',
},
containerReverse: { flexDirection: 'column-reverse' },
containerShadow: {
shadowColor: 'black',
Expand Down
4 changes: 3 additions & 1 deletion src/components/Icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const Icon = ({
normalColor,
activeColor,
}: {
iconName: IconNames | 'Close' | 'QuestionMark'
iconName: IconNames | 'Close' | 'QuestionMark' | 'Backspace'
isActive: boolean
normalColor: string
activeColor: string
Expand Down Expand Up @@ -43,6 +43,8 @@ export const Icon = ({
return <PngIcon fill={color} source={require('../assets/icons/clock.png')} />
case 'QuestionMark':
return <PngIcon fill={color} source={require('../assets/icons/questionMark.png')} />
case 'Backspace':
return <PngIcon fill={color} source={require('../assets/icons/backspace.png')} />
default:
exhaustiveTypeCheck(iconName)
return null
Expand Down
4 changes: 3 additions & 1 deletion src/components/SearchBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export const SearchBar = ({ scrollEmojiCategoryListToIndex }: SearchBarProps) =>
setShouldAnimateScroll(enableSearchAnimation)
}
}

const clearPhrase = () => {
setSearchPhrase('')
clearEmojiTonesData()
Expand Down Expand Up @@ -86,12 +87,13 @@ export const SearchBar = ({ scrollEmojiCategoryListToIndex }: SearchBarProps) =>
const styles = StyleSheet.create({
container: {
marginTop: 16,
marginHorizontal: 16,
marginRight: 8,
borderRadius: 100,
borderWidth: 1,
borderColor: '#00000011',
flexDirection: 'row',
alignItems: 'center',
flex: 1,
},
input: {
paddingVertical: 8,
Expand Down
Loading

0 comments on commit 7e87afe

Please sign in to comment.