react-native-bread 0.5.3 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -11
- package/lib/commonjs/index.js +6 -0
- package/lib/commonjs/toast-provider.js +53 -5
- package/lib/module/index.js +1 -1
- package/lib/module/toast-provider.js +53 -6
- package/lib/typescript/index.d.ts +1 -1
- package/lib/typescript/toast-provider.d.ts +30 -0
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -6,20 +6,19 @@ An extremely lightweight, opinionated toast component for React Native.
|
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
9
|
-
- **
|
|
9
|
+
- **Lightweight** - only 20KB packed size
|
|
10
|
+
- **New Architecture** - built exclusively for React Native 0.76+ with Fabric
|
|
10
11
|
- Clean, imperative API inspired by [Sonner](https://sonner.emilkowal.ski/)
|
|
11
12
|
- Zero setup - add one component, start toasting. No hooks, no providers
|
|
12
|
-
-
|
|
13
|
+
- Smooth 60fps animations powered by Reanimated
|
|
13
14
|
- Natural swipe gestures that feel native to the platform
|
|
14
15
|
- Multiple toast types: `success`, `error`, `info`, `promise`, and `custom`
|
|
15
16
|
- Promise handling with automatic loading → success/error states
|
|
16
|
-
- Complex animations and gestures but with high performance
|
|
17
17
|
- Toast stacking with configurable limits
|
|
18
|
-
-
|
|
19
|
-
- **RTL
|
|
18
|
+
- **Works above modals** - automatic on iOS, simple setup on Android
|
|
19
|
+
- **RTL support** - perfect for Arabic and other RTL languages
|
|
20
20
|
- Completely customizable - colors, icons, styles, animations
|
|
21
21
|
- Full Expo compatibility
|
|
22
|
-
- Imperative API works anywhere - components, utilities, event handlers
|
|
23
22
|
|
|
24
23
|
|
|
25
24
|
|
|
@@ -38,19 +37,20 @@ This package requires the following peer dependencies:
|
|
|
38
37
|
| [react-native-reanimated](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/getting-started) | >= 4.1.0 |
|
|
39
38
|
| [react-native-gesture-handler](https://docs.swmansion.com/react-native-gesture-handler/docs/) | >= 2.25.0 |
|
|
40
39
|
| [react-native-safe-area-context](https://docs.expo.dev/versions/latest/sdk/safe-area-context/) | >= 5.0.0 |
|
|
40
|
+
| [react-native-screens](https://docs.swmansion.com/react-native-screens/) | >= 4.0.0 |
|
|
41
41
|
| [react-native-svg](https://github.com/software-mansion/react-native-svg) | >= 15.8.0 |
|
|
42
42
|
| [react-native-worklets](https://github.com/margelo/react-native-worklets-core) | >= 0.5.0 |
|
|
43
43
|
|
|
44
44
|
If you don't have these installed, you can install all peer dependencies at once:
|
|
45
45
|
|
|
46
46
|
```sh
|
|
47
|
-
bun add react-native-reanimated react-native-gesture-handler react-native-safe-area-context react-native-svg react-native-worklets
|
|
47
|
+
bun add react-native-reanimated react-native-gesture-handler react-native-safe-area-context react-native-screens react-native-svg react-native-worklets
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
Or with npm:
|
|
51
51
|
|
|
52
52
|
```sh
|
|
53
|
-
npm install react-native-reanimated react-native-gesture-handler react-native-safe-area-context react-native-svg react-native-worklets
|
|
53
|
+
npm install react-native-reanimated react-native-gesture-handler react-native-safe-area-context react-native-screens react-native-svg react-native-worklets
|
|
54
54
|
```
|
|
55
55
|
|
|
56
56
|
> **Note**: Make sure your `react-native-reanimated` and `react-native-worklets` versions are compatible. Reanimated 4.1.x works with worklets 0.5.x-0.7.x, while Reanimated 4.2.x requires worklets 0.7.x only.
|
|
@@ -217,9 +217,43 @@ Available options include:
|
|
|
217
217
|
| `toast.dismiss(id)` | Dismiss a specific toast |
|
|
218
218
|
| `toast.dismissAll()` | Dismiss all toasts |
|
|
219
219
|
|
|
220
|
-
##
|
|
220
|
+
## Toasts in Modals
|
|
221
221
|
|
|
222
|
-
|
|
222
|
+
Toasts automatically appear above native modals on **iOS**.
|
|
223
223
|
|
|
224
|
-
**
|
|
224
|
+
On **Android**, you have two options:
|
|
225
|
+
|
|
226
|
+
### Option 1: Use a Contained Modal
|
|
227
|
+
|
|
228
|
+
The simplest fix is to use `containedModal` presentation instead of `modal`. On Android, `modal` and `containedModal` look nearly identical, so this is an easy swap:
|
|
229
|
+
|
|
230
|
+
```tsx
|
|
231
|
+
<Stack.Screen
|
|
232
|
+
name="(modal)"
|
|
233
|
+
options={{ presentation: Platform.OS === "android" ? "containedModal" : "modal" }}
|
|
234
|
+
/>
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
This renders the modal within the React hierarchy on Android, so toasts from your root `<BreadLoaf />` remain visible.
|
|
238
|
+
|
|
239
|
+
### Option 2: Use ToastPortal
|
|
240
|
+
|
|
241
|
+
If you need native modals, add `<ToastPortal />` inside your modal layouts:
|
|
242
|
+
|
|
243
|
+
```tsx
|
|
244
|
+
// app/(modal)/_layout.tsx
|
|
245
|
+
import { Stack } from "expo-router";
|
|
246
|
+
import { ToastPortal } from "react-native-bread";
|
|
247
|
+
|
|
248
|
+
export default function ModalLayout() {
|
|
249
|
+
return (
|
|
250
|
+
<>
|
|
251
|
+
<Stack screenOptions={{ headerShown: false }} />
|
|
252
|
+
<ToastPortal />
|
|
253
|
+
</>
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
The `ToastPortal` component only renders on Android - it returns `null` on iOS, so no platform check is needed.
|
|
225
259
|
|
package/lib/commonjs/index.js
CHANGED
|
@@ -39,6 +39,12 @@ Object.defineProperty(exports, "ToastContainer", {
|
|
|
39
39
|
return _toast.ToastContainer;
|
|
40
40
|
}
|
|
41
41
|
});
|
|
42
|
+
Object.defineProperty(exports, "ToastPortal", {
|
|
43
|
+
enumerable: true,
|
|
44
|
+
get: function () {
|
|
45
|
+
return _toastProvider.ToastPortal;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
42
48
|
Object.defineProperty(exports, "toast", {
|
|
43
49
|
enumerable: true,
|
|
44
50
|
get: function () {
|
|
@@ -4,11 +4,20 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.BreadLoaf = BreadLoaf;
|
|
7
|
+
exports.ToastPortal = ToastPortal;
|
|
7
8
|
var _react = require("react");
|
|
8
9
|
var _reactNative = require("react-native");
|
|
10
|
+
var _reactNativeScreens = require("react-native-screens");
|
|
9
11
|
var _toast = require("./toast.js");
|
|
10
12
|
var _toastStore = require("./toast-store.js");
|
|
11
13
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
14
|
+
function ToastContent() {
|
|
15
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
16
|
+
style: styles.container,
|
|
17
|
+
pointerEvents: "box-none",
|
|
18
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_toast.ToastContainer, {})
|
|
19
|
+
});
|
|
20
|
+
}
|
|
12
21
|
/**
|
|
13
22
|
* Toast component that enables toast notifications in your app.
|
|
14
23
|
* Add `<BreadLoaf />` to your root layout to start showing toasts.
|
|
@@ -51,11 +60,50 @@ function BreadLoaf({
|
|
|
51
60
|
_toastStore.toastStore.setConfig(undefined);
|
|
52
61
|
};
|
|
53
62
|
}, [config]);
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
63
|
+
|
|
64
|
+
// iOS: use FullWindowOverlay to render above native modals
|
|
65
|
+
if (_reactNative.Platform.OS === "ios") {
|
|
66
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeScreens.FullWindowOverlay, {
|
|
67
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(ToastContent, {})
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(ToastContent, {});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Lightweight toast renderer for use inside modal screens.
|
|
75
|
+
*
|
|
76
|
+
* On Android, native modals render above the root React view, so toasts from
|
|
77
|
+
* the main `<BreadLoaf />` won't be visible. Add `<ToastPortal />` inside your
|
|
78
|
+
* modal layouts to show toasts above modal content.
|
|
79
|
+
*
|
|
80
|
+
* This component only renders on Android - it returns `null` on iOS where
|
|
81
|
+
* `<BreadLoaf />` already handles modal overlay via `FullWindowOverlay`.
|
|
82
|
+
*
|
|
83
|
+
* This component only renders toasts - it does not accept configuration.
|
|
84
|
+
* All styling/behavior is inherited from your root `<BreadLoaf />` config.
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```tsx
|
|
88
|
+
* // app/(modal)/_layout.tsx
|
|
89
|
+
* import { Stack } from 'expo-router';
|
|
90
|
+
* import { ToastPortal } from 'react-native-bread';
|
|
91
|
+
*
|
|
92
|
+
* export default function ModalLayout() {
|
|
93
|
+
* return (
|
|
94
|
+
* <>
|
|
95
|
+
* <Stack screenOptions={{ headerShown: false }} />
|
|
96
|
+
* <ToastPortal />
|
|
97
|
+
* </>
|
|
98
|
+
* );
|
|
99
|
+
* }
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
function ToastPortal() {
|
|
103
|
+
if (_reactNative.Platform.OS !== "android") {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(ToastContent, {});
|
|
59
107
|
}
|
|
60
108
|
const styles = _reactNative.StyleSheet.create({
|
|
61
109
|
container: {
|
package/lib/module/index.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
export { CloseIcon, GreenCheck, InfoIcon, RedX } from "./icons/index.js";
|
|
7
7
|
export { ToastContainer } from "./toast.js";
|
|
8
8
|
export { toast } from "./toast-api.js";
|
|
9
|
-
export { BreadLoaf } from "./toast-provider.js";
|
|
9
|
+
export { BreadLoaf, ToastPortal } from "./toast-provider.js";
|
|
10
10
|
|
|
11
11
|
// Store (for advanced usage)
|
|
12
12
|
export { toastStore } from "./toast-store.js";
|
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
import { useEffect } from "react";
|
|
4
|
-
import { StyleSheet, View } from "react-native";
|
|
4
|
+
import { Platform, StyleSheet, View } from "react-native";
|
|
5
|
+
import { FullWindowOverlay } from "react-native-screens";
|
|
5
6
|
import { ToastContainer } from "./toast.js";
|
|
6
7
|
import { toastStore } from "./toast-store.js";
|
|
7
8
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
9
|
+
function ToastContent() {
|
|
10
|
+
return /*#__PURE__*/_jsx(View, {
|
|
11
|
+
style: styles.container,
|
|
12
|
+
pointerEvents: "box-none",
|
|
13
|
+
children: /*#__PURE__*/_jsx(ToastContainer, {})
|
|
14
|
+
});
|
|
15
|
+
}
|
|
8
16
|
/**
|
|
9
17
|
* Toast component that enables toast notifications in your app.
|
|
10
18
|
* Add `<BreadLoaf />` to your root layout to start showing toasts.
|
|
@@ -47,11 +55,50 @@ export function BreadLoaf({
|
|
|
47
55
|
toastStore.setConfig(undefined);
|
|
48
56
|
};
|
|
49
57
|
}, [config]);
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
58
|
+
|
|
59
|
+
// iOS: use FullWindowOverlay to render above native modals
|
|
60
|
+
if (Platform.OS === "ios") {
|
|
61
|
+
return /*#__PURE__*/_jsx(FullWindowOverlay, {
|
|
62
|
+
children: /*#__PURE__*/_jsx(ToastContent, {})
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
return /*#__PURE__*/_jsx(ToastContent, {});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Lightweight toast renderer for use inside modal screens.
|
|
70
|
+
*
|
|
71
|
+
* On Android, native modals render above the root React view, so toasts from
|
|
72
|
+
* the main `<BreadLoaf />` won't be visible. Add `<ToastPortal />` inside your
|
|
73
|
+
* modal layouts to show toasts above modal content.
|
|
74
|
+
*
|
|
75
|
+
* This component only renders on Android - it returns `null` on iOS where
|
|
76
|
+
* `<BreadLoaf />` already handles modal overlay via `FullWindowOverlay`.
|
|
77
|
+
*
|
|
78
|
+
* This component only renders toasts - it does not accept configuration.
|
|
79
|
+
* All styling/behavior is inherited from your root `<BreadLoaf />` config.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```tsx
|
|
83
|
+
* // app/(modal)/_layout.tsx
|
|
84
|
+
* import { Stack } from 'expo-router';
|
|
85
|
+
* import { ToastPortal } from 'react-native-bread';
|
|
86
|
+
*
|
|
87
|
+
* export default function ModalLayout() {
|
|
88
|
+
* return (
|
|
89
|
+
* <>
|
|
90
|
+
* <Stack screenOptions={{ headerShown: false }} />
|
|
91
|
+
* <ToastPortal />
|
|
92
|
+
* </>
|
|
93
|
+
* );
|
|
94
|
+
* }
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
export function ToastPortal() {
|
|
98
|
+
if (Platform.OS !== "android") {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
return /*#__PURE__*/_jsx(ToastContent, {});
|
|
55
102
|
}
|
|
56
103
|
const styles = StyleSheet.create({
|
|
57
104
|
container: {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { CloseIcon, GreenCheck, InfoIcon, RedX } from "./icons";
|
|
2
2
|
export { ToastContainer } from "./toast";
|
|
3
3
|
export { toast } from "./toast-api";
|
|
4
|
-
export { BreadLoaf } from "./toast-provider";
|
|
4
|
+
export { BreadLoaf, ToastPortal } from "./toast-provider";
|
|
5
5
|
export { toastStore } from "./toast-store";
|
|
6
6
|
export type { CustomContentProps, CustomContentRenderFn, ErrorMessageInput, IconProps, IconRenderFn, MessageInput, PromiseMessages, PromiseResult, Toast, ToastConfig, ToastOptions, ToastPosition, ToastState, ToastType, ToastTypeColors, } from "./types";
|
|
7
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -49,5 +49,35 @@ interface BreadLoafProps {
|
|
|
49
49
|
* ```
|
|
50
50
|
*/
|
|
51
51
|
export declare function BreadLoaf({ config }: BreadLoafProps): import("react/jsx-runtime").JSX.Element;
|
|
52
|
+
/**
|
|
53
|
+
* Lightweight toast renderer for use inside modal screens.
|
|
54
|
+
*
|
|
55
|
+
* On Android, native modals render above the root React view, so toasts from
|
|
56
|
+
* the main `<BreadLoaf />` won't be visible. Add `<ToastPortal />` inside your
|
|
57
|
+
* modal layouts to show toasts above modal content.
|
|
58
|
+
*
|
|
59
|
+
* This component only renders on Android - it returns `null` on iOS where
|
|
60
|
+
* `<BreadLoaf />` already handles modal overlay via `FullWindowOverlay`.
|
|
61
|
+
*
|
|
62
|
+
* This component only renders toasts - it does not accept configuration.
|
|
63
|
+
* All styling/behavior is inherited from your root `<BreadLoaf />` config.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```tsx
|
|
67
|
+
* // app/(modal)/_layout.tsx
|
|
68
|
+
* import { Stack } from 'expo-router';
|
|
69
|
+
* import { ToastPortal } from 'react-native-bread';
|
|
70
|
+
*
|
|
71
|
+
* export default function ModalLayout() {
|
|
72
|
+
* return (
|
|
73
|
+
* <>
|
|
74
|
+
* <Stack screenOptions={{ headerShown: false }} />
|
|
75
|
+
* <ToastPortal />
|
|
76
|
+
* </>
|
|
77
|
+
* );
|
|
78
|
+
* }
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
export declare function ToastPortal(): import("react/jsx-runtime").JSX.Element | null;
|
|
52
82
|
export {};
|
|
53
83
|
//# sourceMappingURL=toast-provider.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-bread",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "A lightweight toast library for React Native with premium feeling animations and complex gesture support",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"react-native-gesture-handler": "~2.28.0",
|
|
44
44
|
"react-native-reanimated": "~4.2.1",
|
|
45
45
|
"react-native-safe-area-context": "~5.4.0",
|
|
46
|
+
"react-native-screens": "~4.16.0",
|
|
46
47
|
"react-native-svg": "15.12.1",
|
|
47
48
|
"react-native-worklets": "0.7.2",
|
|
48
49
|
"terser": "^5.44.1",
|
|
@@ -54,6 +55,7 @@
|
|
|
54
55
|
"react-native-gesture-handler": ">=2.25.0",
|
|
55
56
|
"react-native-reanimated": ">=4.1.0",
|
|
56
57
|
"react-native-safe-area-context": ">=5.0.0",
|
|
58
|
+
"react-native-screens": ">=4.0.0",
|
|
57
59
|
"react-native-svg": ">=15.8.0",
|
|
58
60
|
"react-native-worklets": ">=0.5.0"
|
|
59
61
|
},
|
|
@@ -67,6 +69,9 @@
|
|
|
67
69
|
"react-native-safe-area-context": {
|
|
68
70
|
"optional": false
|
|
69
71
|
},
|
|
72
|
+
"react-native-screens": {
|
|
73
|
+
"optional": false
|
|
74
|
+
},
|
|
70
75
|
"react-native-svg": {
|
|
71
76
|
"optional": false
|
|
72
77
|
}
|