Skip to content

Commit

Permalink
fix: customButton prop for custom components
Browse files Browse the repository at this point in the history
  • Loading branch information
DominikDanielewicz committed Mar 17, 2024
1 parent c9b3ba9 commit 83ce8f8
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 38 deletions.
35 changes: 26 additions & 9 deletions docs/docs/documentation/Examples/custom-button.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,16 @@ To preview app with this example, clone [**github repo**](https://github.com/The

### Usage

We've introduced a custom button feature to provide you with the flexibility to add your unique functionality to our interface. This feature allows you to, for example, add a function that deletes the previously used emoji, enhancing user interaction based on your application's specific needs.
We've introduced a custom button feature to provide you with the flexibility to add your unique functionality to our interface.

If you want to reveal the custom button, pass `enableCustomButton` prop. After that, use the `onCustomButtonPress` callback to define the specific action you want the custom button to perform.
The `customButton` 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.

If search bar is enabled, custom button shows next to it.
To use the `customButton` 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 customButton prop array. You can add `customButtonPressHandler` 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.
Also add `style` prop with an object that allows for customizing the styles of different parts of the DeleteButton. This prop enables the adjustment of the container and button component styles, as well as the normal and active colors of the icon.

```jsx
import EmojiPicker from 'rn-emoji-keyboard'
Expand All @@ -27,13 +32,25 @@ const ExampleComponent = () => {

return (
<EmojiPicker
open={isOpen}
onClose={handleOnClose}
onEmojiSelected={handleOnEmojiSelected}
// add props below
onEmojiSelected={handlePick}
open={isModalOpen}
onClose={() => setIsModalOpen(false)}
enableSearchBar
enableCustomButton
onCustomButtonPress={() => deleteLastEmoji()}
customButton={[
<DeleteButton
key="deleteButton"
customButtonPressHandler={deleteLastEmoji}
style={{
containerStyle: {},
buttonStyle: {
borderRadius: 100,
padding: 10,
},
}}
/>,
]}
allowMultipleSelections
categoryPosition="top"
/>
)
}
Expand Down
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',
},
}}
/>
```
18 changes: 15 additions & 3 deletions example/app/(examples)/custom-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ 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>()
Expand Down Expand Up @@ -31,10 +32,21 @@ export default function () {
open={isModalOpen}
onClose={() => setIsModalOpen(false)}
enableSearchBar
enableCustomButton
onCustomButtonPress={() => deleteLastEmoji()}
customButton={[
<DeleteButton
key="deleteButton"
customButtonPressHandler={deleteLastEmoji}
style={{
containerStyle: {},
buttonStyle: {
borderRadius: 100,
padding: 10,
},
}}
/>,
]}
allowMultipleSelections
categoryPosition="bottom"
categoryPosition="top"
/>
</>
)
Expand Down
2 changes: 0 additions & 2 deletions src/EmojiPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ export const EmojiPicker = ({
onRequestClose,
open,
onClose,
onCustomButtonPress,
expandable = defaultKeyboardContext.expandable,
defaultHeight = defaultKeyboardContext.defaultHeight,
allowMultipleSelections = false,
Expand Down Expand Up @@ -52,7 +51,6 @@ export const EmojiPicker = ({
}}
open={open}
onClose={close}
onCustomButtonPress={onCustomButtonPress}
expandable={expandable}
defaultHeight={defaultHeight}
{...props}
Expand Down
31 changes: 19 additions & 12 deletions src/components/CustomButton.tsx → src/components/DeleteButton.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
import React from 'react'
import { View, Pressable, StyleSheet } from 'react-native'
import { View, Pressable, StyleSheet, type StyleProp, type ViewStyle } from 'react-native'
import { KeyboardContext } from '../contexts/KeyboardContext'
import { Icon } from './Icon'

type DeleteButtonStyles = {
containerStyle?: StyleProp<ViewStyle>
buttonStyle?: StyleProp<ViewStyle> | ((state: { pressed: boolean }) => StyleProp<ViewStyle>)
iconNormalColor?: string
iconActiveColor?: string
}

type CustomButtonType = {
customButtonPressHandler: () => void
customButtonPressHandler?: () => void
style?: DeleteButtonStyles
}

export const CustomButton = ({ customButtonPressHandler }: CustomButtonType) => {
export const DeleteButton = ({ customButtonPressHandler, style }: CustomButtonType) => {
const { theme } = React.useContext(KeyboardContext)
return (
<View style={styles.buttonContainer}>
<View style={[styles.buttonContainer, style?.containerStyle]}>
<Pressable
onPress={customButtonPressHandler}
style={({ pressed }) => [
Expand All @@ -22,14 +30,17 @@ export const CustomButton = ({ customButtonPressHandler }: CustomButtonType) =>
borderRadius: 100,
},
styles.button,
typeof style?.buttonStyle === 'function'
? style.buttonStyle({ pressed })
: style?.buttonStyle,
]}
>
{({ pressed }) => (
<Icon
iconName={'Backspace'}
iconName="Backspace"
isActive={pressed}
normalColor={theme.customButton.icon}
activeColor={theme.customButton.iconPressed}
normalColor={style?.iconNormalColor || theme.customButton.icon}
activeColor={style?.iconActiveColor || theme.customButton.iconPressed}
/>
)}
</Pressable>
Expand All @@ -40,16 +51,12 @@ export const CustomButton = ({ customButtonPressHandler }: CustomButtonType) =>
const styles = StyleSheet.create({
buttonContainer: {
marginTop: 16,
marginHorizontal: 16,
borderRadius: 100,
marginLeft: 8,
flexDirection: 'row',
justifyContent: 'flex-end',
},
button: {
justifyContent: 'center',
alignItems: 'center',
},
text: {
color: 'white',
},
})
9 changes: 3 additions & 6 deletions src/components/EmojiStaticKeyboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { SearchBar } from './SearchBar'
import { useKeyboardStore } from '../store/useKeyboardStore'
import { ConditionalContainer } from './ConditionalContainer'
import { SkinTones } from './SkinTones'
import { CustomButton } from './CustomButton'

const CATEGORY_ELEMENT_WIDTH = 37
const isAndroid = Platform.OS === 'android'
Expand All @@ -31,15 +30,14 @@ export const EmojiStaticKeyboard = React.memo(
enableCategoryChangeGesture,
categoryPosition,
enableSearchBar,
enableCustomButton,
customButton,
searchPhrase,
renderList,
disableSafeArea,
theme,
styles: themeStyles,
shouldAnimateScroll,
enableCategoryChangeAnimation,
onCustomButtonPress,
width,
setWidth,
} = React.useContext(KeyboardContext)
Expand Down Expand Up @@ -144,9 +142,7 @@ export const EmojiStaticKeyboard = React.memo(
}
>
{enableSearchBar && <SearchBar />}
{enableCustomButton && (
<CustomButton customButtonPressHandler={onCustomButtonPress} />
)}
{customButton}
</View>
<Animated.FlatList<EmojisByCategory>
extraData={[keyboardState.recentlyUsed.length, searchPhrase]}
Expand Down Expand Up @@ -185,6 +181,7 @@ const styles = StyleSheet.create({
borderRadius: 16,
},
searchContainer: {
paddingHorizontal: 16,
flexDirection: 'row',
justifyContent: 'flex-end',
},
Expand Down
2 changes: 1 addition & 1 deletion src/components/SearchBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export const SearchBar = () => {
const styles = StyleSheet.create({
container: {
marginTop: 16,
marginHorizontal: 16,
marginRight: 8,
borderRadius: 100,
borderWidth: 1,
borderColor: '#00000011',
Expand Down
6 changes: 2 additions & 4 deletions src/contexts/KeyboardContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,7 @@ export type KeyboardProps = {
enableRecentlyUsed?: boolean
categoryPosition?: CategoryPosition
enableSearchBar?: boolean
enableCustomButton?: boolean
onCustomButtonPress?: () => void
customButton?: React.ReactNode[]
categoryOrder?: CategoryTypes[]
onRequestClose?: () => void
disableSafeArea?: boolean
Expand Down Expand Up @@ -177,8 +176,7 @@ export const defaultKeyboardContext: Required<KeyboardProps> & {
enableRecentlyUsed: false,
categoryPosition: 'floating',
enableSearchBar: false,
enableCustomButton: false,
onCustomButtonPress: () => {},
customButton: [],
categoryOrder: [...CATEGORIES],
onRequestClose: () => {},
disableSafeArea: false,
Expand Down

0 comments on commit 83ce8f8

Please sign in to comment.