react-native-bread 0.1.0
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 +148 -0
- package/lib/commonjs/icons/CloseIcon.js +22 -0
- package/lib/commonjs/icons/CloseIcon.js.map +1 -0
- package/lib/commonjs/icons/GreenCheck.js +27 -0
- package/lib/commonjs/icons/GreenCheck.js.map +1 -0
- package/lib/commonjs/icons/InfoIcon.js +24 -0
- package/lib/commonjs/icons/InfoIcon.js.map +1 -0
- package/lib/commonjs/icons/RedX.js +27 -0
- package/lib/commonjs/icons/RedX.js.map +1 -0
- package/lib/commonjs/icons/index.js +34 -0
- package/lib/commonjs/icons/index.js.map +1 -0
- package/lib/commonjs/index.js +59 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/toast-api.js +127 -0
- package/lib/commonjs/toast-api.js.map +1 -0
- package/lib/commonjs/toast-provider.js +71 -0
- package/lib/commonjs/toast-provider.js.map +1 -0
- package/lib/commonjs/toast-store.js +278 -0
- package/lib/commonjs/toast-store.js.map +1 -0
- package/lib/commonjs/toast.js +445 -0
- package/lib/commonjs/toast.js.map +1 -0
- package/lib/commonjs/types.js +6 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/module/icons/CloseIcon.js +16 -0
- package/lib/module/icons/CloseIcon.js.map +1 -0
- package/lib/module/icons/GreenCheck.js +21 -0
- package/lib/module/icons/GreenCheck.js.map +1 -0
- package/lib/module/icons/InfoIcon.js +18 -0
- package/lib/module/icons/InfoIcon.js.map +1 -0
- package/lib/module/icons/RedX.js +21 -0
- package/lib/module/icons/RedX.js.map +1 -0
- package/lib/module/icons/index.js +7 -0
- package/lib/module/icons/index.js.map +1 -0
- package/lib/module/index.js +14 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/toast-api.js +124 -0
- package/lib/module/toast-api.js.map +1 -0
- package/lib/module/toast-provider.js +67 -0
- package/lib/module/toast-provider.js.map +1 -0
- package/lib/module/toast-store.js +274 -0
- package/lib/module/toast-store.js.map +1 -0
- package/lib/module/toast.js +439 -0
- package/lib/module/toast.js.map +1 -0
- package/lib/module/types.js +4 -0
- package/lib/module/types.js.map +1 -0
- package/lib/typescript/icons/CloseIcon.d.ts +3 -0
- package/lib/typescript/icons/CloseIcon.d.ts.map +1 -0
- package/lib/typescript/icons/GreenCheck.d.ts +3 -0
- package/lib/typescript/icons/GreenCheck.d.ts.map +1 -0
- package/lib/typescript/icons/InfoIcon.d.ts +3 -0
- package/lib/typescript/icons/InfoIcon.d.ts.map +1 -0
- package/lib/typescript/icons/RedX.d.ts +3 -0
- package/lib/typescript/icons/RedX.d.ts.map +1 -0
- package/lib/typescript/icons/index.d.ts +5 -0
- package/lib/typescript/icons/index.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +7 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/toast-api.d.ts +109 -0
- package/lib/typescript/toast-api.d.ts.map +1 -0
- package/lib/typescript/toast-provider.d.ts +52 -0
- package/lib/typescript/toast-provider.d.ts.map +1 -0
- package/lib/typescript/toast-store.d.ts +26 -0
- package/lib/typescript/toast-store.d.ts.map +1 -0
- package/lib/typescript/toast.d.ts +2 -0
- package/lib/typescript/toast.d.ts.map +1 -0
- package/lib/typescript/types.d.ts +101 -0
- package/lib/typescript/types.d.ts.map +1 -0
- package/package.json +87 -0
- package/src/icons/CloseIcon.tsx +10 -0
- package/src/icons/GreenCheck.tsx +16 -0
- package/src/icons/InfoIcon.tsx +12 -0
- package/src/icons/RedX.tsx +16 -0
- package/src/icons/index.ts +4 -0
- package/src/index.ts +26 -0
- package/src/toast-api.ts +213 -0
- package/src/toast-provider.tsx +81 -0
- package/src/toast-store.ts +270 -0
- package/src/toast.tsx +417 -0
- package/src/types.ts +121 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { ToastConfig } from "./types";
|
|
3
|
+
interface BreadLoafProps {
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
/**
|
|
6
|
+
* Configuration for customizing toast behavior and appearance.
|
|
7
|
+
* All properties are optional and will be merged with defaults.
|
|
8
|
+
*
|
|
9
|
+
* @property position - Where toasts appear: `'top'` (default) or `'bottom'`
|
|
10
|
+
* @property offset - Extra spacing from screen edge in pixels (default: `0`)
|
|
11
|
+
* @property stacking - Show multiple toasts stacked (default: `true`). When `false`, only one toast shows at a time
|
|
12
|
+
* @property defaultDuration - Default display time in ms (default: `4000`)
|
|
13
|
+
* @property colors - Customize colors per toast type (`success`, `error`, `info`, `loading`)
|
|
14
|
+
* @property toastStyle - Style overrides for the toast container (borderRadius, shadow, padding, etc.)
|
|
15
|
+
* @property titleStyle - Style overrides for the title text
|
|
16
|
+
* @property descriptionStyle - Style overrides for the description text
|
|
17
|
+
*/
|
|
18
|
+
config?: ToastConfig;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Toast provider component that enables toast notifications in your app.
|
|
22
|
+
* Wrap your root component with `<BreadLoaf>` to start showing toasts.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```tsx
|
|
26
|
+
* import { BreadLoaf } from 'react-native-bread';
|
|
27
|
+
*
|
|
28
|
+
* // Basic usage
|
|
29
|
+
* <BreadLoaf>
|
|
30
|
+
* <App />
|
|
31
|
+
* </BreadLoaf>
|
|
32
|
+
*
|
|
33
|
+
* // With configuration
|
|
34
|
+
* <BreadLoaf
|
|
35
|
+
* config={{
|
|
36
|
+
* position: 'bottom',
|
|
37
|
+
* stacking: false,
|
|
38
|
+
* defaultDuration: 5000,
|
|
39
|
+
* colors: {
|
|
40
|
+
* success: { accent: '#22c55e', background: '#f0fdf4' },
|
|
41
|
+
* error: { accent: '#ef4444', background: '#fef2f2' },
|
|
42
|
+
* },
|
|
43
|
+
* toastStyle: { borderRadius: 12 },
|
|
44
|
+
* }}
|
|
45
|
+
* >
|
|
46
|
+
* <App />
|
|
47
|
+
* </BreadLoaf>
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare function BreadLoaf({ children, config }: BreadLoafProps): import("react/jsx-runtime").JSX.Element;
|
|
51
|
+
export {};
|
|
52
|
+
//# sourceMappingURL=toast-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toast-provider.d.ts","sourceRoot":"","sources":["../../src/toast-provider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAa,MAAM,OAAO,CAAC;AAIlD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C,UAAU,cAAc;IACtB,QAAQ,EAAE,SAAS,CAAC;IACpB;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,SAAS,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,cAAc,2CAgB7D"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Toast, ToastConfig, ToastOptions, ToastState, ToastTheme, ToastType } from "./types";
|
|
2
|
+
export type Listener = (state: ToastState) => void;
|
|
3
|
+
declare class ToastStore {
|
|
4
|
+
private state;
|
|
5
|
+
private theme;
|
|
6
|
+
private listeners;
|
|
7
|
+
private toastIdCounter;
|
|
8
|
+
private timeouts;
|
|
9
|
+
subscribe: (listener: Listener) => () => void;
|
|
10
|
+
private emit;
|
|
11
|
+
private setState;
|
|
12
|
+
getState: () => ToastState;
|
|
13
|
+
getTheme: () => ToastTheme;
|
|
14
|
+
setConfig: (config: ToastConfig | undefined) => void;
|
|
15
|
+
show: (title: string, description?: string, type?: ToastType, duration?: number, options?: ToastOptions) => string;
|
|
16
|
+
private addToast;
|
|
17
|
+
private scheduleTimeout;
|
|
18
|
+
private rescheduleAllTimeouts;
|
|
19
|
+
hide: (id: string) => void;
|
|
20
|
+
private removeToast;
|
|
21
|
+
updateToast: (id: string, data: Partial<Omit<Toast, "id" | "createdAt">>) => void;
|
|
22
|
+
hideAll: () => void;
|
|
23
|
+
}
|
|
24
|
+
export declare const toastStore: ToastStore;
|
|
25
|
+
export type { Toast, ToastState, ToastType };
|
|
26
|
+
//# sourceMappingURL=toast-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toast-store.d.ts","sourceRoot":"","sources":["../../src/toast-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAmB,MAAM,SAAS,CAAC;AAEpH,MAAM,MAAM,QAAQ,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;AA0DnD,cAAM,UAAU;IACd,OAAO,CAAC,KAAK,CAEX;IAEF,OAAO,CAAC,KAAK,CAA6B;IAE1C,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,QAAQ,CAAoD;IAEpE,SAAS,GAAI,UAAU,QAAQ,gBAK7B;IAEF,OAAO,CAAC,IAAI;IAMZ,OAAO,CAAC,QAAQ;IAKhB,QAAQ,mBAAoB;IAE5B,QAAQ,mBAAoB;IAE5B,SAAS,GAAI,QAAQ,WAAW,GAAG,SAAS,UAE1C;IAEF,IAAI,GACF,OAAO,MAAM,EACb,cAAc,MAAM,EACpB,OAAM,SAAqB,EAC3B,WAAW,MAAM,EACjB,UAAU,YAAY,KACrB,MAAM,CA8DP;IAEF,OAAO,CAAC,QAAQ;IAYhB,OAAO,CAAC,eAAe;IAgBvB,OAAO,CAAC,qBAAqB;IAW7B,IAAI,GAAI,IAAI,MAAM,UAqBhB;IAEF,OAAO,CAAC,WAAW;IAenB,WAAW,GAAI,IAAI,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,GAAG,WAAW,CAAC,CAAC,UAYvE;IAEF,OAAO,aAML;CACH;AAED,eAAO,MAAM,UAAU,YAAmB,CAAC;AAE3C,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toast.d.ts","sourceRoot":"","sources":["../../src/toast.tsx"],"names":[],"mappings":"AAkFA,eAAO,MAAM,cAAc,sDAgD1B,CAAC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type { TextStyle, ViewStyle } from "react-native";
|
|
3
|
+
export type ToastType = "success" | "error" | "info" | "loading";
|
|
4
|
+
export type ToastPosition = "top" | "bottom";
|
|
5
|
+
export interface ToastTypeColors {
|
|
6
|
+
/** Accent color used for title text and icons */
|
|
7
|
+
accent: string;
|
|
8
|
+
/** Background color of the toast */
|
|
9
|
+
background: string;
|
|
10
|
+
}
|
|
11
|
+
/** Props passed to custom icon render functions */
|
|
12
|
+
export interface IconProps {
|
|
13
|
+
/** The accent color from the theme for this toast type */
|
|
14
|
+
color: string;
|
|
15
|
+
/** Default icon size */
|
|
16
|
+
size: number;
|
|
17
|
+
}
|
|
18
|
+
/** Custom icon render function */
|
|
19
|
+
export type IconRenderFn = (props: IconProps) => ReactNode;
|
|
20
|
+
export interface ToastTheme {
|
|
21
|
+
/** Position of toasts on screen */
|
|
22
|
+
position: ToastPosition;
|
|
23
|
+
/** Extra offset from safe area edge (in addition to safe area insets) */
|
|
24
|
+
offset: number;
|
|
25
|
+
/** Whether to show multiple toasts stacked (default: true). When false, only one toast shows at a time. */
|
|
26
|
+
stacking: boolean;
|
|
27
|
+
/** Maximum number of toasts visible at once when stacking is enabled (default: 3) */
|
|
28
|
+
maxStack: number;
|
|
29
|
+
/** Whether toasts can be dismissed via swipe gesture (default: true) */
|
|
30
|
+
dismissible: boolean;
|
|
31
|
+
/** Whether to show the close button on toasts (default: true). Loading toasts never show close button. */
|
|
32
|
+
showCloseButton: boolean;
|
|
33
|
+
/** Colors for each toast type */
|
|
34
|
+
colors: Record<ToastType, ToastTypeColors>;
|
|
35
|
+
/** Custom icons for each toast type */
|
|
36
|
+
icons: Partial<Record<ToastType, IconRenderFn>>;
|
|
37
|
+
/** Style overrides for the toast container */
|
|
38
|
+
toastStyle: ViewStyle;
|
|
39
|
+
/** Style overrides for the title text */
|
|
40
|
+
titleStyle: TextStyle;
|
|
41
|
+
/** Style overrides for the description text */
|
|
42
|
+
descriptionStyle: TextStyle;
|
|
43
|
+
/** Default duration in ms for toasts (default: 4000) */
|
|
44
|
+
defaultDuration: number;
|
|
45
|
+
}
|
|
46
|
+
/** Per-toast options for customizing individual toasts */
|
|
47
|
+
export interface ToastOptions {
|
|
48
|
+
/** Description text */
|
|
49
|
+
description?: string;
|
|
50
|
+
/** Duration in ms (overrides default) */
|
|
51
|
+
duration?: number;
|
|
52
|
+
/** Custom icon (ReactNode or render function) */
|
|
53
|
+
icon?: ReactNode | IconRenderFn;
|
|
54
|
+
/** Style overrides for this toast's container */
|
|
55
|
+
style?: ViewStyle;
|
|
56
|
+
/** Style overrides for this toast's title */
|
|
57
|
+
titleStyle?: TextStyle;
|
|
58
|
+
/** Style overrides for this toast's description */
|
|
59
|
+
descriptionStyle?: TextStyle;
|
|
60
|
+
/** Whether this toast can be dismissed via swipe (overrides config) */
|
|
61
|
+
dismissible?: boolean;
|
|
62
|
+
/** Whether to show the close button on this toast (overrides config) */
|
|
63
|
+
showCloseButton?: boolean;
|
|
64
|
+
}
|
|
65
|
+
/** Configuration options for customizing toast behavior and appearance. All properties are optional. */
|
|
66
|
+
export type ToastConfig = {
|
|
67
|
+
[K in keyof ToastTheme]?: K extends "colors" ? Partial<Record<ToastType, Partial<ToastTypeColors>>> : K extends "icons" ? Partial<Record<ToastType, IconRenderFn>> : ToastTheme[K];
|
|
68
|
+
};
|
|
69
|
+
export interface Toast {
|
|
70
|
+
id: string;
|
|
71
|
+
title: string;
|
|
72
|
+
description?: string;
|
|
73
|
+
type: ToastType;
|
|
74
|
+
duration: number;
|
|
75
|
+
createdAt: number;
|
|
76
|
+
isExiting?: boolean;
|
|
77
|
+
/** Per-toast style/icon overrides */
|
|
78
|
+
options?: ToastOptions;
|
|
79
|
+
}
|
|
80
|
+
export interface ToastState {
|
|
81
|
+
/** Visible toasts (index 0 = front/newest) */
|
|
82
|
+
visibleToasts: Toast[];
|
|
83
|
+
}
|
|
84
|
+
export type MessageInput = string | {
|
|
85
|
+
title: string;
|
|
86
|
+
description?: string;
|
|
87
|
+
/** Override duration (ms) after promise settles */
|
|
88
|
+
duration?: number;
|
|
89
|
+
};
|
|
90
|
+
export type ErrorMessageInput = MessageInput | ((error: Error) => MessageInput);
|
|
91
|
+
export interface PromiseMessages {
|
|
92
|
+
loading: MessageInput;
|
|
93
|
+
success: MessageInput;
|
|
94
|
+
error: ErrorMessageInput;
|
|
95
|
+
}
|
|
96
|
+
export interface PromiseResult<T> {
|
|
97
|
+
data?: T;
|
|
98
|
+
error?: Error;
|
|
99
|
+
success: boolean;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzD,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;AAEjE,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,QAAQ,CAAC;AAE7C,MAAM,WAAW,eAAe;IAC9B,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,mDAAmD;AACnD,MAAM,WAAW,SAAS;IACxB,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,kCAAkC;AAClC,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,SAAS,KAAK,SAAS,CAAC;AAE3D,MAAM,WAAW,UAAU;IACzB,mCAAmC;IACnC,QAAQ,EAAE,aAAa,CAAC;IACxB,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAC;IACf,2GAA2G;IAC3G,QAAQ,EAAE,OAAO,CAAC;IAClB,qFAAqF;IACrF,QAAQ,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,WAAW,EAAE,OAAO,CAAC;IACrB,0GAA0G;IAC1G,eAAe,EAAE,OAAO,CAAC;IACzB,iCAAiC;IACjC,MAAM,EAAE,MAAM,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;IAC3C,uCAAuC;IACvC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC,CAAC;IAChD,8CAA8C;IAC9C,UAAU,EAAE,SAAS,CAAC;IACtB,yCAAyC;IACzC,UAAU,EAAE,SAAS,CAAC;IACtB,+CAA+C;IAC/C,gBAAgB,EAAE,SAAS,CAAC;IAC5B,wDAAwD;IACxD,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,0DAA0D;AAC1D,MAAM,WAAW,YAAY;IAC3B,uBAAuB;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,IAAI,CAAC,EAAE,SAAS,GAAG,YAAY,CAAC;IAChC,iDAAiD;IACjD,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,mDAAmD;IACnD,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAC7B,uEAAuE;IACvE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,wEAAwE;IACxE,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,wGAAwG;AACxG,MAAM,MAAM,WAAW,GAAG;KACvB,CAAC,IAAI,MAAM,UAAU,CAAC,CAAC,EAAE,CAAC,SAAS,QAAQ,GACxC,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,GACpD,CAAC,SAAS,OAAO,GACf,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC,GACxC,UAAU,CAAC,CAAC,CAAC;CACpB,CAAC;AAEF,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,qCAAqC;IACrC,OAAO,CAAC,EAAE,YAAY,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,8CAA8C;IAC9C,aAAa,EAAE,KAAK,EAAE,CAAC;CACxB;AAGD,MAAM,MAAM,YAAY,GACpB,MAAM,GACN;IACE,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEN,MAAM,MAAM,iBAAiB,GAAG,YAAY,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,YAAY,CAAC,CAAC;AAEhF,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,YAAY,CAAC;IACtB,OAAO,EAAE,YAAY,CAAC;IACtB,KAAK,EAAE,iBAAiB,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;CAClB"}
|
package/package.json
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "react-native-bread",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A delicious toast library for React Native with beautiful animations and gesture support",
|
|
5
|
+
"main": "lib/commonjs/index.js",
|
|
6
|
+
"module": "lib/module/index.js",
|
|
7
|
+
"types": "lib/typescript/index.d.ts",
|
|
8
|
+
"react-native": "src/index.ts",
|
|
9
|
+
"source": "src/index.ts",
|
|
10
|
+
"files": ["src", "lib", "!**/__tests__", "!**/__fixtures__", "!**/__mocks__"],
|
|
11
|
+
"sideEffects": false,
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://github.com/AlshehriAli0/react-native-bread.git"
|
|
15
|
+
},
|
|
16
|
+
"author": "Ali <ali0fawzish@outlook.com>",
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/AlshehriAli0/react-native-bread/issues"
|
|
20
|
+
},
|
|
21
|
+
"homepage": "https://github.com/AlshehriAli0/react-native-bread#readme",
|
|
22
|
+
"keywords": ["react-native", "toast", "notification", "snackbar", "bread", "animation", "gesture", "reanimated"],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "bob build",
|
|
25
|
+
"typecheck": "tsc --noEmit",
|
|
26
|
+
"clean": "rm -rf lib",
|
|
27
|
+
"prepare": "bob build"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"react": "19.1.0",
|
|
31
|
+
"react-native": "0.81.5",
|
|
32
|
+
"react-native-builder-bob": "^0.35.2",
|
|
33
|
+
"react-native-gesture-handler": "~2.28.0",
|
|
34
|
+
"react-native-reanimated": "~4.1.1",
|
|
35
|
+
"react-native-safe-area-context": "~5.4.0",
|
|
36
|
+
"react-native-worklets": "0.5.1",
|
|
37
|
+
"react-native-svg": "15.12.1",
|
|
38
|
+
"typescript": "~5.9.2"
|
|
39
|
+
},
|
|
40
|
+
"peerDependencies": {
|
|
41
|
+
"react": ">=18.0.0",
|
|
42
|
+
"react-native": ">=0.76.0",
|
|
43
|
+
"react-native-gesture-handler": ">=2.0.0",
|
|
44
|
+
"react-native-reanimated": ">=4.0.0",
|
|
45
|
+
"react-native-safe-area-context": ">=4.0.0",
|
|
46
|
+
"react-native-svg": ">=14.0.0",
|
|
47
|
+
"react-native-worklets": ">=0.4.0"
|
|
48
|
+
},
|
|
49
|
+
"peerDependenciesMeta": {
|
|
50
|
+
"react-native-gesture-handler": {
|
|
51
|
+
"optional": false
|
|
52
|
+
},
|
|
53
|
+
"react-native-reanimated": {
|
|
54
|
+
"optional": false
|
|
55
|
+
},
|
|
56
|
+
"react-native-safe-area-context": {
|
|
57
|
+
"optional": false
|
|
58
|
+
},
|
|
59
|
+
"react-native-svg": {
|
|
60
|
+
"optional": false
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"react-native-builder-bob": {
|
|
64
|
+
"source": "src",
|
|
65
|
+
"output": "lib",
|
|
66
|
+
"targets": [
|
|
67
|
+
[
|
|
68
|
+
"commonjs",
|
|
69
|
+
{
|
|
70
|
+
"esm": true
|
|
71
|
+
}
|
|
72
|
+
],
|
|
73
|
+
[
|
|
74
|
+
"module",
|
|
75
|
+
{
|
|
76
|
+
"esm": true
|
|
77
|
+
}
|
|
78
|
+
],
|
|
79
|
+
[
|
|
80
|
+
"typescript",
|
|
81
|
+
{
|
|
82
|
+
"project": "tsconfig.build.json"
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import Svg, { Path, type SvgProps } from "react-native-svg";
|
|
2
|
+
|
|
3
|
+
export const CloseIcon = (props: SvgProps) => (
|
|
4
|
+
<Svg viewBox="0 0 24 24" width={24} height={24} fill="none" {...props}>
|
|
5
|
+
<Path
|
|
6
|
+
fill={props.fill ?? "#8993A4"}
|
|
7
|
+
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"
|
|
8
|
+
/>
|
|
9
|
+
</Svg>
|
|
10
|
+
);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import Svg, { Path, type SvgProps } from "react-native-svg";
|
|
2
|
+
|
|
3
|
+
export const GreenCheck = (props: SvgProps) => (
|
|
4
|
+
<Svg viewBox="0 0 30 31" width={30} height={31} fill="none" {...props}>
|
|
5
|
+
<Path
|
|
6
|
+
fill={props.fill ?? "#28B770"}
|
|
7
|
+
fillRule="evenodd"
|
|
8
|
+
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"
|
|
9
|
+
clipRule="evenodd"
|
|
10
|
+
/>
|
|
11
|
+
<Path
|
|
12
|
+
fill="#fff"
|
|
13
|
+
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"
|
|
14
|
+
/>
|
|
15
|
+
</Svg>
|
|
16
|
+
);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import Svg, { Path, type SvgProps } from "react-native-svg";
|
|
2
|
+
|
|
3
|
+
export const InfoIcon = (props: SvgProps) => (
|
|
4
|
+
<Svg viewBox="0 0 24 24" width={24} height={24} fill="none" {...props}>
|
|
5
|
+
<Path
|
|
6
|
+
fill={props.fill ?? "#EDBE43"}
|
|
7
|
+
fillRule="evenodd"
|
|
8
|
+
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"
|
|
9
|
+
clipRule="evenodd"
|
|
10
|
+
/>
|
|
11
|
+
</Svg>
|
|
12
|
+
);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import Svg, { Path, type SvgProps } from "react-native-svg";
|
|
2
|
+
|
|
3
|
+
export const RedX = (props: SvgProps) => (
|
|
4
|
+
<Svg viewBox="0 0 24 24" width={24} height={24} fill="none" {...props}>
|
|
5
|
+
<Path
|
|
6
|
+
fill={props.fill ?? "#F05964"}
|
|
7
|
+
fillRule="evenodd"
|
|
8
|
+
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"
|
|
9
|
+
clipRule="evenodd"
|
|
10
|
+
/>
|
|
11
|
+
<Path
|
|
12
|
+
fill="#fff"
|
|
13
|
+
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"
|
|
14
|
+
/>
|
|
15
|
+
</Svg>
|
|
16
|
+
);
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Main exports
|
|
2
|
+
|
|
3
|
+
// Icons (for customization)
|
|
4
|
+
export { CloseIcon, GreenCheck, InfoIcon, RedX } from "./icons";
|
|
5
|
+
export { ToastContainer } from "./toast";
|
|
6
|
+
export { toast } from "./toast-api";
|
|
7
|
+
export { BreadLoaf } from "./toast-provider";
|
|
8
|
+
|
|
9
|
+
// Store (for advanced usage)
|
|
10
|
+
export { toastStore } from "./toast-store";
|
|
11
|
+
// Types
|
|
12
|
+
export type {
|
|
13
|
+
ErrorMessageInput,
|
|
14
|
+
IconProps,
|
|
15
|
+
IconRenderFn,
|
|
16
|
+
MessageInput,
|
|
17
|
+
PromiseMessages,
|
|
18
|
+
PromiseResult,
|
|
19
|
+
Toast,
|
|
20
|
+
ToastConfig,
|
|
21
|
+
ToastOptions,
|
|
22
|
+
ToastPosition,
|
|
23
|
+
ToastState,
|
|
24
|
+
ToastType,
|
|
25
|
+
ToastTypeColors,
|
|
26
|
+
} from "./types";
|
package/src/toast-api.ts
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { toastStore } from "./toast-store";
|
|
2
|
+
import type {
|
|
3
|
+
ErrorMessageInput,
|
|
4
|
+
MessageInput,
|
|
5
|
+
PromiseMessages,
|
|
6
|
+
PromiseResult,
|
|
7
|
+
ToastOptions,
|
|
8
|
+
ToastType,
|
|
9
|
+
} from "./types";
|
|
10
|
+
|
|
11
|
+
/** Second parameter can be a string (description) or options object */
|
|
12
|
+
type DescriptionOrOptions = string | ToastOptions;
|
|
13
|
+
|
|
14
|
+
const _toast = (title: string, description?: string, type?: ToastType, duration?: number) => {
|
|
15
|
+
toastStore.show(title, description, type, duration);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/** Helper to parse the second argument which can be string or options */
|
|
19
|
+
const parseDescriptionOrOptions = (
|
|
20
|
+
arg?: DescriptionOrOptions
|
|
21
|
+
): { description?: string; duration?: number; options?: ToastOptions } => {
|
|
22
|
+
if (!arg) return {};
|
|
23
|
+
if (typeof arg === "string") return { description: arg };
|
|
24
|
+
return {
|
|
25
|
+
description: arg.description,
|
|
26
|
+
duration: arg.duration,
|
|
27
|
+
options: arg,
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const parseMessage = (input: MessageInput): { title: string; description?: string; duration?: number } =>
|
|
32
|
+
typeof input === "string" ? { title: input } : input;
|
|
33
|
+
|
|
34
|
+
const parseErrorMessage = (
|
|
35
|
+
input: ErrorMessageInput,
|
|
36
|
+
error: Error
|
|
37
|
+
): { title: string; description?: string; duration?: number } => {
|
|
38
|
+
if (typeof input === "function") {
|
|
39
|
+
return parseMessage(input(error));
|
|
40
|
+
}
|
|
41
|
+
return parseMessage(input);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const promiseToast = async <T>(promise: Promise<T>, messages: PromiseMessages): Promise<PromiseResult<T>> => {
|
|
45
|
+
const loadingCfg = parseMessage(messages.loading);
|
|
46
|
+
|
|
47
|
+
// Very long duration so it stays visible until we resolve/reject
|
|
48
|
+
const toastId = toastStore.show(
|
|
49
|
+
loadingCfg.title,
|
|
50
|
+
loadingCfg.description,
|
|
51
|
+
"loading",
|
|
52
|
+
loadingCfg.duration ?? 60 * 60 * 1000
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
const result = await promise;
|
|
57
|
+
|
|
58
|
+
const successCfg = parseMessage(messages.success);
|
|
59
|
+
toastStore.updateToast(toastId, {
|
|
60
|
+
title: successCfg.title,
|
|
61
|
+
description: successCfg.description,
|
|
62
|
+
type: "success",
|
|
63
|
+
duration: successCfg.duration ?? 4000,
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
return { data: result, success: true };
|
|
67
|
+
} catch (err) {
|
|
68
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
69
|
+
const errorCfg = parseErrorMessage(messages.error, error);
|
|
70
|
+
toastStore.updateToast(toastId, {
|
|
71
|
+
title: errorCfg.title,
|
|
72
|
+
description: errorCfg.description,
|
|
73
|
+
type: "error",
|
|
74
|
+
duration: errorCfg.duration ?? 4000,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
return { error, success: false };
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
type BaseToastFn = ((title: string, description?: string, type?: ToastType, duration?: number) => void) & {
|
|
82
|
+
/**
|
|
83
|
+
* Show a success toast with a green checkmark icon.
|
|
84
|
+
* @param title - The toast title
|
|
85
|
+
* @param descriptionOrOptions - Description string OR options object with description, duration, icon, style, etc.
|
|
86
|
+
* @param duration - Duration in ms (default: 4000). Ignored if options object is passed.
|
|
87
|
+
* @example
|
|
88
|
+
* ```ts
|
|
89
|
+
* // Simple usage
|
|
90
|
+
* toast.success("Saved!", "Your changes have been saved");
|
|
91
|
+
*
|
|
92
|
+
* // With options
|
|
93
|
+
* toast.success("Saved!", {
|
|
94
|
+
* description: "Your changes have been saved",
|
|
95
|
+
* duration: 5000,
|
|
96
|
+
* icon: <CustomIcon />,
|
|
97
|
+
* style: { borderRadius: 8 },
|
|
98
|
+
* });
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
success: (title: string, descriptionOrOptions?: DescriptionOrOptions, duration?: number) => void;
|
|
102
|
+
/**
|
|
103
|
+
* Show an error toast with a red X icon.
|
|
104
|
+
* @param title - The toast title
|
|
105
|
+
* @param descriptionOrOptions - Description string OR options object
|
|
106
|
+
* @param duration - Duration in ms (default: 4000). Ignored if options object is passed.
|
|
107
|
+
* @example
|
|
108
|
+
* ```ts
|
|
109
|
+
* toast.error("Failed", "Something went wrong");
|
|
110
|
+
* toast.error("Failed", { description: "Something went wrong", icon: <CustomErrorIcon /> });
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
error: (title: string, descriptionOrOptions?: DescriptionOrOptions, duration?: number) => void;
|
|
114
|
+
/**
|
|
115
|
+
* Show an info toast with a blue info icon.
|
|
116
|
+
* @param title - The toast title
|
|
117
|
+
* @param descriptionOrOptions - Description string OR options object
|
|
118
|
+
* @param duration - Duration in ms (default: 4000). Ignored if options object is passed.
|
|
119
|
+
* @example
|
|
120
|
+
* ```ts
|
|
121
|
+
* toast.info("Tip", "Swipe up to dismiss");
|
|
122
|
+
* toast.info("Tip", { description: "Swipe up to dismiss", style: { backgroundColor: '#f0f9ff' } });
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
info: (title: string, descriptionOrOptions?: DescriptionOrOptions, duration?: number) => void;
|
|
126
|
+
/**
|
|
127
|
+
* Show a loading toast that automatically transitions to success or error
|
|
128
|
+
* based on the promise result. Great for async operations like API calls.
|
|
129
|
+
* @param promise - The promise to track
|
|
130
|
+
* @param messages - Configuration for loading, success, and error states
|
|
131
|
+
* @returns Promise result with `{ data, success: true }` or `{ error, success: false }`
|
|
132
|
+
* @example
|
|
133
|
+
* ```ts
|
|
134
|
+
* toast.promise(fetchUser(id), {
|
|
135
|
+
* loading: { title: "Loading...", description: "Fetching user data" },
|
|
136
|
+
* success: { title: "Done!", description: "User loaded" },
|
|
137
|
+
* error: (err) => ({ title: "Error", description: err.message }),
|
|
138
|
+
* });
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
promise: <T>(promise: Promise<T>, messages: PromiseMessages) => Promise<PromiseResult<T>>;
|
|
142
|
+
/**
|
|
143
|
+
* Dismiss a specific toast by its ID.
|
|
144
|
+
* @param id - The toast ID to dismiss
|
|
145
|
+
* @example
|
|
146
|
+
* ```ts
|
|
147
|
+
* toast.dismiss("toast-123");
|
|
148
|
+
* ```
|
|
149
|
+
*/
|
|
150
|
+
dismiss: (id: string) => void;
|
|
151
|
+
/**
|
|
152
|
+
* Dismiss all visible toasts immediately.
|
|
153
|
+
* @example
|
|
154
|
+
* ```ts
|
|
155
|
+
* toast.dismissAll();
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
dismissAll: () => void;
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
// Build the toast API
|
|
162
|
+
const toastFn = _toast as unknown as BaseToastFn;
|
|
163
|
+
|
|
164
|
+
toastFn.success = (title: string, descriptionOrOptions?: DescriptionOrOptions, duration?: number) => {
|
|
165
|
+
const { description, duration: optDuration, options } = parseDescriptionOrOptions(descriptionOrOptions);
|
|
166
|
+
toastStore.show(title, description, "success", duration ?? optDuration, options);
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
toastFn.error = (title: string, descriptionOrOptions?: DescriptionOrOptions, duration?: number) => {
|
|
170
|
+
const { description, duration: optDuration, options } = parseDescriptionOrOptions(descriptionOrOptions);
|
|
171
|
+
toastStore.show(title, description, "error", duration ?? optDuration, options);
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
toastFn.info = (title: string, descriptionOrOptions?: DescriptionOrOptions, duration?: number) => {
|
|
175
|
+
const { description, duration: optDuration, options } = parseDescriptionOrOptions(descriptionOrOptions);
|
|
176
|
+
toastStore.show(title, description, "info", duration ?? optDuration, options);
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
toastFn.promise = promiseToast;
|
|
180
|
+
|
|
181
|
+
toastFn.dismiss = (id: string) => {
|
|
182
|
+
toastStore.hide(id);
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
toastFn.dismissAll = () => {
|
|
186
|
+
toastStore.hideAll();
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Toast API for showing notifications.
|
|
191
|
+
*
|
|
192
|
+
* @example
|
|
193
|
+
* ```ts
|
|
194
|
+
* import { toast } from 'react-native-bread';
|
|
195
|
+
*
|
|
196
|
+
* // Basic toasts
|
|
197
|
+
* toast.success("Saved!", "Your changes have been saved");
|
|
198
|
+
* toast.error("Error", "Something went wrong");
|
|
199
|
+
* toast.info("Tip", "Swipe up to dismiss");
|
|
200
|
+
*
|
|
201
|
+
* // Promise toast (loading → success/error)
|
|
202
|
+
* toast.promise(apiCall(), {
|
|
203
|
+
* loading: { title: "Loading..." },
|
|
204
|
+
* success: { title: "Done!" },
|
|
205
|
+
* error: (err) => ({ title: "Failed", description: err.message }),
|
|
206
|
+
* });
|
|
207
|
+
*
|
|
208
|
+
* // Dismiss toasts
|
|
209
|
+
* toast.dismiss(id);
|
|
210
|
+
* toast.dismissAll();
|
|
211
|
+
* ```
|
|
212
|
+
*/
|
|
213
|
+
export const toast = toastFn;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { type ReactNode, useEffect } from "react";
|
|
2
|
+
import { StyleSheet, View } from "react-native";
|
|
3
|
+
import { ToastContainer } from "./toast";
|
|
4
|
+
import { toastStore } from "./toast-store";
|
|
5
|
+
import type { ToastConfig } from "./types";
|
|
6
|
+
|
|
7
|
+
interface BreadLoafProps {
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
/**
|
|
10
|
+
* Configuration for customizing toast behavior and appearance.
|
|
11
|
+
* All properties are optional and will be merged with defaults.
|
|
12
|
+
*
|
|
13
|
+
* @property position - Where toasts appear: `'top'` (default) or `'bottom'`
|
|
14
|
+
* @property offset - Extra spacing from screen edge in pixels (default: `0`)
|
|
15
|
+
* @property stacking - Show multiple toasts stacked (default: `true`). When `false`, only one toast shows at a time
|
|
16
|
+
* @property defaultDuration - Default display time in ms (default: `4000`)
|
|
17
|
+
* @property colors - Customize colors per toast type (`success`, `error`, `info`, `loading`)
|
|
18
|
+
* @property toastStyle - Style overrides for the toast container (borderRadius, shadow, padding, etc.)
|
|
19
|
+
* @property titleStyle - Style overrides for the title text
|
|
20
|
+
* @property descriptionStyle - Style overrides for the description text
|
|
21
|
+
*/
|
|
22
|
+
config?: ToastConfig;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Toast provider component that enables toast notifications in your app.
|
|
27
|
+
* Wrap your root component with `<BreadLoaf>` to start showing toasts.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```tsx
|
|
31
|
+
* import { BreadLoaf } from 'react-native-bread';
|
|
32
|
+
*
|
|
33
|
+
* // Basic usage
|
|
34
|
+
* <BreadLoaf>
|
|
35
|
+
* <App />
|
|
36
|
+
* </BreadLoaf>
|
|
37
|
+
*
|
|
38
|
+
* // With configuration
|
|
39
|
+
* <BreadLoaf
|
|
40
|
+
* config={{
|
|
41
|
+
* position: 'bottom',
|
|
42
|
+
* stacking: false,
|
|
43
|
+
* defaultDuration: 5000,
|
|
44
|
+
* colors: {
|
|
45
|
+
* success: { accent: '#22c55e', background: '#f0fdf4' },
|
|
46
|
+
* error: { accent: '#ef4444', background: '#fef2f2' },
|
|
47
|
+
* },
|
|
48
|
+
* toastStyle: { borderRadius: 12 },
|
|
49
|
+
* }}
|
|
50
|
+
* >
|
|
51
|
+
* <App />
|
|
52
|
+
* </BreadLoaf>
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export function BreadLoaf({ children, config }: BreadLoafProps) {
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
toastStore.setConfig(config);
|
|
58
|
+
return () => {
|
|
59
|
+
// Reset to defaults when this provider unmounts
|
|
60
|
+
toastStore.setConfig(undefined);
|
|
61
|
+
};
|
|
62
|
+
}, [config]);
|
|
63
|
+
return (
|
|
64
|
+
<View style={styles.root}>
|
|
65
|
+
{children}
|
|
66
|
+
<View style={styles.portalContainer} pointerEvents="box-none">
|
|
67
|
+
<ToastContainer />
|
|
68
|
+
</View>
|
|
69
|
+
</View>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const styles = StyleSheet.create({
|
|
74
|
+
root: {
|
|
75
|
+
flex: 1,
|
|
76
|
+
},
|
|
77
|
+
portalContainer: {
|
|
78
|
+
...StyleSheet.absoluteFillObject,
|
|
79
|
+
zIndex: 9999,
|
|
80
|
+
},
|
|
81
|
+
});
|