Skip to content

Commit 3507ac7

Browse files
authored
Merge pull request #212 from wcastand/main
feat: add a ToastWrapper to wrap the toast with a custom component
2 parents 793b39c + 95bdc29 commit 3507ac7

File tree

5 files changed

+87
-1
lines changed

5 files changed

+87
-1
lines changed

docs/docs/Toaster.md

+24
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,29 @@ import { ZView } from 'react-native-z-view';
6969
/>;
7070
```
7171

72+
73+
### Dismiss toast on tap
74+
75+
Use the `ToastWrapper` prop to wrap the Toast component with a custom component. This is useful when you want to customize the behavior of the toast, for example add a dismiss on tap instead of the the close icon.
76+
77+
```tsx
78+
import { Pressable } from "react-native"
79+
80+
function Wrapper({toastId, children}){
81+
function onPress(){
82+
toast.dismiss(toastId)
83+
}
84+
return <Pressable onPress={onPress}>{children}</Pressable>
85+
}
86+
87+
<Toaster
88+
ToastWrapper={Wrapper}
89+
toastOptions={{
90+
style: { backgroundColor: 'red' },
91+
}}
92+
/>;
93+
```
94+
7295
## API Reference
7396

7497
| Property | Description | Default |
@@ -85,5 +108,6 @@ import { ZView } from 'react-native-z-view';
85108
| pauseWhenPageIsHidden | Pauses toast timers when the app enters background. | `{}` |
86109
| `swipeToDismissDirection` | Swipe direction to dismiss (`left`, `up`). | `up` |
87110
| ToasterOverlayWrapper |  Custom component to wrap the Toaster. | `div` |
111+
| ToastWrapper |  Custom component to wrap the Toast. | `div` |
88112
| autoWiggleOnUpdate | Adds a wiggle animation on toast update. `never`, `toast-change`, `always` | `never` |
89113
| richColors |  Makes error and success state more colorful | `false` |

example/src/App.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { SafeAreaProvider } from 'react-native-safe-area-context';
55
import { Toaster } from 'sonner-native';
66
import '../global.css';
77
import Navigator from './navigation';
8+
// import { ToastWrapper } from './ToastWrapper';
89

910
const App: React.FC = () => {
1011
return (
@@ -29,6 +30,7 @@ const App: React.FC = () => {
2930
paddingHorizontal: 20,
3031
},
3132
}}
33+
// ToastWrapper={ToastWrapper}
3234
pauseWhenPageIsHidden
3335
/>
3436
</GestureHandlerRootView>

example/src/ToastWrapper.tsx

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import * as React from 'react';
2+
import { Pressable, View } from 'react-native';
3+
import { toast } from 'sonner-native';
4+
import '../global.css';
5+
6+
export const ToastWrapper: React.ComponentType<
7+
React.ComponentProps<typeof View> & {
8+
children: React.ReactNode;
9+
toastId: string | number;
10+
}
11+
> = ({ toastId, style, ...props }) => {
12+
return (
13+
<Pressable
14+
style={[style, { backgroundColor: 'red' }]}
15+
onPress={() => toast.dismiss(toastId)}
16+
{...props}
17+
/>
18+
);
19+
};

src/toaster.tsx

+35
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ export const ToasterUI: React.FC<
104104
setToasts,
105105
toastsCounter,
106106
toastRefs,
107+
ToastWrapper,
107108
...props
108109
}) => {
109110
addToastHandler = React.useCallback(
@@ -325,6 +326,23 @@ export const ToasterUI: React.FC<
325326
<ToastContext.Provider value={value}>
326327
<Positioner position={position}>
327328
{positionedNonDynamicToasts.map((positionedToast) => {
329+
if (ToastWrapper) {
330+
return (
331+
<ToastWrapper
332+
key={positionedToast.id}
333+
toastId={positionedToast.id}
334+
style={{ width: '100%' }}
335+
>
336+
<Toast
337+
{...positionedToast}
338+
onDismiss={onDismiss}
339+
onAutoClose={onAutoClose}
340+
ref={toastRefs.current[positionedToast.id]}
341+
{...props}
342+
/>
343+
</ToastWrapper>
344+
);
345+
}
328346
return (
329347
<Toast
330348
key={positionedToast.id}
@@ -343,6 +361,23 @@ export const ToasterUI: React.FC<
343361
}
344362
>
345363
{positionedDynamicToasts.map((positionedToast) => {
364+
if (ToastWrapper) {
365+
return (
366+
<ToastWrapper
367+
key={positionedToast.id}
368+
toastId={positionedToast.id}
369+
style={{ width: '100%' }}
370+
>
371+
<Toast
372+
key={positionedToast.id}
373+
{...positionedToast}
374+
onDismiss={onDismiss}
375+
onAutoClose={onAutoClose}
376+
{...props}
377+
/>
378+
</ToastWrapper>
379+
);
380+
}
346381
return (
347382
<Toast
348383
key={positionedToast.id}

src/types.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type React from 'react';
2-
import type { TextStyle, ViewStyle } from 'react-native';
2+
import type { TextStyle, ViewProps, ViewStyle } from 'react-native';
33

44
type StyleProps = {
55
unstyled?: boolean;
@@ -125,6 +125,12 @@ export type ToasterProps = {
125125
swipeToDismissDirection?: ToastSwipeDirection;
126126
pauseWhenPageIsHidden?: boolean;
127127
ToasterOverlayWrapper?: React.ComponentType<{ children: React.ReactNode }>;
128+
ToastWrapper?: React.ComponentType<
129+
ViewProps & {
130+
children: React.ReactNode;
131+
toastId: string | number;
132+
}
133+
>;
128134
};
129135

130136
export type AddToastContextHandler = (

0 commit comments

Comments
 (0)