react-native-bread 0.1.0 → 0.1.2

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.
Files changed (69) hide show
  1. package/README.md +102 -84
  2. package/lib/commonjs/icons/CloseIcon.js +1 -22
  3. package/lib/commonjs/icons/GreenCheck.js +1 -27
  4. package/lib/commonjs/icons/InfoIcon.js +1 -24
  5. package/lib/commonjs/icons/RedX.js +1 -27
  6. package/lib/commonjs/icons/index.js +1 -34
  7. package/lib/commonjs/index.js +1 -59
  8. package/lib/commonjs/toast-api.js +1 -127
  9. package/lib/commonjs/toast-provider.js +1 -71
  10. package/lib/commonjs/toast-store.js +1 -278
  11. package/lib/commonjs/toast.js +1 -445
  12. package/lib/commonjs/types.js +1 -6
  13. package/lib/module/icons/CloseIcon.js +1 -16
  14. package/lib/module/icons/GreenCheck.js +1 -21
  15. package/lib/module/icons/InfoIcon.js +1 -18
  16. package/lib/module/icons/RedX.js +1 -21
  17. package/lib/module/icons/index.js +1 -7
  18. package/lib/module/index.js +1 -14
  19. package/lib/module/toast-api.js +1 -124
  20. package/lib/module/toast-provider.js +1 -67
  21. package/lib/module/toast-store.js +1 -274
  22. package/lib/module/toast.js +1 -439
  23. package/lib/module/types.js +1 -4
  24. package/lib/typescript/toast-provider.d.ts +13 -12
  25. package/package.json +7 -6
  26. package/lib/commonjs/icons/CloseIcon.js.map +0 -1
  27. package/lib/commonjs/icons/GreenCheck.js.map +0 -1
  28. package/lib/commonjs/icons/InfoIcon.js.map +0 -1
  29. package/lib/commonjs/icons/RedX.js.map +0 -1
  30. package/lib/commonjs/icons/index.js.map +0 -1
  31. package/lib/commonjs/index.js.map +0 -1
  32. package/lib/commonjs/toast-api.js.map +0 -1
  33. package/lib/commonjs/toast-provider.js.map +0 -1
  34. package/lib/commonjs/toast-store.js.map +0 -1
  35. package/lib/commonjs/toast.js.map +0 -1
  36. package/lib/commonjs/types.js.map +0 -1
  37. package/lib/module/icons/CloseIcon.js.map +0 -1
  38. package/lib/module/icons/GreenCheck.js.map +0 -1
  39. package/lib/module/icons/InfoIcon.js.map +0 -1
  40. package/lib/module/icons/RedX.js.map +0 -1
  41. package/lib/module/icons/index.js.map +0 -1
  42. package/lib/module/index.js.map +0 -1
  43. package/lib/module/toast-api.js.map +0 -1
  44. package/lib/module/toast-provider.js.map +0 -1
  45. package/lib/module/toast-store.js.map +0 -1
  46. package/lib/module/toast.js.map +0 -1
  47. package/lib/module/types.js.map +0 -1
  48. package/lib/typescript/icons/CloseIcon.d.ts.map +0 -1
  49. package/lib/typescript/icons/GreenCheck.d.ts.map +0 -1
  50. package/lib/typescript/icons/InfoIcon.d.ts.map +0 -1
  51. package/lib/typescript/icons/RedX.d.ts.map +0 -1
  52. package/lib/typescript/icons/index.d.ts.map +0 -1
  53. package/lib/typescript/index.d.ts.map +0 -1
  54. package/lib/typescript/toast-api.d.ts.map +0 -1
  55. package/lib/typescript/toast-provider.d.ts.map +0 -1
  56. package/lib/typescript/toast-store.d.ts.map +0 -1
  57. package/lib/typescript/toast.d.ts.map +0 -1
  58. package/lib/typescript/types.d.ts.map +0 -1
  59. package/src/icons/CloseIcon.tsx +0 -10
  60. package/src/icons/GreenCheck.tsx +0 -16
  61. package/src/icons/InfoIcon.tsx +0 -12
  62. package/src/icons/RedX.tsx +0 -16
  63. package/src/icons/index.ts +0 -4
  64. package/src/index.ts +0 -26
  65. package/src/toast-api.ts +0 -213
  66. package/src/toast-provider.tsx +0 -81
  67. package/src/toast-store.ts +0 -270
  68. package/src/toast.tsx +0 -417
  69. package/src/types.ts +0 -121
package/README.md CHANGED
@@ -1,55 +1,92 @@
1
- # 🍞 react-native-bread
1
+ # React Native Bread 🍞
2
2
 
3
- Drop-in toast notifications for React Native. Clean Sonner like API, buttery 60fps animations, swipe-to-dismiss, and fully customizable.
4
-
5
- ```tsx
6
- toast.success('Saved!'); // That's it. No hooks, no context.
7
- ```
3
+ An opinionated toast component for React Native. Inspired by @emilkowalski's Sonner, built for mobile with smooth 60fps animations and intuitive swipe gestures. Extremely lightweight.
8
4
 
