Skip to content

Commit d970f95

Browse files
committed
feat(toast): handle native modal overlay
1 parent 79ff936 commit d970f95

File tree

4 files changed

+80
-16
lines changed

4 files changed

+80
-16
lines changed

example/src/app/(home)/_layout.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,13 @@ export default function Layout() {
144144
animationDuration: 300,
145145
}}
146146
/>
147+
<Stack.Screen
148+
name="components/toast-native-modal"
149+
options={{
150+
title: 'Toast From Native Modal',
151+
presentation: 'formSheet',
152+
}}
153+
/>
147154
</Stack>
148155
</View>
149156
);
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { Button, useToast } from 'heroui-native';
2+
import { View } from 'react-native';
3+
4+
export default function ToastNativeModalScreen() {
5+
const { toast } = useToast();
6+
7+
return (
8+
<View className="pt-40 px-5 items-center justify-center gap-5">
9+
<Button
10+
variant="secondary"
11+
className="self-center"
12+
onPress={() => {
13+
toast.show({
14+
variant: 'success',
15+
duration: 2000,
16+
label: 'Payment successful',
17+
description:
18+
'Your subscription has been renewed. You will be charged $9.99/month. Thank you for your continued support.',
19+
actionLabel: 'Close',
20+
onActionPress: ({ hide }) => {
21+
hide();
22+
},
23+
});
24+
}}
25+
>
26+
Show toast
27+
</Button>
28+
<Button onPress={() => toast.hide('all')} variant="destructive-soft">
29+
Hide toast
30+
</Button>
31+
</View>
32+
);
33+
}

example/src/app/(home)/components/toast.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Feather from '@expo/vector-icons/Feather';
22
import Octicons from '@expo/vector-icons/Octicons';
3+
import { useRouter } from 'expo-router';
34
import { Button, useToast, type ToastComponentProps } from 'heroui-native';
45
import { useCallback, useRef, useState } from 'react';
56
import { TextInput, View } from 'react-native';
@@ -255,6 +256,23 @@ const KeyboardAvoidingContent = () => {
255256

256257
// ------------------------------------------------------------------------------
257258

259+
const FromNativeModalContent = () => {
260+
const router = useRouter();
261+
262+
return (
263+
<View className="flex-1 items-center justify-center px-5 gap-5">
264+
<Button
265+
variant="secondary"
266+
onPress={() => router.push('components/toast-native-modal')}
267+
>
268+
Open modal
269+
</Button>
270+
</View>
271+
);
272+
};
273+
274+
// ------------------------------------------------------------------------------
275+
258276
const CustomToastsContent = () => {
259277
const { toast } = useToast();
260278
const LOADING_TOAST_ID = 'loading-toast';
@@ -411,6 +429,11 @@ const TOAST_VARIANTS: UsageVariant[] = [
411429
label: 'Keyboard avoiding',
412430
content: <KeyboardAvoidingContent />,
413431
},
432+
{
433+
value: 'from-native-modal',
434+
label: 'From native modal',
435+
content: <FromNativeModalContent />,
436+
},
414437
{
415438
value: 'custom-toasts',
416439
label: 'Custom toasts',

src/providers/toast/insets-container.tsx

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import type { ReactNode } from 'react';
2-
import { useMemo } from 'react';
2+
import { Fragment, useMemo } from 'react';
33
import { Platform, View } from 'react-native';
44
import { useSafeAreaInsets } from 'react-native-safe-area-context';
5+
import { FullWindowOverlay } from 'react-native-screens';
56
import type { ToastInsets } from './types';
67

78
interface InsetsContainerProps {
@@ -53,21 +54,21 @@ export function InsetsContainer({
5354
};
5455
}, [safeAreaInsets, insets]);
5556

57+
const WindowOverlay = Platform.OS === 'ios' ? FullWindowOverlay : Fragment;
58+
5659
return (
57-
<View
58-
className="absolute inset-0 pointer-events-box-none"
59-
style={{
60-
paddingTop: finalInsets.top,
61-
paddingBottom: finalInsets.bottom,
62-
paddingLeft: finalInsets.left,
63-
paddingRight: finalInsets.right,
64-
}}
65-
>
66-
{contentWrapper ? (
67-
contentWrapper(children)
68-
) : (
69-
<View className="flex-1">{children}</View>
70-
)}
71-
</View>
60+
<WindowOverlay>
61+
<View
62+
className="absolute inset-0 pointer-events-box-none"
63+
style={{
64+
paddingTop: finalInsets.top,
65+
paddingBottom: finalInsets.bottom,
66+
paddingLeft: finalInsets.left,
67+
paddingRight: finalInsets.right,
68+
}}
69+
>
70+
{contentWrapper ? contentWrapper(children) : children}
71+
</View>
72+
</WindowOverlay>
7273
);
7374
}

0 commit comments

Comments
 (0)