5
+ https://github.com/user-attachments/assets/8a862dba-422c-4573-9f12-0a36cf6efe49
9
6
 
7
+ ## Features
10
8
 
11
- https://github.com/user-attachments/assets/8a862dba-422c-4573-9f12-0a36cf6efe49
9
+ - **Extremely lightweight** package, only 13.8KB packed size
10
+ - Clean, imperative API inspired by [Sonner](https://sonner.emilkowal.ski/)
11
+ - Zero setup - add one component, start toasting. No hooks, no providers
12
+ - Built for mobile with smooth 60fps animations via Reanimated 3
13
+ - Natural swipe gestures that feel native to the platform
14
+ - Multiple toast types: `success`, `error`, `info`, and `promise`
15
+ - Promise handling with automatic loading → success/error states
16
+ - Toast stacking with configurable limits
17
+ - Position toasts at top or bottom of screen
18
+ - Completely customizable - colors, icons, styles, animations
19
+ - Full Expo compatibility
20
+ - Imperative API works anywhere - components, utilities, event handlers
12
21
 
13
22
 
14
23
 
15
24
  ## Installation
16
25
 
17
- ```bash
26
+ ```sh
18
27
  bun add react-native-bread
19
- # or any package manager
20
28
  ```
21
29
 
22
- ### Peer Dependencies
30
+ #### Requirements
23
31
 
24
- You'll need these installed and configured in your project:
32
+ To use this package, **you also need to install its peer dependencies**. Check out their documentation for more information:
25
33
 
26
- ```bash
27
- bun add react-native-reanimated react-native-gesture-handler react-native-safe-area-context react-native-svg react-native-worklets
28
- ```
34
+ - [React Native Reanimated](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/getting-started)
35
+ - [React Native Gesture Handler](https://docs.swmansion.com/react-native-gesture-handler/docs/)
36
+ - [React Native Safe Area Context](https://docs.expo.dev/versions/latest/sdk/safe-area-context/)
37
+ - [React Native SVG](https://github.com/software-mansion/react-native-svg)
38
+ - [React Native Worklets](https://github.com/margelo/react-native-worklets-core)
29
39
 
30
40
 
31
- ## Quick Start
41
+ ## Usage
32
42
 
33
- Wrap your app with `<BreadLoaf>` and you're good to go:
43
+ ### In your App.tsx/entry point
34
44
 
35
45
  ```tsx
36
46
  import { BreadLoaf } from 'react-native-bread';
37
47
 
38
- export default function App() {
48
+ function App() {
39
49
  return (
40
- <BreadLoaf>
41
- <YourApp />
42
- </BreadLoaf>
50
+ <View>
51
+ <NavigationContainer>...</NavigationContainer>
52
+ <BreadLoaf />
53
+ </View>
43
54
  );
44
55
  }
45
56
  ```
46
57
 
47
- Then show toasts from anywhere:
58
+ ### Expo Router
59
+
60
+ When using Expo Router, place the `BreadLoaf` component in your root layout file (`app/_layout.tsx`):
61
+
62
+ ```tsx
63
+ import { BreadLoaf } from 'react-native-bread';
64
+ import { Stack } from 'expo-router';
65
+
66
+ export default function RootLayout() {
67
+ return (
68
+ <>
69
+ <Stack>
70
+ <Stack.Screen name="(tabs)" options={{ headerShown: false }} />
71
+ <Stack.Screen name="+not-found" />
72
+ </Stack>
73
+ <BreadLoaf />
74
+ </>
75
+ );
76
+ }
77
+ ```
78
+
79
+ This ensures the toasts will be displayed across all screens in your app.
80
+
81
+ ### Show a toast
48
82
 
49
83
  ```tsx
50
84
  import { toast } from 'react-native-bread';
51
85
 
52
- // Basic toasts
86
+ // Basic usage
87
+ toast.success('Saved!');
88
+
89
+ // With description
53
90
  toast.success('Saved!', 'Your changes have been saved');
54
91
  toast.error('Error', 'Something went wrong');
55
92
  toast.info('Tip', 'Swipe to dismiss');
@@ -62,87 +99,68 @@ toast.promise(fetchData(), {
62
99
  });
63
100
  ```
64
101
 
65
- ## API
66
-
67
- ### Toast Methods
68
-
69
- | Method | Description |
70
- |--------|-------------|
71
- | `toast.success(title, description?)` | Green checkmark toast |
72
- | `toast.error(title, description?)` | Red X toast |
73
- | `toast.info(title, description?)` | Yellow info toast |
74
- | `toast.promise(promise, messages)` | Loading → success/error toast |
75
- | `toast.dismiss(id)` | Dismiss a specific toast |
76
- | `toast.dismissAll()` | Dismiss all toasts |
102
+ ## Customization
77
103
 
78
104
  ### Per-Toast Options
79
105
 
80
- Instead of a description string, you can pass an options object as the second argument:
106
+ Pass an options object as the second argument to customize individual toasts:
81
107
 
82
108
  ```tsx
83
109
  toast.success('Saved!', {
84
110
  description: 'Your changes have been saved',
85
111
  duration: 5000,
86
112
  icon: <CustomIcon />,
113
+ style: { backgroundColor: '#fff' },
114
+ dismissible: true,
115
+ showCloseButton: true,
87
116
  });
88
117
  ```
89
118
 
90
- | Option | Type | Description |
91
- |--------|------|-------------|
92
- | `description` | `string` | Toast description text |
93
- | `duration` | `number` | Display time in ms |
94
- | `icon` | `ReactNode \| (props) => ReactNode` | Custom icon component |
95
- | `style` | `ViewStyle` | Toast container style overrides |
96
- | `titleStyle` | `TextStyle` | Title text style overrides |
97
- | `descriptionStyle` | `TextStyle` | Description text style overrides |
98
- | `dismissible` | `boolean` | Enable/disable swipe to dismiss |
99
- | `showCloseButton` | `boolean` | Show/hide the X button |
100
-
101
- ### BreadLoaf Config
119
+ ### Global Configuration
102
120
 
103
- Customize all toasts globally via the `config` prop:
121
+ Customize all toasts globally via the `config` prop on `<BreadLoaf />`:
104
122
 
105
123
  ```tsx
106
- <BreadLoaf config={{ position: 'bottom', stacking: false }}>
107
- <App />
108
- </BreadLoaf>
124
+ <BreadLoaf
125
+ config={{
126
+ position: 'bottom',
127
+ stacking: true,
128
+ maxStack: 3,
129
+ defaultDuration: 4000,
130
+ colors: {
131
+ success: { accent: '#22c55e', background: '#f0fdf4' },
132
+ error: { accent: '#ef4444', background: '#fef2f2' },
133
+ }
134
+ }}
135
+ />
109
136
  ```
110
137
 
111
- | Option | Type | Default | Description |
112
- |--------|------|---------|-------------|
113
- | `position` | `'top' \| 'bottom'` | `'top'` | Where toasts appear |
114
- | `offset` | `number` | `0` | Extra spacing from screen edge (px) |
115
- | `stacking` | `boolean` | `true` | Show multiple toasts stacked |
116
- | `maxStack` | `number` | `3` | Max visible toasts when stacking |
117
- | `dismissible` | `boolean` | `true` | Allow swipe to dismiss |
118
- | `showCloseButton` | `boolean` | `true` | Show X button (except loading toasts) |
119
- | `defaultDuration` | `number` | `4000` | Default display time (ms) |
120
- | `colors` | `object` | — | Colors per toast type (see below) |
121
- | `icons` | `object` | | Custom icons per toast type |
122
- | `toastStyle` | `ViewStyle` | — | Global toast container styles |
123
- | `titleStyle` | `TextStyle` | — | Global title text styles |
124
- | `descriptionStyle` | `TextStyle` | — | Global description text styles |
125
-
126
- #### Colors
127
-
128
- Each toast type (`success`, `error`, `info`, `loading`) accepts:
129
-
130
- | Property | Description |
131
- |----------|-------------|
132
- | `accent` | Icon and title color |
133
- | `background` | Toast background color |
138
+ Available options include:
139
+ - **position**: `'top' | 'bottom'` - Where toasts appear
140
+ - **offset**: Extra spacing from screen edge
141
+ - **stacking**: Show multiple toasts stacked
142
+ - **maxStack**: Max visible toasts when stacking
143
+ - **dismissible**: Allow swipe to dismiss
144
+ - **showCloseButton**: Show X button
145
+ - **defaultDuration**: Default display time in ms
146
+ - **colors**: Custom colors per toast type
147
+ - **icons**: Custom icons per toast type
148
+ - **toastStyle**, **titleStyle**, **descriptionStyle**: Global style overrides
134
149
 
135
- ```tsx
136
- colors: {
137
- success: { accent: '#22c55e', background: '#f0fdf4' },
138
- error: { accent: '#ef4444', background: '#fef2f2' },
139
- }
140
- ```
150
+ ## API Reference
151
+
152
+ | Method | Description |
153
+ |--------|-------------|
154
+ | `toast.success(title, description?)` | Show success toast |
155
+ | `toast.error(title, description?)` | Show error toast |
156
+ | `toast.info(title, description?)` | Show info toast |
157
+ | `toast.promise(promise, messages)` | Show loading → success/error toast |
158
+ | `toast.dismiss(id)` | Dismiss a specific toast |
159
+ | `toast.dismissAll()` | Dismiss all toasts |
141
160
 
142
- ## Known Limitations
161
+ ## Known Issues
143
162
 
144
- ### Toasts Behind Modals
163
+ **Modal Overlays**: Toasts may render behind React Native's `<Modal>` component since modals are mounted at the native layer.
145
164
 
146
- When you trigger a toast while opening a native modal (or transparent modal), the toast may appear **behind** the modal. This happens because React Native modals are mounted natively on top of everything.
165
+ **Solution**: Use absolute positioning within your component tree instead of `<Modal>` for better toast visibility.
147
166
 
148
- **Workaround**: Use a "contained" modal approach — render your modal content inside your regular component tree with absolute positioning, rather than using React Native's `<Modal>` component. This way toasts will appear on top as expected.
@@ -1,22 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.CloseIcon = void 0;
7
- var _reactNativeSvg = _interopRequireWildcard(require("react-native-svg"));
8
- var _jsxRuntime = require("react/jsx-runtime");
9
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
10
- const CloseIcon = props => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.default, {
11
- viewBox: "0 0 24 24",
12
- width: 24,
13
- height: 24,
14
- fill: "none",
15
- ...props,
16
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Path, {
17
- fill: props.fill ?? "#8993A4",
18
- d: "M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41Z"
19
- })
20
- });
21
- exports.CloseIcon = CloseIcon;
22
- //# sourceMappingURL=CloseIcon.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.CloseIcon=void 0;var e=function(e,t){if("function"==typeof WeakMap)var r=new WeakMap,n=new WeakMap;return function(e,t){if(!t&&e&&e.__esModule)return e;var o,i,f={__proto__:null,default:e};if(null===e||"object"!=typeof e&&"function"!=typeof e)return f;if(o=t?n:r){if(o.has(e))return o.get(e);o.set(e,f)}for(const t in e)"default"!==t&&{}.hasOwnProperty.call(e,t)&&((i=(o=Object.defineProperty)&&Object.getOwnPropertyDescriptor(e,t))&&(i.get||i.set)?o(f,t,i):f[t]=e[t]);return f}(e,t)}(require("react-native-svg")),t=require("react/jsx-runtime");exports.CloseIcon=r=>(0,t.jsx)(e.default,{viewBox:"0 0 24 24",width:24,height:24,fill:"none",...r,children:(0,t.jsx)(e.Path,{fill:r.fill??"#8993A4",d:"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41Z"})});
@@ -1,27 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.GreenCheck = void 0;
7
- var _reactNativeSvg = _interopRequireWildcard(require("react-native-svg"));
8
- var _jsxRuntime = require("react/jsx-runtime");
9
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
10
- const GreenCheck = props => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNativeSvg.default, {
11
- viewBox: "0 0 30 31",
12
- width: 30,
13
- height: 31,
14
- fill: "none",
15
- ...props,
16
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Path, {
17
- fill: props.fill ?? "#28B770",
18
- fillRule: "evenodd",
19
- d: "m19.866 13.152-5.772 5.773a.933.933 0 0 1-1.326 0L9.88 16.039a.938.938 0 0 1 1.325-1.327l2.225 2.224 5.109-5.11a.938.938 0 1 1 1.326 1.326Zm.28-9.652H9.602C5.654 3.5 3 6.276 3 10.409v9.935c0 4.131 2.654 6.906 6.602 6.906h10.543c3.95 0 6.605-2.775 6.605-6.906v-9.935c0-4.133-2.654-6.909-6.604-6.909Z",
20
- clipRule: "evenodd"
21
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Path, {
22
- fill: "#fff",
23
- d: "m19.866 13.152-5.772 5.773a.933.933 0 0 1-1.326 0L9.88 16.039a.938.938 0 0 1 1.325-1.327l2.225 2.224 5.109-5.11a.938.938 0 1 1 1.326 1.326Z"
24
- })]
25
- });
26
- exports.GreenCheck = GreenCheck;
27
- //# sourceMappingURL=GreenCheck.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.GreenCheck=void 0;var e=function(e,t){if("function"==typeof WeakMap)var r=new WeakMap,n=new WeakMap;return function(e,t){if(!t&&e&&e.__esModule)return e;var i,l,a={__proto__:null,default:e};if(null===e||"object"!=typeof e&&"function"!=typeof e)return a;if(i=t?n:r){if(i.has(e))return i.get(e);i.set(e,a)}for(const t in e)"default"!==t&&{}.hasOwnProperty.call(e,t)&&((l=(i=Object.defineProperty)&&Object.getOwnPropertyDescriptor(e,t))&&(l.get||l.set)?i(a,t,l):a[t]=e[t]);return a}(e,t)}(require("react-native-svg")),t=require("react/jsx-runtime");exports.GreenCheck=r=>(0,t.jsxs)(e.default,{viewBox:"0 0 30 31",width:30,height:31,fill:"none",...r,children:[(0,t.jsx)(e.Path,{fill:r.fill??"#28B770",fillRule:"evenodd",d:"m19.866 13.152-5.772 5.773a.933.933 0 0 1-1.326 0L9.88 16.039a.938.938 0 0 1 1.325-1.327l2.225 2.224 5.109-5.11a.938.938 0 1 1 1.326 1.326Zm.28-9.652H9.602C5.654 3.5 3 6.276 3 10.409v9.935c0 4.131 2.654 6.906 6.602 6.906h10.543c3.95 0 6.605-2.775 6.605-6.906v-9.935c0-4.133-2.654-6.909-6.604-6.909Z",clipRule:"evenodd"}),(0,t.jsx)(e.Path,{fill:"#fff",d:"m19.866 13.152-5.772 5.773a.933.933 0 0 1-1.326 0L9.88 16.039a.938.938 0 0 1 1.325-1.327l2.225 2.224 5.109-5.11a.938.938 0 1 1 1.326 1.326Z"})]});
@@ -1,24 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.InfoIcon = void 0;
7
- var _reactNativeSvg = _interopRequireWildcard(require("react-native-svg"));
8
- var _jsxRuntime = require("react/jsx-runtime");
9
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
10
- const InfoIcon = props => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.default, {
11
- viewBox: "0 0 24 24",
12
- width: 24,
13
- height: 24,
14
- fill: "none",
15
- ...props,
16
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Path, {
17
- fill: props.fill ?? "#EDBE43",
18
- fillRule: "evenodd",
19
- d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2Zm1 15h-2v-6h2v6Zm0-8h-2V7h2v2Z",
20
- clipRule: "evenodd"
21
- })
22
- });
23
- exports.InfoIcon = InfoIcon;
24
- //# sourceMappingURL=InfoIcon.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.InfoIcon=void 0;var e=function(e,t){if("function"==typeof WeakMap)var r=new WeakMap,n=new WeakMap;return function(e,t){if(!t&&e&&e.__esModule)return e;var o,i,f={__proto__:null,default:e};if(null===e||"object"!=typeof e&&"function"!=typeof e)return f;if(o=t?n:r){if(o.has(e))return o.get(e);o.set(e,f)}for(const t in e)"default"!==t&&{}.hasOwnProperty.call(e,t)&&((i=(o=Object.defineProperty)&&Object.getOwnPropertyDescriptor(e,t))&&(i.get||i.set)?o(f,t,i):f[t]=e[t]);return f}(e,t)}(require("react-native-svg")),t=require("react/jsx-runtime");exports.InfoIcon=r=>(0,t.jsx)(e.default,{viewBox:"0 0 24 24",width:24,height:24,fill:"none",...r,children:(0,t.jsx)(e.Path,{fill:r.fill??"#EDBE43",fillRule:"evenodd",d:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2Zm1 15h-2v-6h2v6Zm0-8h-2V7h2v2Z",clipRule:"evenodd"})});
@@ -1,27 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.RedX = void 0;
7
- var _reactNativeSvg = _interopRequireWildcard(require("react-native-svg"));
8
- var _jsxRuntime = require("react/jsx-runtime");
9
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
10
- const RedX = props => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNativeSvg.default, {
11
- viewBox: "0 0 24 24",
12
- width: 24,
13
- height: 24,
14
- fill: "none",
15
- ...props,
16
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Path, {
17
- fill: props.fill ?? "#F05964",
18
- fillRule: "evenodd",
19
- d: "M15.58 15.572a.935.935 0 0 1-1.326 0l-2.258-2.258-2.251 2.252a.938.938 0 0 1-1.326-1.325l2.251-2.252-2.252-2.254A.936.936 0 1 1 9.742 8.41l2.253 2.252 2.252-2.25a.939.939 0 0 1 1.325 1.325l-2.25 2.252 2.257 2.257a.938.938 0 0 1 0 1.326ZM17.271.126H6.727C2.777.125.125 2.9.125 7.032v9.936c0 4.13 2.652 6.907 6.603 6.907H17.27c3.95 0 6.605-2.776 6.605-6.907V7.032c0-4.132-2.654-6.907-6.604-6.907Z",
20
- clipRule: "evenodd"
21
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Path, {
22
- fill: "#fff",
23
- d: "M15.58 15.572a.935.935 0 0 1-1.326 0l-2.258-2.258-2.251 2.252a.938.938 0 0 1-1.326-1.325l2.251-2.252-2.252-2.254A.936.936 0 1 1 9.742 8.41l2.253 2.252 2.252-2.25a.939.939 0 0 1 1.325 1.325l-2.25 2.252 2.257 2.257a.938.938 0 0 1 0 1.326Z"
24
- })]
25
- });
26
- exports.RedX = RedX;
27
- //# sourceMappingURL=RedX.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.RedX=void 0;var e=function(e,t){if("function"==typeof WeakMap)var r=new WeakMap,l=new WeakMap;return function(e,t){if(!t&&e&&e.__esModule)return e;var n,a,i={__proto__:null,default:e};if(null===e||"object"!=typeof e&&"function"!=typeof e)return i;if(n=t?l:r){if(n.has(e))return n.get(e);n.set(e,i)}for(const t in e)"default"!==t&&{}.hasOwnProperty.call(e,t)&&((a=(n=Object.defineProperty)&&Object.getOwnPropertyDescriptor(e,t))&&(a.get||a.set)?n(i,t,a):i[t]=e[t]);return i}(e,t)}(require("react-native-svg")),t=require("react/jsx-runtime");exports.RedX=r=>(0,t.jsxs)(e.default,{viewBox:"0 0 24 24",width:24,height:24,fill:"none",...r,children:[(0,t.jsx)(e.Path,{fill:r.fill??"#F05964",fillRule:"evenodd",d:"M15.58 15.572a.935.935 0 0 1-1.326 0l-2.258-2.258-2.251 2.252a.938.938 0 0 1-1.326-1.325l2.251-2.252-2.252-2.254A.936.936 0 1 1 9.742 8.41l2.253 2.252 2.252-2.25a.939.939 0 0 1 1.325 1.325l-2.25 2.252 2.257 2.257a.938.938 0 0 1 0 1.326ZM17.271.126H6.727C2.777.125.125 2.9.125 7.032v9.936c0 4.13 2.652 6.907 6.603 6.907H17.27c3.95 0 6.605-2.776 6.605-6.907V7.032c0-4.132-2.654-6.907-6.604-6.907Z",clipRule:"evenodd"}),(0,t.jsx)(e.Path,{fill:"#fff",d:"M15.58 15.572a.935.935 0 0 1-1.326 0l-2.258-2.258-2.251 2.252a.938.938 0 0 1-1.326-1.325l2.251-2.252-2.252-2.254A.936.936 0 1 1 9.742 8.41l2.253 2.252 2.252-2.25a.939.939 0 0 1 1.325 1.325l-2.25 2.252 2.257 2.257a.938.938 0 0 1 0 1.326Z"})]});
@@ -1,34 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- Object.defineProperty(exports, "CloseIcon", {
7
- enumerable: true,
8
- get: function () {
9
- return _CloseIcon.CloseIcon;
10
- }
11
- });
12
- Object.defineProperty(exports, "GreenCheck", {
13
- enumerable: true,
14
- get: function () {
15
- return _GreenCheck.GreenCheck;
16
- }
17
- });
18
- Object.defineProperty(exports, "InfoIcon", {
19
- enumerable: true,
20
- get: function () {
21
- return _InfoIcon.InfoIcon;
22
- }
23
- });
24
- Object.defineProperty(exports, "RedX", {
25
- enumerable: true,
26
- get: function () {
27
- return _RedX.RedX;
28
- }
29
- });
30
- var _CloseIcon = require("./CloseIcon.js");
31
- var _GreenCheck = require("./GreenCheck.js");
32
- var _InfoIcon = require("./InfoIcon.js");
33
- var _RedX = require("./RedX.js");
34
- //# sourceMappingURL=index.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),Object.defineProperty(exports,"CloseIcon",{enumerable:!0,get:function(){return e.CloseIcon}}),Object.defineProperty(exports,"GreenCheck",{enumerable:!0,get:function(){return r.GreenCheck}}),Object.defineProperty(exports,"InfoIcon",{enumerable:!0,get:function(){return n.InfoIcon}}),Object.defineProperty(exports,"RedX",{enumerable:!0,get:function(){return t.RedX}});var e=require("./CloseIcon.js"),r=require("./GreenCheck.js"),n=require("./InfoIcon.js"),t=require("./RedX.js");
@@ -1,59 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- Object.defineProperty(exports, "BreadLoaf", {
7
- enumerable: true,
8
- get: function () {
9
- return _toastProvider.BreadLoaf;
10
- }
11
- });
12
- Object.defineProperty(exports, "CloseIcon", {
13
- enumerable: true,
14
- get: function () {
15
- return _index.CloseIcon;
16
- }
17
- });
18
- Object.defineProperty(exports, "GreenCheck", {
19
- enumerable: true,
20
- get: function () {
21
- return _index.GreenCheck;
22
- }
23
- });
24
- Object.defineProperty(exports, "InfoIcon", {
25
- enumerable: true,
26
- get: function () {
27
- return _index.InfoIcon;
28
- }
29
- });
30
- Object.defineProperty(exports, "RedX", {
31
- enumerable: true,
32
- get: function () {
33
- return _index.RedX;
34
- }
35
- });
36
- Object.defineProperty(exports, "ToastContainer", {
37
- enumerable: true,
38
- get: function () {
39
- return _toast.ToastContainer;
40
- }
41
- });
42
- Object.defineProperty(exports, "toast", {
43
- enumerable: true,
44
- get: function () {
45
- return _toastApi.toast;
46
- }
47
- });
48
- Object.defineProperty(exports, "toastStore", {
49
- enumerable: true,
50
- get: function () {
51
- return _toastStore.toastStore;
52
- }
53
- });
54
- var _index = require("./icons/index.js");
55
- var _toast = require("./toast.js");
56
- var _toastApi = require("./toast-api.js");
57
- var _toastProvider = require("./toast-provider.js");
58
- var _toastStore = require("./toast-store.js");
59
- //# sourceMappingURL=index.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),Object.defineProperty(exports,"BreadLoaf",{enumerable:!0,get:function(){return n.BreadLoaf}}),Object.defineProperty(exports,"CloseIcon",{enumerable:!0,get:function(){return e.CloseIcon}}),Object.defineProperty(exports,"GreenCheck",{enumerable:!0,get:function(){return e.GreenCheck}}),Object.defineProperty(exports,"InfoIcon",{enumerable:!0,get:function(){return e.InfoIcon}}),Object.defineProperty(exports,"RedX",{enumerable:!0,get:function(){return e.RedX}}),Object.defineProperty(exports,"ToastContainer",{enumerable:!0,get:function(){return t.ToastContainer}}),Object.defineProperty(exports,"toast",{enumerable:!0,get:function(){return r.toast}}),Object.defineProperty(exports,"toastStore",{enumerable:!0,get:function(){return o.toastStore}});var e=require("./icons/index.js"),t=require("./toast.js"),r=require("./toast-api.js"),n=require("./toast-provider.js"),o=require("./toast-store.js");
@@ -1,127 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.toast = void 0;
7
- var _toastStore = require("./toast-store.js");
8
- /** Second parameter can be a string (description) or options object */
9
-
10
- const _toast = (title, description, type, duration) => {
11
- _toastStore.toastStore.show(title, description, type, duration);
12
- };
13
-
14
- /** Helper to parse the second argument which can be string or options */
15
- const parseDescriptionOrOptions = arg => {
16
- if (!arg) return {};
17
- if (typeof arg === "string") return {
18
- description: arg
19
- };
20
- return {
21
- description: arg.description,
22
- duration: arg.duration,
23
- options: arg
24
- };
25
- };
26
- const parseMessage = input => typeof input === "string" ? {
27
- title: input
28
- } : input;
29
- const parseErrorMessage = (input, error) => {
30
- if (typeof input === "function") {
31
- return parseMessage(input(error));
32
- }
33
- return parseMessage(input);
34
- };
35
- const promiseToast = async (promise, messages) => {
36
- const loadingCfg = parseMessage(messages.loading);
37
-
38
- // Very long duration so it stays visible until we resolve/reject
39
- const toastId = _toastStore.toastStore.show(loadingCfg.title, loadingCfg.description, "loading", loadingCfg.duration ?? 60 * 60 * 1000);
40
- try {
41
- const result = await promise;
42
- const successCfg = parseMessage(messages.success);
43
- _toastStore.toastStore.updateToast(toastId, {
44
- title: successCfg.title,
45
- description: successCfg.description,
46
- type: "success",
47
- duration: successCfg.duration ?? 4000
48
- });
49
- return {
50
- data: result,
51
- success: true
52
- };
53
- } catch (err) {
54
- const error = err instanceof Error ? err : new Error(String(err));
55
- const errorCfg = parseErrorMessage(messages.error, error);
56
- _toastStore.toastStore.updateToast(toastId, {
57
- title: errorCfg.title,
58
- description: errorCfg.description,
59
- type: "error",
60
- duration: errorCfg.duration ?? 4000
61
- });
62
- return {
63
- error,
64
- success: false
65
- };
66
- }
67
- };
68
- // Build the toast API
69
- const toastFn = _toast;
70
- toastFn.success = (title, descriptionOrOptions, duration) => {
71
- const {
72
- description,
73
- duration: optDuration,
74
- options
75
- } = parseDescriptionOrOptions(descriptionOrOptions);
76
- _toastStore.toastStore.show(title, description, "success", duration ?? optDuration, options);
77
- };
78
- toastFn.error = (title, descriptionOrOptions, duration) => {
79
- const {
80
- description,
81
- duration: optDuration,
82
- options
83
- } = parseDescriptionOrOptions(descriptionOrOptions);
84
- _toastStore.toastStore.show(title, description, "error", duration ?? optDuration, options);
85
- };
86
- toastFn.info = (title, descriptionOrOptions, duration) => {
87
- const {
88
- description,
89
- duration: optDuration,
90
- options
91
- } = parseDescriptionOrOptions(descriptionOrOptions);
92
- _toastStore.toastStore.show(title, description, "info", duration ?? optDuration, options);
93
- };
94
- toastFn.promise = promiseToast;
95
- toastFn.dismiss = id => {
96
- _toastStore.toastStore.hide(id);
97
- };
98
- toastFn.dismissAll = () => {
99
- _toastStore.toastStore.hideAll();
100
- };
101
-
102
- /**
103
- * Toast API for showing notifications.
104
- *
105
- * @example
106
- * ```ts
107
- * import { toast } from 'react-native-bread';
108
- *
109
- * // Basic toasts
110
- * toast.success("Saved!", "Your changes have been saved");
111
- * toast.error("Error", "Something went wrong");
112
- * toast.info("Tip", "Swipe up to dismiss");
113
- *
114
- * // Promise toast (loading → success/error)
115
- * toast.promise(apiCall(), {
116
- * loading: { title: "Loading..." },
117
- * success: { title: "Done!" },
118
- * error: (err) => ({ title: "Failed", description: err.message }),
119
- * });
120
- *
121
- * // Dismiss toasts
122
- * toast.dismiss(id);
123
- * toast.dismissAll();
124
- * ```
125
- */
126
- const toast = exports.toast = toastFn;
127
- //# sourceMappingURL=toast-api.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.toast=void 0;var t=require("./toast-store.js");const o=t=>t?"string"==typeof t?{description:t}:{description:t.description,duration:t.duration,options:t}:{},s=t=>"string"==typeof t?{title:t}:t,r=(o,s,r,e)=>{t.toastStore.show(o,s,r,e)};r.success=(s,r,e)=>{const{description:i,duration:n,options:a}=o(r);t.toastStore.show(s,i,"success",e??n,a)},r.error=(s,r,e)=>{const{description:i,duration:n,options:a}=o(r);t.toastStore.show(s,i,"error",e??n,a)},r.info=(s,r,e)=>{const{description:i,duration:n,options:a}=o(r);t.toastStore.show(s,i,"info",e??n,a)},r.promise=async(o,r)=>{const e=s(r.loading),i=t.toastStore.show(e.title,e.description,"loading",e.duration??36e5);try{const e=await o,n=s(r.success);return t.toastStore.updateToast(i,{title:n.title,description:n.description,type:"success",duration:n.duration??4e3}),{data:e,success:!0}}catch(o){const e=o instanceof Error?o:new Error(String(o)),n=((t,o)=>s("function"==typeof t?t(o):t))(r.error,e);return t.toastStore.updateToast(i,{title:n.title,description:n.description,type:"error",duration:n.duration??4e3}),{error:e,success:!1}}},r.dismiss=o=>{t.toastStore.hide(o)},r.dismissAll=()=>{t.toastStore.hideAll()};exports.toast=r;
@@ -1,71 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.BreadLoaf = BreadLoaf;
7
- var _react = require("react");
8
- var _reactNative = require("react-native");
9
- var _toast = require("./toast.js");
10
- var _toastStore = require("./toast-store.js");
11
- var _jsxRuntime = require("react/jsx-runtime");
12
- /**
13
- * Toast provider component that enables toast notifications in your app.
14
- * Wrap your root component with `<BreadLoaf>` to start showing toasts.
15
- *
16
- * @example
17
- * ```tsx
18
- * import { BreadLoaf } from 'react-native-bread';
19
- *
20
- * // Basic usage
21
- * <BreadLoaf>
22
- * <App />
23
- * </BreadLoaf>
24
- *
25
- * // With configuration
26
- * <BreadLoaf
27
- * config={{
28
- * position: 'bottom',
29
- * stacking: false,
30
- * defaultDuration: 5000,
31
- * colors: {
32
- * success: { accent: '#22c55e', background: '#f0fdf4' },
33
- * error: { accent: '#ef4444', background: '#fef2f2' },
34
- * },
35
- * toastStyle: { borderRadius: 12 },
36
- * }}
37
- * >
38
- * <App />
39
- * </BreadLoaf>
40
- * ```
41
- */
42
- function BreadLoaf({
43
- children,
44
- config
45
- }) {
46
- (0, _react.useEffect)(() => {
47
- _toastStore.toastStore.setConfig(config);
48
- return () => {
49
- // Reset to defaults when this provider unmounts
50
- _toastStore.toastStore.setConfig(undefined);
51
- };
52
- }, [config]);
53
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
54
- style: styles.root,
55
- children: [children, /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
56
- style: styles.portalContainer,
57
- pointerEvents: "box-none",
58
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_toast.ToastContainer, {})
59
- })]
60
- });
61
- }
62
- const styles = _reactNative.StyleSheet.create({
63
- root: {
64
- flex: 1
65
- },
66
- portalContainer: {
67
- ..._reactNative.StyleSheet.absoluteFillObject,
68
- zIndex: 9999
69
- }
70
- });
71
- //# sourceMappingURL=toast-provider.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.BreadLoaf=function({config:i}){return(0,e.useEffect)(()=>(o.toastStore.setConfig(i),()=>{o.toastStore.setConfig(void 0)}),[i]),(0,s.jsx)(t.View,{style:n.container,pointerEvents:"box-none",children:(0,s.jsx)(r.ToastContainer,{})})};var e=require("react"),t=require("react-native"),r=require("./toast.js"),o=require("./toast-store.js"),s=require("react/jsx-runtime");const n=t.StyleSheet.create({container:{...t.StyleSheet.absoluteFillObject,zIndex:9999}});